RideObject_SetRide: btst #3,$2A(a1) beq.s loc_1E4A0 movea.w $42(a1),a3 bclr d6,$2A(a3) loc_1E4A0: move.w a0,$42(a1) ...We've seen this before. Bit 3 of the player's status bitfield is the "standing on object" flag. When the player lands on an object that's using the SolidObjectFull function, the object sets this bit and copies the address of its own SST to offset $42 of the player's SST. It also sets bit 3 or 4 of its own SST, depending on which player landed on it.
The code at loc_1E4A0 above wants to do the same, but before it can do so, it needs to check whether the player was already standing on another object, and if so, clear bit 3 or 4 of its SST. Which bit it clears is indicated by register d6.
You can already tell where this is going.
If both players are riding the same vertical cylinder object, and the object changes player 1's mapping frame, player 2's handler runs with d6 erroneously set to 1, which corresponds to the vertical flip flag in the object's status bitfield.
Time to put the pieces together. If player 2 is standing on a solid object, player 1 is riding a cylinder, and player 2 starts riding the cylinder at the exact same time that the cylinder object changes player 1's mapping frame, player 2's handler will call RideObject_SetRide with d6 set to 1, clearing the vertical flip flag of the object player 2 was standing on.
At least that was the theory. If the object player 2 was standing on just happened to be upside down...
I love this game so damn much.
At first, I only saw that the platform flipped right-side-up, but eventually it clicked that Tails entering the cylinder kicked Sonic out.
ReplyDeleteIs there any location that this can be seen without Debug Mode?
Tails didn't "kick Sonic out", I just jumped out to show the platform.
DeleteI just found the bug two days ago, so I don't know of any place you can do it without debug. Would be really cool, though.
Oh, okay. There's sleuthing to be done...
Delete