Demo Playback Fix - RetroKoH/S1Fixed GitHub Wiki
(Original guide by FraGag)
Source: SCHG Page
Commit: 696f86d
Did you know that the original release of Sonic 1 (REV00) had a bug that let you disrupt demos by holding A, B or C? Basically, if you hold one of these buttons, it disrupts the programmed input, causing Sonic to NOT jump when he's supposed to. This can be used to hilarious effect. It can also make it incredibly difficult to record new demos, especially if these demos are supposed to showcase new abilities such as the Spin Dash or a double jump technique.
This bug happens because the demo playback routine compares the wrong button flags of the current frame with the corresponding button flags of the previous frame ($FFF604 instead of $FFF602), resulting in a button held for more than one frame being erroneously interpreted as continual new presses of that button instead.
To fix it, open _inc\MoveSonicInDemo.asm and find the label .notcredits
. Replace these lines:
if Revision=0
move.b (a0),d2
else
moveq #0,d2
endc
with this line:
move.b v_jpadhold2-v_jpadhold1(a0),d2
FraGag explains:
The old code read from $FFFFF604, which contains the actual controller input instead of the fake controller input simulated by the demo playback, which is why the player can disrupt a demo by pressing A, B or C; if this value is zero (i.e. if you don't press anything on the controller), the game will think that no buttons were pressed on the previous frame in the demo, which causes the game to emulate presses on every frame. In REV01, the instruction was changed to clear the register so that the controller input is ignored, making the clever press/hold detection that was supposed to happen completely useless. The solution proposed here makes it read the value from $FFF602, which tell what buttons were pressed in the previous frame in the demo.