Actions

SCHG How-to

Difference between revisions of "Fix Scattered Rings Underwater Physics"

From Sonic Retro

(Put the Sonic 1 version of the fix onto the wiki. Will add the other two.)
 
m (Small changes)
Line 1: Line 1:
 
''(Guide for all 3 games written by [[redhotsonic]].''
 
''(Guide for all 3 games written by [[redhotsonic]].''
  
Quote from ''redhotsonic'', - "Ah, the scattered rings when you get hurt. It can cause slowdown to your game, and even mess up the under water palette. Now, when Sonic is underwater, his movement and his gravity is changed so he moves slower to act like he's in water. But when he is hurt under water, isn't it funny that the scattered rings still act the same as if you weren't in water?"
+
Quote from ''redhotsonic'', - "Ah, the scattered rings when you get hurt. It can cause slowdown to your game, and even mess up the underwater palette. Now, when Sonic is underwater, his movement and his gravity is changed so he moves slower to act like he's in water. But when he is hurt under water, isn't it funny that the scattered rings still act the same as if you weren't in water?"
  
 
This is something that occurs in all 3 Sonic the Hedgehog Mega Drive games (and by 3, that IS counting S3&K as one game, though S&K has no water anyway, so it wouldn't be included regardless... but I digress). But is it really a bug? or is it merely a design choice? In either case, it's something that could stand to be fixed, and this guide tells you how to fix the ring physics in all of the games. First off... let's start with the original...
 
This is something that occurs in all 3 Sonic the Hedgehog Mega Drive games (and by 3, that IS counting S3&K as one game, though S&K has no water anyway, so it wouldn't be included regardless... but I digress). But is it really a bug? or is it merely a design choice? In either case, it's something that could stand to be fixed, and this guide tells you how to fix the ring physics in all of the games. First off... let's start with the original...
Line 7: Line 7:
 
'Sonic 1 fix' - ''This guide uses the SVN disassembly.''
 
'Sonic 1 fix' - ''This guide uses the SVN disassembly.''
  
First, In your disassembly, go to "_incObj\25 & 37 Rings.asm"
+
First, In your disassembly, go to "_incObj\'25 & 37 Rings.asm'"
Go to "@makerings:" (part of the scattered rings object code) and find this bit of coding:
+
Go to ''@makerings:'' (part of the scattered rings object code) and find this bit of coding:
 
<asm>
 
<asm>
 
     bsr.w  CalcSine
 
     bsr.w  CalcSine

Revision as of 09:39, 23 April 2012

(Guide for all 3 games written by redhotsonic.

Quote from redhotsonic, - "Ah, the scattered rings when you get hurt. It can cause slowdown to your game, and even mess up the underwater palette. Now, when Sonic is underwater, his movement and his gravity is changed so he moves slower to act like he's in water. But when he is hurt under water, isn't it funny that the scattered rings still act the same as if you weren't in water?"

This is something that occurs in all 3 Sonic the Hedgehog Mega Drive games (and by 3, that IS counting S3&K as one game, though S&K has no water anyway, so it wouldn't be included regardless... but I digress). But is it really a bug? or is it merely a design choice? In either case, it's something that could stand to be fixed, and this guide tells you how to fix the ring physics in all of the games. First off... let's start with the original...

'Sonic 1 fix' - This guide uses the SVN disassembly.

First, In your disassembly, go to "_incObj\'25 & 37 Rings.asm'" Go to @makerings: (part of the scattered rings object code) and find this bit of coding: <asm>

    bsr.w   CalcSine
    move.w  d4,d2
    lsr.w   #8,d2

</asm>

Just underneath, paste this: <asm>

               tst.b   ($FFFFF64C).w           ; Does the level have water?
               beq.s   @skiphalvingvel         ; If not, branch and skip underwater checks
               move.w  ($FFFFF646).w,d6        ; Move water level to d6
               cmp.w   y_pos(a0),d6            ; Is the ring object underneath the water level?
               bgt.s   @skiphalvingvel         ; If not, branch and skip underwater commands
               asr.w   #$1,d0                  ; Half d0.  Makes the ring's x_vel bounce to the left/right slower
               asr.w   #$1,d1                  ; Half d1.  Makes the ring's y_vel bounce up/down slower

@skiphalvingvel: </asm>

'You should end up with something looking like this:' <asm> @makerings:

               move.b  #id_RingLoss,0(a1) ; load bouncing ring object
               addq.b  #2,obRoutine(a1)
               move.b  #8,obHeight(a1)
               move.b  #8,obWidth(a1)
               move.w  obX(a0),obX(a1)
               move.w  obY(a0),obY(a1)
               move.l  #Map_Ring,obMap(a1)
               move.w  #$27B2,obGfx(a1)
               move.b  #4,obRender(a1)
               move.b  #3,obPriority(a1)
               move.b  #$47,obColType(a1)
               move.b  #8,obActWid(a1)
               move.b  #-1,(v_ani3_time).w
               tst.w   d4
               bmi.s   @loc_9D62
               move.w  d4,d0
               bsr.w   CalcSine
               move.w  d4,d2
               lsr.w   #8,d2
               tst.b   ($FFFFF64C).w           ; Does the level have water?
               beq.s   @skiphalvingvel         ; If not, branch and skip underwater checks
               move.w  ($FFFFF646).w,d6        ; Move water level to d6
               cmp.w   y_pos(a0),d6            ; Is the ring object underneath the water level?
               bgt.s   @skiphalvingvel         ; If not, branch and skip underwater commands
               asr.w   #$1,d0                  ; Half d0.  Makes the ring's x_vel bounce to the left/right slower
               asr.w   #$1,d1                  ; Half d1.  Makes the ring's y_vel bounce up/down slower

@skiphalvingvel:

               asl.w   d2,d0
               asl.w   d2,d1
               move.w  d0,d2
               move.w  d1,d3
               addi.b  #$10,d4
               bcc.s   @loc_9D62
               subi.w  #$80,d4
               bcc.s   @loc_9D62
               move.w  #$288,d4

</asm> This ensures that when underwater, the rings x_vel and y_vel are halved so they appear to be moving slower.

Next, go to label "RLoss_Bounce:" and under <asm>

               move.b  (v_ani3_frame).w,obFrame(a0)
               bsr.w   SpeedToPos
               addi.w  #$18,obVelY(a0)

</asm> place this: <asm>

               tst.b   ($FFFFF64C).w           ; Does the level have water?
               beq.s   @skipbounceslow         ; If not, branch and skip underwater checks
               move.w  ($FFFFF646).w,d6        ; Move water level to d6
               cmp.w   y_pos(a0),d6            ; Is the ring object underneath the water level?
               bgt.s   @skipbounceslow         ; If not, branch and skip underwater commands
               subi.w  #$E,obVelY(a0)          ; Reduce gravity by $E ($18-$E=$A), giving the underwater effect

@skipbounceslow: </asm> You can change the value of the gravity if you like, but I found $E to suit. Anyway, you should have something looking like this: <asm> RLoss_Bounce:  ; Routine 2

               move.b  (v_ani3_frame).w,obFrame(a0)
               bsr.w   SpeedToPos
               addi.w  #$18,obVelY(a0)
               tst.b   ($FFFFF64C).w           ; Does the level have water?
               beq.s   @skipbounceslow         ; If not, branch and skip underwater checks
               move.w  ($FFFFF646).w,d6        ; Move water level to d6
               cmp.w   y_pos(a0),d6            ; Is the ring object underneath the water level?
               bgt.s   @skipbounceslow         ; If not, branch and skip underwater commands
               subi.w  #$E,obVelY(a0)          ; Reduce gravity by $E ($18-$E=$A), giving the underwater effect

@skipbounceslow:

               bmi.s   @chkdel
               move.b  (v_vbla_byte).w,d0
               add.b   d7,d0
               andi.b  #3,d0
               bne.s   @chkdel
               jsr     ObjFloorDist
               tst.w   d1
               bpl.s   @chkdel
               add.w   d1,obY(a0)
               move.w  obVelY(a0),d0
               asr.w   #2,d0
               sub.w   d0,obVelY(a0)
               neg.w   obVelY(a0)

</asm> This ensures when underwater, the gravity is not as great. Otherwise, the rings will gain speed and then it won't give the desired underwater effect.