Actions

SCHG How-to

Difference between revisions of "Fix Speed Bugs in Sonic 2"

From Sonic Retro

m (Added S2Howtos template, added category)
(Added fix for use with other guide, replaces spaces with tabs)
Line 24: Line 24:
 
<asm>
 
<asm>
 
; NORMAL
 
; NORMAL
        move.w #$600,(Sonic_top_speed).w
+
move.w #$600,(Sonic_top_speed).w
        move.w #$C,(Sonic_acceleration).w
+
move.w #$C,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
  
 
; NORMAL SPEED SHOES
 
; NORMAL SPEED SHOES
        move.w #$C00,(Sonic_top_speed).w
+
move.w #$C00,(Sonic_top_speed).w
        move.w #$18,(Sonic_acceleration).w
+
move.w #$18,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
 
          
 
          
 
; SUPER SONIC
 
; SUPER SONIC
        move.w #$A00,(Sonic_top_speed).w
+
move.w #$A00,(Sonic_top_speed).w
        move.w #$30,(Sonic_acceleration).w
+
move.w #$30,(Sonic_acceleration).w
        move.w #$100,(Sonic_deceleration).w
+
move.w #$100,(Sonic_deceleration).w
 
          
 
          
 
; NORMAL UNDERWATER
 
; NORMAL UNDERWATER
        move.w #$300,(Sonic_top_speed).w
+
move.w #$300,(Sonic_top_speed).w
        move.w #6,(Sonic_acceleration).w
+
move.w #6,(Sonic_acceleration).w
        move.w #$40,(Sonic_deceleration).w
+
move.w #$40,(Sonic_deceleration).w
  
 
; SUPER SONIC UNDERWATER
 
; SUPER SONIC UNDERWATER
        move.w #$500,(Sonic_top_speed).w
+
move.w #$500,(Sonic_top_speed).w
        move.w #$18,(Sonic_acceleration).w
+
move.w #$18,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
 
</asm>
 
</asm>
 
As you can see, the game doesn't have speed settings for "Normal underwater with speed shoes", "Super Sonic with speed shoes" or "Super Sonic underwater with speed shoes". No wonder why all these bugs exist. Now, we have to come up with these speeds, which I have already done with some maths involved. To get "Normal underwater with speed shoes", I thought, how does normal Sonic get speed shoes speed? Well, everything is doubled except his deceleration, which stays the same. So I did the same and got this new speed setting.
 
As you can see, the game doesn't have speed settings for "Normal underwater with speed shoes", "Super Sonic with speed shoes" or "Super Sonic underwater with speed shoes". No wonder why all these bugs exist. Now, we have to come up with these speeds, which I have already done with some maths involved. To get "Normal underwater with speed shoes", I thought, how does normal Sonic get speed shoes speed? Well, everything is doubled except his deceleration, which stays the same. So I did the same and got this new speed setting.
Line 52: Line 52:
 
<asm>
 
<asm>
 
; NORMAL UNDERWATER SPEED SHOES
 
; NORMAL UNDERWATER SPEED SHOES
        move.w #$600,(Sonic_top_speed).w
+
move.w #$600,(Sonic_top_speed).w
        move.w #$C,(Sonic_acceleration).w
+
move.w #$C,(Sonic_acceleration).w
        move.w #$40,(Sonic_deceleration).w
+
move.w #$40,(Sonic_deceleration).w
 
</asm>
 
</asm>
  
Line 60: Line 60:
 
<asm>
 
<asm>
 
; SUPER SONIC SPEED SHOES
 
; SUPER SONIC SPEED SHOES
        move.w #$C00,(Sonic_top_speed).w
+
move.w #$C00,(Sonic_top_speed).w
        move.w #$30,(Sonic_acceleration).w
+
move.w #$30,(Sonic_acceleration).w
        move.w #$100,(Sonic_deceleration).w
+
move.w #$100,(Sonic_deceleration).w
 
</asm>
 
</asm>
  
Line 68: Line 68:
 
<asm>
 
<asm>
 
; SUPER SONIC UNDERWATER SPEED SHOES
 
; SUPER SONIC UNDERWATER SPEED SHOES
        move.w #$A00,(Sonic_top_speed).w
+
move.w #$A00,(Sonic_top_speed).w
        move.w #$30,(Sonic_acceleration).w
+
move.w #$30,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
 
</asm>
 
</asm>
 
You do not need to add any of the ASM above into your hack, YET. Just note these for now.
 
You do not need to add any of the ASM above into your hack, YET. Just note these for now.
Line 84: Line 84:
 
; This array defines what speeds the character should be set to
 
; This array defines what speeds the character should be set to
 
; ----------------------------------------------------------------------------
 
; ----------------------------------------------------------------------------
;               blank  top_speed       acceleration   deceleration   ; #     ; Comment
+
; top_speed acceleration deceleration ; # ; Comment
 
Speedsettings:
 
Speedsettings:
        dc.w   $0,    $600,           $C,             $80             ; $00   ; Normal
+
dc.w $600, $C, $80 ; $00 ; Normal
        dc.w   $0,    $C00,           $18,           $80             ; $08   ; Normal Speedshoes
