Actions

SCHG How-to

Fix the camera follow bug

From Sonic Retro

(Original guide by MarkeyJester)

This bug is almost unnoticable in the original game, if you are to write your own special screen movements that cause the screen to move away from Sonic, and then let the engine move the screen back to Sonic, then it can become noticable

Explaining the issue

The engine that allows the screen to follow Sonic has the responsibility of ensuring that the screen does not move more than 10 (hex) pixels any direction at one time, this is to allow the draw code to draw the lines of 16x16 blocks correctly without skipping any lines, this means that if Sonic is away from the screen's "central box" position by less than 10 (hex) pixels, then the screen's "central box" will move directly to Sonic, if however, Sonic is further than that, the screen will move at a maximum of 10 (hex) pixels in the direction it is suppose to be moving to. The routine "ScrollVertical:" handles this for moving the screen up and down, "ScrollHoriz:" on the other hand (or should I say "ScrollHoriz2:") handles this for the screen moving right, but not when moving left.

Fixing the issue

Observe the code for right movement:

loc_65CC:
		cmpi.w	#$10,d0					; <- Restriction
		bcs.s	loc_65D6				; <- Restriction
		move.w	#$10,d0					; <- Restriction

loc_65D6:
		add.w	($FFFFF700).w,d0
		cmp.w	($FFFFF72A).w,d0
		blt.s	loc_65E4
		move.w	($FFFFF72A).w,d0

As you can see by the code marked "Restriction", this is to prevent the screen from moving right by 10 pixels, thereas if we look at the code for left movement:

loc_65F6:
		add.w	($FFFFF700).w,d0
		cmp.w	($FFFFF728).w,d0
		bgt.s	loc_65E4
		move.w	($FFFFF728).w,d0
		bra.s	loc_65E4

The "Restriction" does not exist, the fix is moderately simple:

loc_65F6:
		cmpi.w	#$FFF0,d0				; has the screen moved more than 10 pixels left?
		bcc.s	Left_NoMax				; if not, branch
		move.w	#$FFF0,d0				; set the maximum move distance to 10 pixels left

Left_NoMax:
		add.w	($FFFFF700).w,d0
		cmp.w	($FFFFF728).w,d0
		bgt.s	loc_65E4
		move.w	($FFFFF728).w,d0
		bra.s	loc_65E4


Horizontal Wrap Bug Fix

Hivebrain Disassembly

This version of the guide is for Hivebrain's 2005 disassembly.

There is another bug related to this which funnily enough is also related to the good old "screen wrapping vertically" bug in Sonic 2 and up, but this is to do with horizontal rather than vertical, at routing "ScrollHoriz2:" we have:

ScrollHoriz2:				; XREF: ScrollHoriz
		move.w	($FFFFD008).w,d0
		sub.w	($FFFFF700).w,d0
		subi.w	#$90,d0
		bcs.s	loc_65F6
		subi.w	#$10,d0
		bcc.s	loc_65CC
		clr.w	($FFFFF73A).w
		rts

bcc and bcs are unsigned branches, the problem here is that if Sonic is behind the screen (I.e. to the left), the result will be negative (I.e. a value from 8000 to FFFF), but with the unsigned branches it will obviously treat 8000 to FFFF as positive and higher than 7FFF, thus it believes it has to move right rather than left, the fix is also simple, change the unsigned branch conditions with signed branch conditions:

ScrollHoriz2:				; XREF: ScrollHoriz
		move.w	($FFFFD008).w,d0
		sub.w	($FFFFF700).w,d0
		subi.w	#$90,d0
		bmi.s	loc_65F6				; cs to mi (for negative)
		subi.w	#$10,d0
		bpl.s	loc_65CC				; cc to pl (for negative)
		clr.w	($FFFFF73A).w
		rts

The cc to pl should not matter, but it's best to be safe.


GitHub Disassembly

This version of the guide is for the GitHub disassembly.

Navigate to _inc\DeformLayers.asm (Rev 00) or _inc\DeformLayers (JP1).asm (Rev 01) and do the following.

Change this:

MoveScreenHoriz:
		move.w	(v_player+obX).w,d0
		sub.w	(v_screenposx).w,d0 ; Sonic's distance from left edge of screen
		subi.w	#144,d0		; is distance less than 144px?
		bcs.s	SH_BehindMid	; if yes, branch
		subi.w	#16,d0		; is distance more than 160px?
		bcc.s	SH_AheadOfMid	; if yes, branch
		clr.w	(v_scrshiftx).w
		rts

To this:

MoveScreenHoriz:
		move.w	(v_player+obX).w,d0
		sub.w	(v_screenposx).w,d0 ; Sonic's distance from left edge of screen
		subi.w	#144,d0		; is distance less than 144px?
		bmi.s	SH_BehindMid	; if yes, branch			<---- cs to mi (for negative)
		subi.w	#16,d0		; is distance more than 160px?
		bpl.s	SH_AheadOfMid	; if yes, branch			<---- cc to pl (for negative)
		clr.w	(v_scrshiftx).w
		rts

The cc to pl should not matter, but it's best to be safe.

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 | Fix a remember sprite related bug
Changing Design Choices
Change Spike Behavior | Collide with Water After Being Hurt | 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 | Add Super Sonic | Add the Air Roll
Sound Features
Expand the Sound Index | Play Different Songs Per Act | Port Sonic 2 Final Sound Driver | Port Sonic 3's Sound Driver | Port Flamewing's Sonic 3 & Knuckles Sound Driver | Change The SEGA Sound
Extending the Game
Load Chunks From ROM | Add Extra Characters | Make an Alternative Title Screen | Use Dynamic Tilesets | Make GHZ Load Alternate Art | Make Ending 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 | Use Dynamic Palettes
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)

|Fix the camera follow bug]]