Difference between revisions of "Fix the Walk-Jump Bug in Sonic 1"
From Sonic Retro
Scarred Sun (talk | contribs) |
Scarred Sun (talk | contribs) m (Text replacement - "</asm>" to "</syntaxhighlight>") |
||
Line 19: | Line 19: | ||
loc_FBA0: | loc_FBA0: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
− | ...</ | + | ...</syntaxhighlight> |
As the comment says, it sets the walking animation for use right here. Your first assumption may be to remove that instruction altogether, but you don't want to do that, as some little animation bugs can still occur this way. The way to fix it is to add a conditional branch, checking to see if Sonic's animation should be set to rolling, and skipping the changing of his animation if so. You should change the code to look something like this: | As the comment says, it sets the walking animation for use right here. Your first assumption may be to remove that instruction altogether, but you don't want to do that, as some little animation bugs can still occur this way. The way to fix it is to add a conditional branch, checking to see if Sonic's animation should be set to rolling, and skipping the changing of his animation if so. You should change the code to look something like this: | ||
Line 32: | Line 32: | ||
loc_FBA0: | loc_FBA0: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
− | ...</ | + | ...</syntaxhighlight> |
And that's it! A much simpler method of getting rid of this bug, and one that doesn't alter the original player object as well. | And that's it! A much simpler method of getting rid of this bug, and one that doesn't alter the original player object as well. | ||
Line 47: | Line 47: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
bclr #5,$22(a1) | bclr #5,$22(a1) | ||
− | ...</ | + | ...</syntaxhighlight> |
and replace it with this: | and replace it with this: | ||
Line 62: | Line 62: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
bclr #5,$22(a1) | bclr #5,$22(a1) | ||
− | ...</ | + | ...</syntaxhighlight> |
===Drowning=== | ===Drowning=== | ||
Line 81: | Line 81: | ||
loc_FBA0: | loc_FBA0: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
− | ...</ | + | ...</syntaxhighlight> |
'''Obj26''' (Monitor): | '''Obj26''' (Monitor): | ||
Line 98: | Line 98: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
bclr #5,$22(a1) | bclr #5,$22(a1) | ||
− | ...</ | + | ...</syntaxhighlight> |
===Hurt by spikes=== | ===Hurt by spikes=== | ||
Line 119: | Line 119: | ||
loc_FBA0: | loc_FBA0: | ||
bclr #5,$22(a0) | bclr #5,$22(a0) | ||
− | ...</ | + | ...</syntaxhighlight> |
==GitHub Disassembly== | ==GitHub Disassembly== | ||
Line 133: | Line 133: | ||
Solid_NotPushing: | Solid_NotPushing: | ||
− | bclr #5,obStatus(a0) ; clear pushing flag</ | + | bclr #5,obStatus(a0) ; clear pushing flag</syntaxhighlight> |
Line 147: | Line 147: | ||
Solid_NotPushing: | Solid_NotPushing: | ||
bclr #5,obStatus(a0) ; clear pushing flag | bclr #5,obStatus(a0) ; clear pushing flag | ||
− | ...</ | + | ...</syntaxhighlight> |
And that's it! A much simpler method of getting rid of this bug, and one that doesn't alter the original player object as well. | And that's it! A much simpler method of getting rid of this bug, and one that doesn't alter the original player object as well. | ||
Line 162: | Line 162: | ||
bclr #5,obStatus(a0) | bclr #5,obStatus(a0) | ||
bclr #5,obStatus(a1) | bclr #5,obStatus(a1) | ||
− | ...</ | + | ...</syntaxhighlight> |
and replace it with this: | and replace it with this: | ||
Line 177: | Line 177: | ||
bclr #5,obStatus(a0) | bclr #5,obStatus(a0) | ||
bclr #5,obStatus(a1) | bclr #5,obStatus(a1) | ||
− | ...</ | + | ...</syntaxhighlight> |
===Drowning=== | ===Drowning=== | ||
Line 196: | Line 196: | ||
Solid_NotPushing: | Solid_NotPushing: | ||
bclr #5,obStatus(a0) ; clear pushing flag | bclr #5,obStatus(a0) ; clear pushing flag | ||
− | ...</ | + | ...</syntaxhighlight> |
'''Monitor''': | '''Monitor''': | ||
Line 213: | Line 213: | ||
bclr #5,obStatus(a0) | bclr #5,obStatus(a0) | ||
bclr #5,obStatus(a1) | bclr #5,obStatus(a1) | ||
− | ...</ | + | ...</syntaxhighlight> |
===Hurt by spikes=== | ===Hurt by spikes=== | ||
Line 234: | Line 234: | ||
Solid_NotPushing: | Solid_NotPushing: | ||
bclr #5,obStatus(a0) ; clear pushing flag | bclr #5,obStatus(a0) ; clear pushing flag | ||
− | ...</ | + | ...</syntaxhighlight> |
{{S1Howtos}} | {{S1Howtos}} | ||
[[Category:SCHG How-tos|Fix the Walk-Jump Bug in Sonic 1]] | [[Category:SCHG How-tos|Fix the Walk-Jump Bug in Sonic 1]] |
Revision as of 21:29, 20 December 2015
(Original guide by Cinossu and Mercury)
In Sonic the Hedgehog there's a lovely bug where Sonic jumps into the air in his walking animation. It occurs in several places (to the right of the second purple rock with a yellow spring on top of it in Green Hill Zone Act 2 being a good place to see it, as well as near the lava in Marble Zone), but they all have one thing in common; they are near an object that calls the SolidObject routine.
Instead of changing how jumps are shown within Sonic's object code, you can fix this within the SolidObject routine itself (and if you look in Sonic 2, a variant of this is used as well).
Contents
Hivebrain's 2005 Disassembly
Jumping
The first thing you'll want to find is loc_FB92. It starts off looking like this:
<asm> loc_FB92: btst #5,$22(a0) beq.s loc_FBAC move.w #1,$1C(a1) ; use walking animation
loc_FBA0: bclr #5,$22(a0) ...</syntaxhighlight>
As the comment says, it sets the walking animation for use right here. Your first assumption may be to remove that instruction altogether, but you don't want to do that, as some little animation bugs can still occur this way. The way to fix it is to add a conditional branch, checking to see if Sonic's animation should be set to rolling, and skipping the changing of his animation if so. You should change the code to look something like this:
<asm>loc_FB92: btst #5,$22(a0) beq.s loc_FBAC cmp.b #2,$1C(a1) ; check if in jumping/rolling animation beq.s loc_FBA0 move.w #1,$1C(a1) ; use walking animation
loc_FBA0: bclr #5,$22(a0) ...</syntaxhighlight>
And that's it! A much simpler method of getting rid of this bug, and one that doesn't alter the original player object as well.
The above fix only works concerning solid objects other than Monitors, meaning there will still be a fair number of areas in which the walk-jump bug will occur unless you also modify the following code. Find the Obj26 label, and scroll down until you see this:
<asm> loc_A25C: btst #5,$22(a0) beq.s Obj26_Animate move.w #1,$1C(a1)
loc_A26A: bclr #5,$22(a0) bclr #5,$22(a1) ...</syntaxhighlight>
and replace it with this:
<asm> loc_A25C: btst #5,$22(a0) beq.s Obj26_Animate cmp.b #2,$1C(a1) ; check if in jumping/rolling animation beq.s loc_A26A move.w #1,$1C(a1)
loc_A26A: bclr #5,$22(a0) bclr #5,$22(a1) ...</syntaxhighlight>
Drowning
There is also another related bug: if Sonic drowns while adjacent to a solid object or Monitor, he will fall off the screen in his walking animation, and not his drowning animation as he should. This can be fixed by adding a check for his drowning animation in addition to his jumping/rolling animation in the code described above.
SolidObject:
<asm>loc_FB92: btst #5,$22(a0) beq.s loc_FBAC cmp.b #2,$1C(a1) ; check if in jumping/rolling animation beq.s loc_FBA0 cmp.b #$17,$1C(a1) ; check if in drowning animation beq.s loc_FBA0 move.w #1,$1C(a1) ; use walking animation
loc_FBA0: bclr #5,$22(a0) ...</syntaxhighlight>
Obj26 (Monitor):
<asm> loc_A25C: btst #5,$22(a0) beq.s Obj26_Animate cmp.b #2,$1C(a1) ; check if in jumping/rolling animation beq.s loc_A26A cmp.b #$17,$1C(a1) ; check if in drowning animation beq.s loc_A26A move.w #1,$1C(a1)
loc_A26A: bclr #5,$22(a0) bclr #5,$22(a1) ...</syntaxhighlight>
Hurt by spikes
There is yet another related bug: if Sonic walks or runs into sideways-pointing spikes, he will be hurt as usual, but bounce in his walking animation, and not his hurt animation. This can be fixed by adding a check for his hurt animation.
SolidObject:
<asm>loc_FB92: btst #5,$22(a0) beq.s loc_FBAC cmp.b #2,$1C(a1) ; check if in jumping/rolling animation beq.s loc_FBA0 cmp.b #$17,$1C(a1) ; check if in drowning animation beq.s loc_FBA0 cmp.b #$1A,$1C(a1) ; check if in hurt animation beq.s loc_FBA0 move.w #1,$1C(a1) ; use walking animation
loc_FBA0: bclr #5,$22(a0) ...</syntaxhighlight>
GitHub Disassembly
Jumping
The first thing you'll want to find is Solid_Ignore. Open _incObj\sub SolidObject.asm, it starts off looking like this:
<asm>Solid_Ignore: btst #5,obStatus(a0) ; is Sonic pushing? beq.s Solid_Debug ; if not, branch move.w #id_Run,obAnim(a1) ; use running animation
Solid_NotPushing: bclr #5,obStatus(a0) ; clear pushing flag</syntaxhighlight>
As the comment says, it sets the walking animation for use right here. Your first assumption may be to remove that instruction altogether, but you don't want to do that, as some little animation bugs can still occur this way. The way to fix it is to add a conditional branch, checking to see if Sonic's animation should be set to rolling, and skipping the changing of his animation if so. You should change the code to look something like this:
<asm>Solid_Ignore: btst #5,obStatus(a0) ; is Sonic pushing? beq.s Solid_Debug ; if not, branch cmpi.b #id_Roll,obAnim(a1) ; is Sonic in his jumping/rolling animation? beq.s Solid_NotPushing ; if so, branch move.w #id_Run,obAnim(a1) ; use running animation
Solid_NotPushing: bclr #5,obStatus(a0) ; clear pushing flag ...</syntaxhighlight>
And that's it! A much simpler method of getting rid of this bug, and one that doesn't alter the original player object as well.
The above fix only works concerning solid objects other than Monitors, meaning there will still be a fair number of areas in which the walk-jump bug will occur unless you also modify the following code. Open _incObj\26 Monitor.asm and scroll down until you see this:
<asm> loc_A25C: btst #5,obStatus(a0) beq.s Mon_Animate move.w #1,obAnim(a1) ; clear obAnim and set obNextAni to 1
loc_A26A: bclr #5,obStatus(a0) bclr #5,obStatus(a1) ...</syntaxhighlight>
and replace it with this:
<asm> loc_A25C: btst #5,obStatus(a0) beq.s Mon_Animate cmpi.b #id_Roll,obAnim(a1) ; is Sonic in his jumping/rolling animation? beq.s loc_A26A ; if so, branch move.w #1,obAnim(a1) ; clear obAnim and set obNextAni to 1, putting Sonic in his walking animation
loc_A26A: bclr #5,obStatus(a0) bclr #5,obStatus(a1) ...</syntaxhighlight>
Drowning
There is also another related bug: if Sonic drowns while adjacent to a solid object or Monitor, he will fall off the screen in his walking animation, and not his drowning animation as he should. This can be fixed by adding a check for his drowning animation in addition to his jumping/rolling animation in the code described above.
SolidObject:
<asm>Solid_Ignore: btst #5,obStatus(a0) ; is Sonic pushing? beq.s Solid_Debug ; if not, branch cmpi.b #id_Roll,obAnim(a1) ; is Sonic in his jumping/rolling animation? beq.s Solid_NotPushing ; if so, branch cmpi.b #id_Drown,obAnim(a1) ; is Sonic in his drowning animation? beq.s Solid_NotPushing ; if so, branch move.w #id_Run,obAnim(a1) ; use running animation
Solid_NotPushing: bclr #5,obStatus(a0) ; clear pushing flag ...</syntaxhighlight>
Monitor:
<asm> loc_A25C: btst #5,obStatus(a0) beq.s Mon_Animate cmpi.b #id_Roll,obAnim(a1) ; is Sonic in his jumping/rolling animation? beq.s loc_A26A ; if so, branch cmpi.b #id_Drown,obAnim(a1) ; is Sonic in his drowning animation? beq.s loc_A26A ; if so, branch move.w #1,obAnim(a1) ; clear obAnim and set obNextAni to 1, putting Sonic in his walking animation
loc_A26A: bclr #5,obStatus(a0) bclr #5,obStatus(a1) ...</syntaxhighlight>
Hurt by spikes
There is yet another related bug: if Sonic walks or runs into sideways-pointing spikes, he will be hurt as usual, but bounce in his walking animation, and not his hurt animation. This can be fixed by adding a check for his hurt animation.
SolidObject:
<asm>Solid_Ignore: btst #5,obStatus(a0) ; is Sonic pushing? beq.s Solid_Debug ; if not, branch cmpi.b #id_Roll,obAnim(a1) ; is Sonic in his jumping/rolling animation? beq.s Solid_NotPushing ; if so, branch cmpi.b #id_Drown,obAnim(a1) ; is Sonic in his drowning animation? beq.s Solid_NotPushing ; if so, branch cmpi.b #id_Hurt,obAnim(a1) ; is Sonic in his hurt animation? beq.s Solid_NotPushing ; if so, branch move.w #id_Run,obAnim(a1) ; use running animation
Solid_NotPushing: bclr #5,obStatus(a0) ; clear pushing flag ...</syntaxhighlight>