Actions

SCHG How-to

Difference between revisions of "Fix the Walk-Jump Bug in Sonic 1"

From Sonic Retro

m
Line 1: Line 1:
 
{{GuideBy|Cinossu|Mercury|PsychoSk8r}}
 
{{GuideBy|Cinossu|Mercury|PsychoSk8r}}
  
In ''[[Sonic the Hedgehog (16-bit)|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.
+
In ''[[Sonic the Hedgehog (16-bit)|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).
 
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).
  
==2005 HiveBrain disassembly==
+
==Hivebrain's 2005 Disassembly==
 +
 
 +
===Jumping===
  
 
The first thing you'll want to find is '''loc_FB92'''. It starts off looking like this:
 
The first thing you'll want to find is '''loc_FB92'''. It starts off looking like this:
Line 18: Line 20:
 
...</asm>
 
...</asm>
  
If you look at the comment left, it sets the walking animation for use right here. Your first assumption may be to remove this call 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 over it, checking to see if Sonic's animation should be set to rolling. 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:
  
 
<asm>loc_FB92:
 
<asm>loc_FB92:
Line 33: Line 35:
 
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.
  
'''Monitors'''
+
The above fix only works concerning solid objects other than [[Monitor|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:
 
 
The above fix only works concerning solid objects other than [[Monitor|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 until you see this:
 
  
 
<asm>
 
<asm>
Line 46: Line 46:
 
bclr #5,$22(a0)
 
bclr #5,$22(a0)
 
bclr #5,$22(a1)
 
bclr #5,$22(a1)
...
+
...</asm>
</asm>
 
  
 
and replace it with this:
 
and replace it with this:
Line 62: Line 61:
 
bclr #5,$22(a0)
 
bclr #5,$22(a0)
 
bclr #5,$22(a1)
 
bclr #5,$22(a1)
...
+
...</asm>
</asm>
 
  
'''Drowning'''
+
===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 routines described above.
+
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''':
 
'''SolidObject''':
Line 99: Line 97:
 
bclr #5,$22(a0)
 
bclr #5,$22(a0)
 
bclr #5,$22(a1)
 
bclr #5,$22(a1)
...
+
...</asm>
</asm>
 
  
 +
===Hurt by spikes===
  
'''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.
 
 
There is yet another related bug. If Sonic walks or runs into spike pointing sideways, 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''':
 
'''SolidObject''':
Line 124: Line 120:
 
...</asm>
 
...</asm>
  
 +
==GitHub Disassembly==
  
 +
===Jumping===
  
==GitHub disassembly==
+
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
  
For those modders who use GitHub dissasembly, here is the ported guide, also a bit more summarized:
+
Solid_NotPushing:
 +
bclr #5,obStatus(a0) ; clear pushing flag</asm>
  
The first thing you'll want to find is Solid_Ignore. Open '''_incObj\sub SolidObject.asm''', it starts off looking like this:
 
  
Solid_Ignore:  
+
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?
 
btst #5,obStatus(a0) ; is Sonic pushing?
 
 
beq.s Solid_Debug ; if not, branch
 
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
 
move.w #id_Run,obAnim(a1) ; use running animation
  
 +
Solid_NotPushing:
 +
bclr #5,obStatus(a0) ; clear pushing flag
 +
...</asm>
  
If you look at the comment left, it sets the running animation for use right here. Then what you have to do is add conditional checks for rolling, drowning and hurt status. You should change the code to look something like this:
+
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.
  
Solid_Ignore:  
+
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:
  
btst #5,$22(a0)  
+
<asm>
 +
loc_A25C:
 +
btst #5,obStatus(a0)
 +
beq.s Mon_Animate
 +
move.w #1,obAnim(a1) ; clear obAnim and set obNextAni to 1
  
beq.s Solid_Debug
+
loc_A26A:
 +
bclr #5,obStatus(a0)
 +
bclr #5,obStatus(a1)
 +
...</asm>
  
cmp.b #id_roll,obAnim(a1) ; check if in jumping/rolling animation
+
and replace it with this:
  
beq.s Solid_NotPushing
+
<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
  
cmp.b #id_Drown,obAnim(a1) ; check if in drowning animation
+
loc_A26A:
 +
bclr #5,obStatus(a0)
 +
bclr #5,obStatus(a1)
 +
...</asm>
  
beq.s Solid_NotPushing
+
===Drowning===
  
cmp.b #id_Hurt,obAnim(a1) ; check if in hurt animation  
+
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.
  
beq.s Solid_NotPushing
+
'''SolidObject''':
  
move.w #id_Run,obAnim(a1) ; use walking animation
+
<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
 +
...</asm>
  
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.
+
'''Monitor''':
 
 
==Monitors==
 
 
 
 
 
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 and/or walk-drown bugs will occur unless you also modify the following code. Open _incObj\26 Monitor.asm and scroll until you see this:
 
  
 +
<asm>
 
loc_A25C:
 
loc_A25C:
 
 
btst #5,obStatus(a0)
 
btst #5,obStatus(a0)
 
 
beq.s Mon_Animate
 
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
  
move.w #1,obAnim(a1) ; clear obAnim and set obNextAni to 1
+
loc_A26A:
 +
bclr #5,obStatus(a0)
 +
bclr #5,obStatus(a1)
 +
...</asm>
  
 +
===Hurt by spikes===
  
And replace with this:
+
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''':
  
loc_A25C:  
+
<asm>Solid_Ignore:
 
+
btst #5,obStatus(a0) ; is Sonic pushing?
btst #5,obStatus(a0)
+
beq.s Solid_Debug ; if not, branch
 
+
cmpi.b #id_Roll,obAnim(a1) ; is Sonic in his jumping/rolling animation?
beq.s Mon_Animate
+
beq.s Solid_NotPushing ; if so, branch
 
+
cmpi.b #id_Drown,obAnim(a1) ; is Sonic in his drowning animation?
cmp.b #id_Roll,obAnim(a1) ; check if in jumping/rolling animation  
+
beq.s Solid_NotPushing ; if so, branch
 
+
cmpi.b #id_Hurt,obAnim(a1) ; is Sonic in his hurt animation?
beq.s loc_A26A
+
beq.s Solid_NotPushing ; if so, branch
 
+
move.w #id_Run,obAnim(a1) ; use running animation
cmp.b #id_Drown,obAnim(a1) ; check if in drowning animation  
 
 
 
beq.s loc_A26A
 
 
 
move.w #id_Run,obAnim(a1)
 
  
 +
Solid_NotPushing:
 +
bclr #5,obStatus(a0) ; clear pushing flag
 +
...</asm>
  
Save the two files, compile and enjoy a less buggier Sonic!
 
  
 
{{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 16:03, 8 February 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).

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) ...</asm>

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) ...</asm>

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) ...</asm>

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) ...</asm>

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) ...</asm>

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) ...</asm>

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) ...</asm>

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</asm>


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 ...</asm>

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) ...</asm>

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) ...</asm>

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 ...</asm>

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) ...</asm>

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 ...</asm>