+
dc.w $C00, $18, $80 ; $08 ; Normal Speedshoes
        dc.w   $0,    $300,           $6,             $40             ; $16   ; Normal Underwater
+
dc.w $300, $6, $40 ; $16 ; Normal Underwater
        dc.w   $0,    $600,           $C,             $40             ; $24   ; Normal Underwater Speedshoes
+
dc.w $600, $C, $40 ; $24 ; Normal Underwater Speedshoes
        dc.w   $0,    $A00,           $30,           $100           ; $32   ; Super
+
dc.w $A00, $30, $100 ; $32 ; Super
        dc.w   $0,    $C00,           $30,           $100           ; $40   ; Super Speedshoes
+
dc.w $C00, $30, $100 ; $40 ; Super Speedshoes
        dc.w   $0,    $500,           $18,           $80             ; $48   ; Super Underwater
+
dc.w $500, $18, $80 ; $48 ; Super Underwater
        dc.w   $0,    $A00,           $30,           $80             ; $56   ; Super Underwater Speedshoes
+
dc.w $A00, $30, $80 ; $56 ; Super Underwater Speedshoes
 
; ===========================================================================
 
; ===========================================================================
 
</asm>
 
</asm>
Line 114: Line 114:
  
 
ApplySpeedSettings:
 
ApplySpeedSettings:
        moveq   #0,d0                           ; Quickly clear d0
+
moveq #0,d0 ; Quickly clear d0
        tst.w   speedshoes_time(a0)             ; Does character have speedshoes?
+
tst.w speedshoes_time(a0) ; Does character have speedshoes?
        beq.s   +                               ; If not, branch
+
beq.s + ; If not, branch
        addq.b #1,d0                           ; Quickly add 1 to d0
+
addq.b #6,d0 ; Quickly add 6 to d0
 
+
 
+
        btst   #6,status(a0)                   ; Is the character underwater?
+
btst #6,status(a0) ; Is the character underwater?
        beq.s   +                               ; If not, branch
+
beq.s + ; If not, branch
        addq.b #2,d0                           ; Quickly add 2 to d0
+
addi.b #12,d0 ; Add 12 to d0
 
+
 
+
        cmpa.w #MainCharacter,a0               ; Is it Tails currently following this code?
+
cmpa.w #MainCharacter,a0 ; Is it Tails currently following this code?
        bne.s   +                               ; If so, branch and ignore next question
+
bne.s + ; If so, branch and ignore next question
        tst.b   (Super_Sonic_flag).w           ; Is the character Super?
+
tst.b (Super_Sonic_flag).w ; Is the character Super?
        beq.s   +                               ; If not, branch
+
beq.s + ; If not, branch
        addq.b #4,d0                           ; Quickly add 4 to d0
+
addi.b #24,d0 ; Add 24 to d0
 
+
 
+
        add.b  d0,d0                          ; Multiply itself
+
lea Speedsettings(pc,d0.w),a1 ; Load correct speed settings into a1
        add.b  d0,d0                          ; And again
+
move.l (a1)+,(a2)+ ; Set character's new top speed and acceleration
        add.b  d0,d0                          ; And again
+
move.w (a1),(a2) ; Set character's deceleration
        lea     Speedsettings(pc,d0.w),a1       ; Load correct speed settings into a1
+
rts ; Finish subroutine
        addq.l  #2,a1                          ; Increment a1 by 2 quickly
 
        move.l (a1)+,(a2)+                     ; Set character's new top speed and acceleration
 
        move.w (a1),(a2)                       ; Set character's deceleration
 
        rts                                     ; Finish subroutine
 
 
; ===========================================================================
 
; ===========================================================================
 
</asm>
 
</asm>
Line 147: Line 143:
 
Now we have our new code, we need to make some jumps to it. First, go to "Obj01_Init:". You only need to do this bit if you have checkpoints starting underwater, otherwise, you can skip this bit of the step. You MUST follow the rest of this step from when you see "************" onward. Anyway, under the label "Obj01_Init:", find and delete these lines:
 
Now we have our new code, we need to make some jumps to it. First, go to "Obj01_Init:". You only need to do this bit if you have checkpoints starting underwater, otherwise, you can skip this bit of the step. You MUST follow the rest of this step from when you see "************" onward. Anyway, under the label "Obj01_Init:", find and delete these lines:
 
<asm>
 
<asm>
        move.w #$600,(Sonic_top_speed).w       ; set Sonic's top speed
+
move.w #$600,(Sonic_top_speed).w ; set Sonic's top speed
        move.w #$C,(Sonic_acceleration).w     ; set Sonic's acceleration
+
move.w #$C,(Sonic_acceleration).w ; set Sonic's acceleration
        move.w #$80,(Sonic_deceleration).w     ; set Sonic's deceleration
+
move.w #$80,(Sonic_deceleration).w ; set Sonic's deceleration
 
</asm>
 
</asm>
  
 
and replace with this
 
and replace with this
 
<asm>
 
