For a Sonic 2 guide, keep reading this post.
For a Sonic 1 guide, read this post.
For a Sonic 3 and Knuckles guide, read this post.
(This isn't actually a bug as such, it's a design change. This guide is for Sonic 2)

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?

In this very short tutorial, I will tell you how to make the rings act correctly under water. I am using Xenowhirl's Disassembly. For other disassemblies, it must be extremely similar to this so I'm sure you won't have a problem if you follow this guide. Remember, always back up your disassembly first before following guides. I will not be held responsible if anything goes wrong.
First, go to "loc_120BA:" (part of the scattered rings object code) and find this bit of coding:
bsr.w JmpTo4_CalcSine move.w d4,d2 lsr.w #8,d2
Just underneath, paste this:
tst.b (Water_flag).w ; Does the level have water? beq.s + ; If not, branch and skip underwater checks move.w (Water_Level_2).w,d6 ; Move water level to d6 cmp.w y_pos(a0),d6 ; Is the ring object underneath the water level? bgt.s + ; 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 +
So, you should end up with something looking like this:
loc_120BA: _move.b #$37,0(a1) ; load obj37 addq.b #2,routine(a1) move.b #8,y_radius(a1) move.b #8,x_radius(a1) move.w x_pos(a0),x_pos(a1) move.w y_pos(a0),y_pos(a1) move.l #Obj25_MapUnc_12382,mappings(a1) move.w #$26BC,art_tile(a1) bsr.w Adjust2PArtPointer2 move.b #$84,render_flags(a1) move.b #3,priority(a1) move.b #$47,collision_flags(a1) move.b #8,width_pixels(a1) move.b #-1,(Ring_spill_anim_counter).w tst.w d4 bmi.s loc_12132 move.w d4,d0 bsr.w JmpTo4_CalcSine move.w d4,d2 lsr.w #8,d2 tst.b (Water_flag).w ; Does the level have water? beq.s + ; If not, branch and skip underwater checks move.w (Water_Level_2).w,d6 ; Move water level to d6 cmp.w y_pos(a0),d6 ; Is the ring object underneath the water level? bgt.s + ; 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 + asl.w d2,d0 asl.w d2,d1 move.w d0,d2 move.w d1,d3 addi.b #$10,d4 bcc.s loc_12132 subi.w #$80,d4 bcc.s loc_12132 move.w #$288,d4
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 "Obj_37_sub_2:" and under
move.b (Ring_spill_anim_frame).w,mapping_frame(a0) bsr.w ObjectMove addi.w #$18,y_vel(a0)
Put this:
tst.b (Water_flag).w ; Does the level have water? beq.s + ; If not, branch and skip underwater checks move.w (Water_Level_2).w,d6 ; Move water level to d6 cmp.w y_pos(a0),d6 ; Is the ring object underneath the water level? bgt.s + ; If not, branch and skip underwater commands subi.w #$E,y_vel(a0) ; Reduce gravity by $E ($18-$E=$A), giving the underwater effect for the rings +
You can change the value of the gravity if you like, but I found $E to suit.
So, you should have something looking like this:
Obj_37_sub_2: move.b (Ring_spill_anim_frame).w,mapping_frame(a0) bsr.w ObjectMove addi.w #$18,y_vel(a0) tst.b (Water_flag).w ; Does the level have water? beq.s + ; If not, branch and skip underwater checks move.w (Water_Level_2).w,d6 ; Move water level to d6 cmp.w y_pos(a0),d6 ; Is the ring object underneath the water level? bgt.s + ; If not, branch and skip underwater commands subi.w #$E,y_vel(a0) ; Reduce gravity by $E ($18-$E=$A), giving the underwater effect for the rings + bmi.s loc_121B8 move.b ($FFFFFE0F).w,d0 add.b d7,d0 andi.b #7,d0 bne.s loc_121B8 tst.b render_flags(a0) bpl.s loc_121D0 jsr (RingCheckFloorDist).l tst.w d1 bpl.s loc_121B8 add.w d1,y_pos(a0) move.w y_vel(a0),d0 asr.w #2,d0 sub.w d0,y_vel(a0) neg.w y_vel(a0)
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.
And that's it. Save, build and test.
I don't think I've ever seen anyone do this in their hack. I've just applied to it in my Sonic 2 Recreation hack. I hope to see this in more hacks from now on!
In case, here is a Sonic 2 Rom, only edited to include the underwater Scattered rings. To see for yourself.
Cheers,
redhotsonic

