Since it's been a while, I thought I'd post a new little bug fix I just finished. No wiki this time, sorry. If someone would be kind enough to volunteer to wiki this, I'd be very thankful. Otherwise, I'd just take care of it myself, (whe)never.
What I've got this time is a bug I've actually already posted partial fixes for in the past and even made a slightly better fix recently. Pretty much out of the blue, a much more elegant solution came to me just a few minutes ago.
The bug: The player object's speed values behave inconsistently when entering and exiting water. For instance, if a player falls into water while speed shoes are active, the sped up movement stats will be lost; should the power up run out under water, then the player will receive above water normal stats. This bug exists in all of the four main series games.
The fix (s2 semi recent hg disassembly)
:
First, locate
Obj01_InWater and comment out or remove a few lines as follows:
(...)
; 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
;+
(...)
Do the same for
Obj01_OutWater:
(...)
; 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
;+
(...)
It might seem odd to simply remove these lines, as they are what make the players slower/faster under/above water, but the next set of changes should make the solution clear:
Locate Sonic_Move, which should look like this:
Sonic_Move:
move.w (Sonic_top_speed).w,d6
move.w (Sonic_acceleration).w,d5
move.w (Sonic_deceleration).w,d4
(...)
Underneath the last displayed line, add this:
btst #6,status(a0) ; is Sonic under water?
beq.s + ; if not, branch
lsr.w #1,d4 ; reduce stats
lsr.w #1,d5
lsr.w #1,d6
+
Next, do the same for
Sonic_RollSpeed:
move.w (Sonic_top_speed).w,d6
asl.w #1,d6
move.w (Sonic_acceleration).w,d5
asr.w #1,d5 ; natural roll deceleration = 1/2 normal acceleration
move.w #$20,d4 ; controlled roll deceleration... interestingly,
; this should be Sonic_deceleration/4 according to Tails_RollSpeed,
; which means Sonic is much better than Tails at slowing down his rolling when he's underwater
btst #6,status(a0) ; is Sonic under water?
beq.s + ; if not, branch
lsr.w #1,d5 ; reduce stats
lsr.w #1,d6
+
and
Sonic_ChgJumpDir:
move.w (Sonic_top_speed).w,d6
move.w (Sonic_acceleration).w,d5
asl.w #1,d5
btst #6,status(a0) ; is Sonic under water?
beq.s + ; if not, branch
lsr.w #1,d5 ; reduce stats
lsr.w #1,d6
+
Finally, in
Sonic_RevertToNormal remove the following lines:
(...)
; 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
Of course, these same changes need to be applied to the other player objects where applicable.
In S3&K, the speed stats are not read or written to directly by the player objects. Instead, the address of the first value is loaded into a4 and the RAM addresses are accessed as follows:
move.w #$600,(a4) ; top speed
move.w #$C,2(a4) ; acceleration
move.w #$80,4(a4) ; deceleration
If this fix is applied, the
Wrong speed when transforming under water part of the Super Sonic fixes no longer needs to, or rather, should not be applied.
An explanation: The original problem comes from the fact that there are so many cases to consider when assigning the correct speed values with and without speed shoes and when super. Most of the cases were simply left out. Our fix simply circumvents the problem by calculating the correct under water stats when necessary.
Incidentally, this only works if you wish to preserve the original under water physics, namely making everything half as fast. If for whatever reason someone wants to use a custom set of speed values under water, I will gladly post my previous fix as well.