<asm>
        lea     (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
Line 162: Line 158:
 
Under "Obj01_ChkShoes:" find and delete these lines:
 
Under "Obj01_ChkShoes:" find and delete these lines:
 
<asm>
 
<asm>
        move.w #$600,(Sonic_top_speed).w
+
move.w #$600,(Sonic_top_speed).w
        move.w #$C,(Sonic_acceleration).w
+
move.w #$C,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
        tst.b   (Super_Sonic_flag).w
+
tst.b (Super_Sonic_flag).w
        beq.s   Obj01_RmvSpeed
+
beq.s Obj01_RmvSpeed
        move.w #$A00,(Sonic_top_speed).w
+
move.w #$A00,(Sonic_top_speed).w
        move.w #$30,(Sonic_acceleration).w
+
move.w #$30,(Sonic_acceleration).w
        move.w #$100,(Sonic_deceleration).w
+
move.w #$100,(Sonic_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with this
 
and replace with this
 
<asm>
 
<asm>
        lea     (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
 
Next, under "Obj01_InWater:" find these lines and delete:
 
Next, under "Obj01_InWater:" find these lines and delete:
 
<asm>
 
<asm>
        move.w #$300,(Sonic_top_speed).w
+
move.w #$300,(Sonic_top_speed).w
        move.w #6,(Sonic_acceleration).w
+
move.w #6,(Sonic_acceleration).w
        move.w #$40,(Sonic_deceleration).w
+
move.w #$40,(Sonic_deceleration).w
        tst.b   (Super_Sonic_flag).w
+
tst.b (Super_Sonic_flag).w
        beq.s   +
+
beq.s +
        move.w #$500,(Sonic_top_speed).w
+
move.w #$500,(Sonic_top_speed).w
        move.w #$18,(Sonic_acceleration).w
+
move.w #$18,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
 
+
 
+
 
</asm>
 
</asm>
Line 193: Line 189:
 
and replace with:
 
and replace with:
 
<asm>
 
<asm>
        lea     (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
 
Next, under "Obj01_OutWater:" find these lines and delete:
 
Next, under "Obj01_OutWater:" find these lines and delete:
 
<asm>
 
<asm>
        move.w #$600,(Sonic_top_speed).w
+
move.w #$600,(Sonic_top_speed).w
        move.w #$C,(Sonic_acceleration).w
+
move.w #$C,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
        tst.b   (Super_Sonic_flag).w
+
tst.b (Super_Sonic_flag).w
        beq.s   +
+
beq.s +
        move.w #$A00,(Sonic_top_speed).w
+
move.w #$A00,(Sonic_top_speed).w
        move.w #$30,(Sonic_acceleration).w
+
move.w #$30,(Sonic_acceleration).w
        move.w #$100,(Sonic_deceleration).w
+
move.w #$100,(Sonic_deceleration).w
 
+
 
+
 
</asm>
 
</asm>
Line 212: Line 208:
 
and replace with:
 
and replace with:
 
<asm>
 
<asm>
        lea     (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
 
Next, go to "Sonic_CheckGoSuper:" and find and delete these lines:
 
Next, go to "Sonic_CheckGoSuper:" and find and delete these lines:
 
<asm>
 
<asm>
        move.w #$A00,(Sonic_top_speed).w
+
move.w #$A00,(Sonic_top_speed).w
        move.w #$30,(Sonic_acceleration).w
+
move.w #$30,(Sonic_acceleration).w
        move.w #$100,(Sonic_deceleration).w
+
move.w #$100,(Sonic_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with:
 
and replace with:
 
<asm>
 
<asm>
        lea     (Sonic_top_speed).w,a2         ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        bsr.w   ApplySpeedSettings             ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
 
Next, go to "Sonic_RevertToNormal:" and find and delete these lines:
 
Next, go to "Sonic_RevertToNormal:" and find and delete these lines:
 
<asm>
 
<asm>
        move.w #$600,(Sonic_top_speed).w
+
move.w #$600,(Sonic_top_speed).w
        move.w #$C,(Sonic_acceleration).w
+
move.w #$C,(Sonic_acceleration).w
        move.w #$80,(Sonic_deceleration).w
+
move.w #$80,(Sonic_deceleration).w
        btst   #6,status(a0)   ; Check if underwater, return if not
+
btst #6,status(a0) ; Check if underwater, return if not
        beq.s   return_1AC3C
+
beq.s return_1AC3C
        move.w #$300,(Sonic_top_speed).w
+
move.w #$300,(Sonic_top_speed).w
        move.w #6,(Sonic_acceleration).w
+
move.w #6,(Sonic_acceleration).w
        move.w #$40,(Sonic_deceleration).w
+
move.w #$40,(Sonic_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with this slightly different code:
 
and replace with this slightly different code:
 
<asm>
 
<asm>
        lea     (Sonic_top_speed).w,a2         ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        bra.w   ApplySpeedSettings             ; Fetch Speed settings and return
+
bra.w ApplySpeedSettings ; Fetch Speed settings and return
 
</asm>
 
</asm>
  
Line 250: Line 246:
 
So, go to "Obj02_Init:". You only need to do this bit if you have checkpoints starting underwater, otherwise, you can skip this bit of the step. You MUST follow the rest of this step from when you see "11:27, 17 August 2013 (UTC)11:27, 17 August 2013 (UTC)~~" onwards. Anyway, under the label "Obj02_Init:", find and delete these lines:
 
So, go to "Obj02_Init:". You only need to do this bit if you have checkpoints starting underwater, otherwise, you can skip this bit of the step. You MUST follow the rest of this step from when you see "11:27, 17 August 2013 (UTC)11:27, 17 August 2013 (UTC)~~" onwards. Anyway, under the label "Obj02_Init:", find and delete these lines:
 
<asm>
 
<asm>
        move.w #$600,(Tails_top_speed).w       ; set Tails' top speed
+
move.w #$600,(Tails_top_speed).w ; set Tails' top speed
        move.w #$C,(Tails_acceleration).w     ; set Tails' acceleration
+
move.w #$C,(Tails_acceleration).w ; set Tails' acceleration
        move.w #$80,(Tails_deceleration).w     ; set Tails' deceleration
+
move.w #$80,(Tails_deceleration).w ; set Tails' deceleration
 
</asm>
 
</asm>
  
 
and replace with this slightly different code:
 
and replace with this slightly different code:
 
<asm>
 
<asm>
        lea     (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
+
lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
Line 265: Line 261:
 
Next, go to "Obj02_ChkShoes:" and find and delete these lines:
 
Next, go to "Obj02_ChkShoes:" and find and delete these lines:
 
<asm>
 
<asm>
        move.w #$600,(Tails_top_speed).w
+
move.w #$600,(Tails_top_speed).w
        move.w #$C,(Tails_acceleration).w
+
move.w #$C,(Tails_acceleration).w
        move.w #$80,(Tails_deceleration).w
+
move.w #$80,(Tails_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with:
 
and replace with:
 
<asm>
 
<asm>
        lea     (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
+
lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
 
Next, find "Obj02_InWater:" and find and delete these lines:
 
Next, find "Obj02_InWater:" and find and delete these lines:
 
<asm>
 
<asm>
        move.w  #$300,(Tails_top_speed).w
+
move.w  #$300,(Tails_top_speed).w
        move.w  #6,(Tails_acceleration).w
+
move.w  #6,(Tails_acceleration).w
        move.w  #$40,(Tails_deceleration).w
+
move.w  #$40,(Tails_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with:
 
and replace with:
 
<asm>
 
<asm>
        lea     (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
+
lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 
</asm>
 
</asm>
  
 
Next, under "Obj02_OutWater:", find and delete:
 
Next, under "Obj02_OutWater:", find and delete:
 
<asm>
 
<asm>
        move.w #$600,(Tails_top_speed).w
+
move.w #$600,(Tails_top_speed).w
        move.w #$C,(Tails_acceleration).w
+
move.w #$C,(Tails_acceleration).w
        move.w #$80,(Tails_deceleration).w
+
move.w #$80,(Tails_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with:
 
and replace with:
 
<asm>
 
<asm>
        lea     (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
+
lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
        bsr.w   ApplySpeedSettings     ; Fetch Speed settings
+
bsr.w ApplySpeedSettings ; Fetch Speed settings
 +
</asm>
 +
 
 +
If you followed [[SCHG How-to:Fix Tails' respawn speeds|this guide]], then there's one more place to edit: Find label "loc_1BC68:" and find and delete these lines:
 +
<asm>
 +
move.w #$600,(Tails_top_speed).w ; set Tails' top speed
 +
move.w #$C,(Tails_acceleration).w ; set Tails' acceleration
 +
move.w #$80,(Tails_deceleration).w ; set Tails' deceleration
 +
</asm>
 +
 
 +
and replace with:
 +
<asm>
 +
move.l a1,-(sp) ; Backup a1
 +
lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
 +
bsr.w ApplySpeedSettings ; Fetch Speed settings
 +
move.l (sp)+,a1 ; Restore a1
 
</asm>
 
</asm>
  
 
That's Tails. Let's edit the speed shoes object code. Locate label "super_shoes:" and find and delete these lines:
 
That's Tails. Let's edit the speed shoes object code. Locate label "super_shoes:" and find and delete these lines:
 
<asm>
 
<asm>
        move.w  #$C00,(Sonic_top_speed).w
+
move.w  #$C00,(Sonic_top_speed).w
        move.w  #$18,(Sonic_acceleration).w
+
move.w  #$18,(Sonic_acceleration).w
        move.w  #$80,(Sonic_deceleration).w
+
move.w  #$80,(Sonic_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with this new code:
 
and replace with this new code:
 
<asm>
 
<asm>
        movem.l a0-a2,-(sp)             ; Move a0, a1 and a2 onto stack
+
movem.l a0-a2,-(sp) ; Move a0, a1 and a2 onto stack
        lea     (MainCharacter).w,a0   ; Load Sonic to a0
+
lea (MainCharacter).w,a0 ; Load Sonic to a0
        lea     (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
+
lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2
        jsr     ApplySpeedSettings     ; Fetch Speed settings
+
jsr ApplySpeedSettings ; Fetch Speed settings
        movem.l (sp)+,a0-a2             ; Move a0, a1 and a2 from stack
+
movem.l (sp)+,a0-a2 ; Move a0, a1 and a2 from stack
 
</asm>
 
</asm>
  
 
Then finally, go to "loc_12A10" and delete these lines:
 
Then finally, go to "loc_12A10" and delete these lines:
 
<asm>
 
<asm>
        move.w #$C00,(Tails_top_speed).w
+
move.w #$C00,(Tails_top_speed).w
        move.w #$18,(Tails_acceleration).w
+
move.w #$18,(Tails_acceleration).w
        move.w #$80,(Tails_deceleration).w
+
move.w #$80,(Tails_deceleration).w
 
</asm>
 
</asm>
  
 
and replace with this slightly different new code:
 
and replace with this slightly different new code:
 
<asm>
 
<asm>
        movem.l a0-a2,-(sp)             ; Move a0, a1 and a2 onto stack
+
movem.l a0-a2,-(sp) ; Move a0, a1 and a2 onto stack
        lea     (MainCharacter).w,a0   ; Load Tails to a0
+
lea (MainCharacter).w,a0 ; Load Tails to a0
        lea     (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
+
lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2
        jsr     ApplySpeedSettings     ; Fetch Speed settings
+
jsr ApplySpeedSettings ; Fetch Speed settings
        movem.l (sp)+,a0-a2             ; Move a0, a1 and a2 from stack
+
movem.l (sp)+,a0-a2 ; Move a0, a1 and a2 from stack
 
</asm>
 
</asm>
  
Line 345: Line 356:
 
Find "Level_ClrRam:" and directly underneath it before the ClearRAM macros, put this:
 
Find "Level_ClrRam:" and directly underneath it before the ClearRAM macros, put this:
 
<asm>
 
<asm>
        clr.b   (Super_Sonic_flag).w
+
clr.b (Super_Sonic_flag).w
 
</asm>
 
</asm>
  

Revision as of 11:50, 17 August 2014

In Sonic 2, there are multiple speed issue bugs with Sonic and Tails, but first, let's look at Sonic. It's uncommon, but not exactly rare, and when Super Sonic is enabled, it becomes more apparent. But sometimes, Sonic's top speed, acceleration and deceleration can be set wrong. The most common place for the bugs to occur is around the area of ARZ1 where the speed shoes are placed.

With people's hacks putting stuff speed shoes underwater and other places in their layouts, these bugs can happen more often. Such issues include:

  • If Super Sonic and you hit speed shoes, his top speed goes a little bit higher which is fine, but his acceleration and deceleration decreases. Technically, it's applying normal Sonic's speed shoes speed.
  • If you get speed shoes, then go underwater, speed shoes's speed is lost. Even if you get back out of the water, Sonic's speed is normal.
  • If Super Sonic and you get speed shoes, if you go underwater, speed shoes's speed are lost. Even if you get out of the water, Super Sonic's speed is normal.
  • If underwater and you get speed shoes, Sonic's "out-of-water" speed shoes speeds apply, making you go way too fast underwater. Getting out of water or even back in results in the speed shoes speeds being lost, even with speed shoes still applied.
  • If Super Sonic and underwater and you get speed shoes, Normal Sonic's "out-of-water" speed shoes speed apply, making you go way too fast underwater. Getting out of water or even back in and the speed shoes speeds are lost, even with speed shoes applied, but applies Super Sonic's speed settings.
  • If underwater and you get speed shoes, bug above applies but if you never leave the water, once speed shoes wear off, Sonic's normal speed applies, even though you're still underwater, making you still too fast.
  • If Super and underwater and you get speed shoes, the bug 2 bullets above applies but if you never leave the water, once speed shoes wear off, Super Sonic's speed applies, even though you're still underwater, making you still too fast.
  • If underwater and then you transform into Super Sonic, Super Sonic's "out-of-water" speed applies, making you way too fast.
  • If you have speed shoes and then you transform into Super Sonic, Super Sonic's speed applies, making you lose speed shoes speed, making you that bit slower than you should be.
  • If underwater when you have speed shoes and then you transform into Super Sonic, Super Sonic's "out-of-water" speed applies, and you lose your speed shoes speed.
  • If underwater when you have speed shoes and you're Super Sonic and you transform back to normal Sonic, normal Sonic's "underwater" speed applies, making you lose your speed shoes.

A lot, eh? The main issue is that the game never checks to see if you have the speed shoes applied or not. Or when becoming Super and etc, it's not checking if underwater, etc, etc. It would have to do a few checks itself to get it right and I suspect Sonic Team didn't have time to do it as it wasn't particularly important. But we're going to fix these ourselves, and it's much easier than you think.

Please note: I am using Xenowhirl's Sonic 2 disassembly, although this shouldn't be hard to follow if you're using the HG disassembly. KingofHarts note: I've applied this to the HG Sonic 1 disassembly. There should be little to no compatibility issues.

Part 1: Creating new speeds

First of all, we need to make some new speed settings. Here are some of Sonic's speeds settings listed in Sonic 2 currently: <asm>

NORMAL

move.w #$600,(Sonic_top_speed).w move.w #$C,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w

NORMAL SPEED SHOES

move.w #$C00,(Sonic_top_speed).w move.w #$18,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w

SUPER SONIC

move.w #$A00,(Sonic_top_speed).w move.w #$30,(Sonic_acceleration).w move.w #$100,(Sonic_deceleration).w

NORMAL UNDERWATER

move.w #$300,(Sonic_top_speed).w move.w #6,(Sonic_acceleration).w move.w #$40,(Sonic_deceleration).w

SUPER SONIC UNDERWATER

move.w #$500,(Sonic_top_speed).w move.w #$18,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w </asm> As you can see, the game doesn't have speed settings for "Normal underwater with speed shoes", "Super Sonic with speed shoes" or "Super Sonic underwater with speed shoes". No wonder why all these bugs exist. Now, we have to come up with these speeds, which I have already done with some maths involved. To get "Normal underwater with speed shoes", I thought, how does normal Sonic get speed shoes speed? Well, everything is doubled except his deceleration, which stays the same. So I did the same and got this new speed setting.

<asm>

NORMAL UNDERWATER SPEED SHOES

move.w #$600,(Sonic_top_speed).w move.w #$C,(Sonic_acceleration).w move.w #$40,(Sonic_deceleration).w </asm>

It's almost identical to Sonic's normal speed, except his deceleration is slower. To get "Super Sonic with speed shoes", I left the top speed setting it already does alone, but made it not decrease Super Sonic's acceleration and deceleration, making him that tiny bit faster: <asm>

SUPER SONIC SPEED SHOES

move.w #$C00,(Sonic_top_speed).w move.w #$30,(Sonic_acceleration).w move.w #$100,(Sonic_deceleration).w </asm>

To get "Super Sonic underwater with speedshoes", I followed the same method on how "Normal" does it, and got this: <asm>

SUPER SONIC UNDERWATER SPEED SHOES

move.w #$A00,(Sonic_top_speed).w move.w #$30,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w </asm> You do not need to add any of the ASM above into your hack, YET. Just note these for now.

Part 2: Creating a new table

Now we've got all our speeds, we need to put it all into a table, which I have already done on your behalf. You may use the table below, modifying it to your liking.

<asm>

===========================================================================
----------------------------------------------------------------------------
Speed Settings Array
This array defines what speeds the character should be set to
----------------------------------------------------------------------------
top_speed acceleration deceleration ; # ; Comment

Speedsettings: dc.w $600, $C, $80 ; $00 ; Normal dc.w $C00, $18, $80 ; $08 ; Normal Speedshoes dc.w $300, $6, $40 ; $16 ; Normal Underwater dc.w $600, $C, $40 ; $24 ; Normal Underwater Speedshoes dc.w $A00, $30, $100 ; $32 ; Super dc.w $C00, $30, $100 ; $40 ; Super Speedshoes dc.w $500, $18, $80 ; $48 ; Super Underwater dc.w $A00, $30, $80 ; $56 ; Super Underwater Speedshoes

===========================================================================

</asm>

This will be our new table. We'll insert this into the ASM file shortly. First, let's go onto the next step.

Part 3: Creating a new subroutine to apply the speeds

So, we need to create a new subroutine to grab the right speed under Sonic's conditions:

<asm>

===========================================================================
---------------------------------------------------------------------------
Subroutine to collect the right speed setting for a character
a0 must be character
a1 will be the result and have the correct speed settings
a2 is characters' speed
---------------------------------------------------------------------------
||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||

ApplySpeedSettings: moveq #0,d0 ; Quickly clear d0 tst.w speedshoes_time(a0) ; Does character have speedshoes? beq.s + ; If not, branch addq.b #6,d0 ; Quickly add 6 to d0 + btst #6,status(a0) ; Is the character underwater? beq.s + ; If not, branch addi.b #12,d0 ; Add 12 to d0 + cmpa.w #MainCharacter,a0 ; Is it Tails currently following this code? bne.s + ; If so, branch and ignore next question tst.b (Super_Sonic_flag).w ; Is the character Super? beq.s + ; If not, branch addi.b #24,d0 ; Add 24 to d0 + lea Speedsettings(pc,d0.w),a1 ; Load correct speed settings into a1 move.l (a1)+,(a2)+ ; Set character's new top speed and acceleration move.w (a1),(a2) ; Set character's deceleration rts ; Finish subroutine

===========================================================================

</asm>

What this will do is perform checks for stuff like if you're underwater, have speed shoes or are Super and depending on the results, it will add bytes to d0. Once finished with the questions, whatever d0 is, it will multiply itself 3 times. With the new result in d0 after that multiplication, it will then grab data from the table with its starting position being whatever d0 is. For example, say you're normal Sonic and underwater. After the questions, d0 should be 2. Multiply itself 3 times, d0 becomes 16. If you then look for 16 on the table, you'll see that it does indeed equal "Normal Underwater". So it got the right speed setting.

Add this new subroutine to your code, and add the table right below it. The best place to put all of this code is between Sonic's code and Tails' code, preferably right above Tails' code.

Part 4: Replacing code

Now we have our new code, we need to make some jumps to it. First, go to "Obj01_Init:". You only need to do this bit if you have checkpoints starting underwater, otherwise, you can skip this bit of the step. You MUST follow the rest of this step from when you see "************" onward. Anyway, under the label "Obj01_Init:", find and delete these lines: <asm> move.w #$600,(Sonic_top_speed).w ; set Sonic's top speed move.w #$C,(Sonic_acceleration).w ; set Sonic's acceleration move.w #$80,(Sonic_deceleration).w ; set Sonic's deceleration </asm>

and replace with this <asm> lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

************

Under "Obj01_ChkShoes:" find and delete these lines: <asm> move.w #$600,(Sonic_top_speed).w move.w #$C,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w tst.b (Super_Sonic_flag).w beq.s Obj01_RmvSpeed move.w #$A00,(Sonic_top_speed).w move.w #$30,(Sonic_acceleration).w move.w #$100,(Sonic_deceleration).w </asm>

and replace with this <asm> lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

Next, under "Obj01_InWater:" find these lines and delete: <asm> move.w #$300,(Sonic_top_speed).w move.w #6,(Sonic_acceleration).w move.w #$40,(Sonic_deceleration).w tst.b (Super_Sonic_flag).w beq.s + move.w #$500,(Sonic_top_speed).w move.w #$18,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w + </asm>

and replace with: <asm> lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

Next, under "Obj01_OutWater:" find these lines and delete: <asm> move.w #$600,(Sonic_top_speed).w move.w #$C,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w tst.b (Super_Sonic_flag).w beq.s + move.w #$A00,(Sonic_top_speed).w move.w #$30,(Sonic_acceleration).w move.w #$100,(Sonic_deceleration).w + </asm>

and replace with: <asm> lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

Next, go to "Sonic_CheckGoSuper:" and find and delete these lines: <asm> move.w #$A00,(Sonic_top_speed).w move.w #$30,(Sonic_acceleration).w move.w #$100,(Sonic_deceleration).w </asm>

and replace with: <asm> lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

Next, go to "Sonic_RevertToNormal:" and find and delete these lines: <asm> move.w #$600,(Sonic_top_speed).w move.w #$C,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w btst #6,status(a0) ; Check if underwater, return if not beq.s return_1AC3C move.w #$300,(Sonic_top_speed).w move.w #6,(Sonic_acceleration).w move.w #$40,(Sonic_deceleration).w </asm>

and replace with this slightly different code: <asm> lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 bra.w ApplySpeedSettings ; Fetch Speed settings and return </asm>

Now onto Tails. Seeing as how Tails uses the exact same speeds, we can use the exact same table. NOTE: If Tails DOES use different speeds, though, you will want to create a new table. Keep that in mind. So, go to "Obj02_Init:". You only need to do this bit if you have checkpoints starting underwater, otherwise, you can skip this bit of the step. You MUST follow the rest of this step from when you see "11:27, 17 August 2013 (UTC)11:27, 17 August 2013 (UTC)~~" onwards. Anyway, under the label "Obj02_Init:", find and delete these lines: <asm> move.w #$600,(Tails_top_speed).w ; set Tails' top speed move.w #$C,(Tails_acceleration).w ; set Tails' acceleration move.w #$80,(Tails_deceleration).w ; set Tails' deceleration </asm>

and replace with this slightly different code: <asm> lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

11:27, 17 August 2013 (UTC)11:27, 17 August 2013 (UTC)~~

Next, go to "Obj02_ChkShoes:" and find and delete these lines: <asm> move.w #$600,(Tails_top_speed).w move.w #$C,(Tails_acceleration).w move.w #$80,(Tails_deceleration).w </asm>

and replace with: <asm> lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

Next, find "Obj02_InWater:" and find and delete these lines: <asm> move.w #$300,(Tails_top_speed).w move.w #6,(Tails_acceleration).w move.w #$40,(Tails_deceleration).w </asm>

and replace with: <asm> lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

Next, under "Obj02_OutWater:", find and delete: <asm> move.w #$600,(Tails_top_speed).w move.w #$C,(Tails_acceleration).w move.w #$80,(Tails_deceleration).w </asm>

and replace with: <asm> lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings </asm>

If you followed this guide, then there's one more place to edit: Find label "loc_1BC68:" and find and delete these lines: <asm> move.w #$600,(Tails_top_speed).w ; set Tails' top speed move.w #$C,(Tails_acceleration).w ; set Tails' acceleration move.w #$80,(Tails_deceleration).w ; set Tails' deceleration </asm>

and replace with: <asm> move.l a1,-(sp) ; Backup a1 lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2 bsr.w ApplySpeedSettings ; Fetch Speed settings move.l (sp)+,a1 ; Restore a1 </asm>

That's Tails. Let's edit the speed shoes object code. Locate label "super_shoes:" and find and delete these lines: <asm> move.w #$C00,(Sonic_top_speed).w move.w #$18,(Sonic_acceleration).w move.w #$80,(Sonic_deceleration).w </asm>

and replace with this new code: <asm> movem.l a0-a2,-(sp) ; Move a0, a1 and a2 onto stack lea (MainCharacter).w,a0 ; Load Sonic to a0 lea (Sonic_top_speed).w,a2 ; Load Sonic_top_speed into a2 jsr ApplySpeedSettings ; Fetch Speed settings movem.l (sp)+,a0-a2 ; Move a0, a1 and a2 from stack </asm>

Then finally, go to "loc_12A10" and delete these lines: <asm> move.w #$C00,(Tails_top_speed).w move.w #$18,(Tails_acceleration).w move.w #$80,(Tails_deceleration).w </asm>

and replace with this slightly different new code: <asm> movem.l a0-a2,-(sp) ; Move a0, a1 and a2 onto stack lea (MainCharacter).w,a0 ; Load Tails to a0 lea (Tails_top_speed).w,a2 ; Load Tails_top_speed into a2 jsr ApplySpeedSettings ; Fetch Speed settings movem.l (sp)+,a0-a2 ; Move a0, a1 and a2 from stack </asm>

All done. Please note, do not edit under the label "loc_3AA22:". This is the only speed settings that can be left alone. This is when Sonic jumps onto the Tornado at the end of WFZ. This code applies to Super Sonic too (so Super Sonic goes slower) but this is to stop Super Sonic over-shooting the Tornado and falling to his death. The speed only applies when Sonic is about to jump onto the plane.

Be warned! If you have put in other places where you've made the characters change their speed, you'll want to edit them too!

Part 5: Fixing a new bug

With the above fixes applied, a new bug has been introduced. The bug? If you're Super Sonic and you die whilst Super, the "Super_Sonic_flag" will still remain set. This means, once the level restarts, the speed settings will fetch speeds with Super Sonic in mind, because of the flag. So if you go underwater or get spped shoes, it will still think you're Super and take that into account. And if you followed the two steps for when Sonic and Tails get created, then the Super speeds will apply then too.

Also whilst Super Sonic, if you pause the game and press A to quit, the flag will remain set. You could select Tails in options and Tails will have Super speeds. Anyway, let's fix this.

Find "Level_ClrRam:" and directly underneath it before the ClearRAM macros, put this: <asm> clr.b (Super_Sonic_flag).w </asm>

There we go, all bugs should be fixed. Now, when you enter/exit water, enter/exit speed shoes and/or enter/exit Super, the speeds should all be set correctly!

SCHG How-To Guide: Sonic the Hedgehog 2 (16-bit)
Fixing Bugs
Fix Demo Playback | Fix a Race Condition with Pattern Load Cues | Fix Super Sonic Bugs | Use Correct Height When Roll Jumping | Fix Jump Height Bug When Exiting Water | Fix Screen Boundary Spin Dash Bug | Correct Drowning Bugs | Fix Camera Y Position for Tails | Fix Tails Subanimation Error | Fix Tails' Respawn Speeds | Fix Accidental Deletion of Scattered Rings | Fix Ring Timers | Fix Rexon Crash | Fix Monitor Collision Bug | Fix EHZ Deformation Bug | Correct CPZ Boss Attack Behavior | Fix Bug in ARZ Boss Arrow's Platform Behavior | Fix ARZ Boss Walking on Air Glitch | Fix ARZ Boss Sprite Behavior | Fix Multiple CNZ Boss Bugs | Fix HTZ Background Scrolling Mountains | Fix OOZ Launcher Speed Up Glitch | Fix DEZ Giant Mech Collision Glitch | Fix Boss Deconstruction Behavior | Fix Speed Bugs | Fix 14 Continues Cheat | Fix Debug Mode Crash | Fix 99+ Lives | Fix Sonic 2's Sega Screen
Design Choices
Remove the Air Speed Cap | Disable Floor Collision While Dying | Modify Super Sonic Transformation Methods & Behavior | Enable/Disable Tails in Certain Levels | Collide with Water After Being Hurt | Retain Rings When Returning at a Star Post | Improve the Fade In\Fade Out Progression Routines | Fix Scattered Rings' Underwater Physics | Insert LZ Water Ripple Effect | Restore Lost CPZ Boss Feature | Prevent SCZ Tornado Spin Dash Death | Improve ObjectMove Subroutines | Port S3K Rings Manager | Port S3K Object Manager | Port S3K Priority Manager | Edit Level Order with ASM‎ | Alter Ring Requirements in Special Stages | Make Special Stage Characters Use Normal DPLCs | Speed Up Ring Loss Process | Change spike behaviour in Sonic 2
Adding Features
Create Insta-kill and High Jump Monitors | Create Clone and Special Stage Monitors | Port Knuckles
Sound Features
Expand Music Index to Start at $00 | Port Sonic 1 Sound Driver | Port Sonic 2 Clone Driver | Port Sonic 3 Sound Driver | Port Flamewing's Sonic 3 & Knuckles Sound Driver | Expand the Music Index to Start at $00 (Sonic 2 Clone Driver Version) | Play Different Songs Per Act
Extending the Game
Extend the Level Index Past $10 | Extend the Level Select | Extend Water Tables | Add Extra Characters | Free Up 2 Universal SSTs