SCHG How-To Guide: Sonic the Hedgehog (16-bit)
Fixing Bugs
Fix Demo Playback | Fix a Race Condition with Pattern Load Cues | Fix the SEGA Sound | Display the Press Start Button Text | Fix the Level Select Menu | Fix the Hidden Points Bug | Fix Accidental Deletion of Scattered Rings | Fix Ring Timers | Fix the Walk-Jump Bug | Correct Drowning Bugs | Fix the Death Boundary Bug | Fix the Camera Follow Bug | Fix Song Restoration Bugs | Fix the HUD Blinking | Fix the Level Select Graphics Bug | Fix a remember sprite related bug
Changing Design Choices
Change Spike Behavior | Collide with Water After Being Hurt | Fix Special Stage Jumping Physics | Improve the Fade In\Fade Out Progression Routines | Fix Scattered Rings' Underwater Physics | Remove the Speed Cap | Port the REV01 Background Effects | Port Sonic 2's Level Art Loader | Retain Rings Between Acts | Add Sonic 2 (Simon Wai Prototype) Level Select | Improve ObjectMove Subroutines | Port Sonic 2 Level Select
Adding Features
Add Spin Dash ( Part 1 / Part 2 / Part 3 / Part 4 ) | Add Eggman Monitor | Add Super Sonic | Add the Air Roll
Sound Features
Expand the Sound Index | Play Different Songs Per Act | Port Sonic 2 Final Sound Driver | Port Sonic 3's Sound Driver | Port Flamewing's Sonic 3 & Knuckles Sound Driver | Change The SEGA Sound
Extending the Game
Load Chunks From ROM | Add Extra Characters | Make an Alternative Title Screen | Use Dynamic Tilesets | Make GHZ Load Alternate Art | Make Ending Load Alternate Art | Add a New Zone | Set Up the Goggle Monitor | Add New Moves | Add a Dynamic Collision System | Dynamic Special Stage Walls System | Extend Sprite Mappings and Art Limit | Enigma Credits | Use Dynamic Palettes
Miscellaneous
Convert the Hivebrain 2005 Disassembly to ASM68K
Split Disassembly Guides
Set Up a Split Disassembly | Basic Level Editing | Basic Art Editing | Basic ASM Editing (Spin Dash)