Actions

SCHG How-to

Fix Accidental Deletion of Scattered Rings

From Sonic Retro

(Original guide by redhotsonic)

The Problem

There is a glitch within the scattered rings. Let me explain. In the scattered rings code, there is a check to see if rings have reached the bottom of the level and if so, to delete themselves. Here is some code from Sonic 2's scattered rings object.

loc_121B8:
        tst.b   (Ring_spill_anim_counter).w
        beq.s   BranchTo5_DeleteObject
        move.w  (Camera_Max_Y_pos_now).w,d0     ; HERE
        addi.w  #$E0,d0                         ; HERE
        cmp.w   y_pos(a0),d0                    ; HERE
        bcs.s   BranchTo5_DeleteObject          ; HERE
        bra.w   DisplaySprite

It has this code because when rings reach to the bottom of the level, they delete themselves, so they do not spawn at the top of the level (they won't loop). This is a good thing, as we don't want rings looping, right? But there is an issue with levels that are y-wrapped enabled. Easy example: Sonic 2's Metropolis Zone, Act 2.


FixDeletionOfScatteredRings Image1.png

If you go to these co-ordinates in MTZ2, you will see Asteron (starfish badnik) to the right. Go to him and let him hurt you.


FixDeletionOfScatteredRings Image2.png

I've just got hurt, look at all the rings that are about to scatter. But, the bottom line of the level is right above me.


FixDeletionOfScatteredRings Image3.png

Look at that! Most of my rings have suddenly vanished! To help, I've drawn a red line. That's the line where if the rings reach, to delete themselves. The rings think that that line is the bottom of the level, but because this level is y-wrapped, technically, there is no "bottom of level". So we still want the rings to be there so we can collect them.


NOTE: This bug is also present in Sonic 1 & 3K, but it is quite hard to pull the glitch off. Generally because the only time you're passing the y-wrap in S1 and S3K, is when you're in the water slide in LZ Act 3, or in the ice tunnel in ICZ Act 1.

But if you're editing these level layouts to cross the y-wrap quite often, the glitch may become more apparent. And you might want to fix it. Therefore, we will cover fixing this for ALL 3 games! Lets start with Sonic 1, and work our way forward...

The Fix

NOTE: The fix I have added, I've not equated. That way, the fix is compatible with any disassembly you are using. I've told what disassembly for which game I'm going by, but if you're using any other disassembly, you can still use my fix. Credit to Berserker6 for adding the Hivebrain 2005 instructions.

Sonic 1 fix- SVN

Go to "@chkdel:" and you'll see this:

	@chkdel:
		tst.b	(v_ani3_time).w
		beq.s	RLoss_Delete
		move.w	(v_limitbtm2).w,d0
		addi.w	#$E0,d0
		cmp.w	obY(a0),d0	; has object moved below level boundary?
		bcs.s	RLoss_Delete	; if yes, branch
		bra.w	DisplaySprite

Right after the first branch to "RLoss_Delete", insert this:

		cmpi.w	#$FF00,($FFFFF72C).w		; is vertical wrapping enabled?
		beq.w	DisplaySprite			; if so, branch

So, you have something like this:

	@chkdel:
		tst.b	(v_ani3_time).w
		beq.s	RLoss_Delete
		cmpi.w	#$FF00,($FFFFF72C).w		; is vertical wrapping enabled?
		beq.w	DisplaySprite			; if so, branch
		move.w	(v_limitbtm2).w,d0
		addi.w	#$E0,d0
		cmp.w	obY(a0),d0	; has object moved below level boundary?
		bcs.s	RLoss_Delete	; if yes, branch
		bra.w	DisplaySprite

Sonic 1 fix- Hivebrain's 2005 Disassembly

Go to "Obj37_ChkDel:" and you'll see this:

Obj37_ChkDel:				; XREF: Obj37_Bounce
		tst.b	($FFFFFEC6).w
		beq.s	Obj37_Delete
		move.w	($FFFFF72E).w,d0
		addi.w	#$E0,d0
		cmp.w	$C(a0),d0	; has object moved below level boundary?
		bcs.s	Obj37_Delete	; if yes, branch
		bra.w	DisplaySprite

Right after the first branch to "Obj37_Delete", insert this:

		cmpi.w	#$FF00,($FFFFF72C).w		; is vertical wrapping enabled?
		beq.w	DisplaySprite			; if so, branch

So, you have something like this:

Obj37_ChkDel:				; XREF: Obj37_Bounce
		tst.b	($FFFFFEC6).w
		beq.s	Obj37_Delete
		cmpi.w	#$FF00,($FFFFF72C).w		; is vertical wrapping enabled?
		beq.w	DisplaySprite			; if so, branch
		move.w	($FFFFF72E).w,d0
		addi.w	#$E0,d0
		cmp.w	$C(a0),d0	; has object moved below level boundary?
		bcs.s	Obj37_Delete	; if yes, branch
		bra.w	DisplaySprite

Sonic 2 Xenowhirl fix

Go to "loc_121B8:" and you'll see this:

loc_121B8:
	tst.b	(Ring_spill_anim_counter).w
	beq.s	BranchTo5_DeleteObject
	move.w	(Camera_Max_Y_pos_now).w,d0
	addi.w	#$E0,d0
	cmp.w	y_pos(a0),d0
	bcs.s	BranchTo5_DeleteObject
	bra.w	DisplaySprite

Right after the first branch to "BranchTo5_DeleteObject", insert this:

	cmpi.w	#$FF00,($FFFFEECC).w		; is vertical wrapping enabled?
	beq.w	DisplaySprite			; if so, branch

So, you have something like this:

loc_121B8:
	tst.b	(Ring_spill_anim_counter).w
	beq.s	BranchTo5_DeleteObject
	cmpi.w	#$FF00,($FFFFEECC).w		; is vertical wrapping enabled?
	beq.w	DisplaySprite			; if so, branch
	move.w	(Camera_Max_Y_pos_now).w,d0
	addi.w	#$E0,d0
	cmp.w	y_pos(a0),d0
	bcs.s	BranchTo5_DeleteObject
	bra.w	DisplaySprite


For those who are using the GitHub dissasmbly

BranchTo5_DeleteObject

Appears as

Obj37_Delete

Sonic 3K fix

This guide uses the SVN disassembly.

Go to "loc_1A79C" and you'll see this:

loc_1A79C:
		tst.b	(Ring_spill_anim_counter).w
		beq.s	loc_1A7E4
		move.w	(Camera_max_Y_pos).w,d0
		addi.w	#$E0,d0
		cmp.w	$14(a0),d0
		bcs.s	loc_1A7E4

Right after the first branch to "loc_1A7E4", insert this:

		cmpi.w	#$FF00,($FFFFEE18).w		; is vertical wrapping enabled?
		beq.w	loc_1A7B0			; if so, branch

So, you have something like this:

loc_1A79C:
		tst.b	(Ring_spill_anim_counter).w
		beq.s	loc_1A7E4
		cmpi.w	#$FF00,($FFFFEE18).w		; is vertical wrapping enabled?
		beq.w	loc_1A7B0			; if so, branch
		move.w	(Camera_max_Y_pos).w,d0
		addi.w	#$E0,d0
		cmp.w	$14(a0),d0
		bcs.s	loc_1A7E4

The bug explained

Basically, whenever rings fall to the bottom of the level, they delete themselves to stop from looping and coming from the top of the screen (like Sonic does on y-wrapped levels). But with levels with y-wrap enabled, the rings would still delete themselves when they reached those same co-ordinates. In the pictures provided as examples (In the OP), those rings reached the co-ordinates and deleted themselves, which we don't want theoretically, there is no bottom of level and you want your rings back!

So, all we've done here to all 3 games, is if y-wrap is enabled, do not delete the rings if they've reached the co-ordinates. Only if y-wrap is disabled, will the game delete the rings once they've reached the bottom of the level.

The rings itself will still delete themselves after a certain amount of time, so, you do not need to worry about them being around forever if y-wrap is enabled.

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
Changing Design Choices
Change Spike Behavior | 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
Sound Features
Expand Music Index From $94 to $9F | Extend Music Slots | Play Different Songs Per Act | Expand Music Index to Start at $00 | Port Sonic 2 Final Sound Driver | Port Sonic 3's Sound Driver
Extending the Game
Load Chunks From ROM | Add Extra Characters | Make an Alternative Title Screen | Use Dynamic Tilesets | Make GHZ 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
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)


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 Spin Dash Code and Add Spin Dash Speeds | 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
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 | Add beta spindash to Sonic 2 | 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
Port Sonic 1 Sound Driver | Port Sonic 2 Clone Driver | Port Sonic 3 Sound Driver | Expand the Music Index to Start at $00 (Sonic 2 Clone Driver Version)
Extending the Game
Extend the Level Index Past $10 | Extend the Level Select | Extend Water Tables | Add Extra Characters | Free Up 2 Universal SSTs