SCHG How-to

Fix demo playback

From Sonic Retro

(Original guide by FraGag)

In Sonic 1 and Sonic 2, the demo playback routine doesn't behave correctly: it emulates press-press-press-press... instead of press-hold-hold-hold... In other words, it simulates button presses every frame the button is supposed to be held down instead of simulating a press only once. This happens because the game, to determine whether a button should be set to pressed and/or held, compares the button flags of the current frame with the button flags of the previous frame, but the demo playback routine reads the wrong value ($FFF604 instead of $FFF602). This doesn't have any negative effect in the original game demos, because pressing A, B or C while the character is in the air doesn't do anything. However, if you record a demo using the Spin Dash, or new air moves such as the Jump Dash or the Homing Attack, and you hold down A, B or C for more than one frame long, they will trigger too often or too early. The same buggy instruction is also what makes it possible to disrupt a demo by pressing A, B or C while it plays in Sonic 1 REV00.

Recording new demos can be tricky if not done right, and it doesn't help when the demo doesn't play back correctly because of a bug in the original game. Fortunately, this problem is very easy to fix, and this guide will show you how to fix it in Sonic 1 REV00, Sonic 1 REV01 and Sonic 2 (any edition). Sonic 3 and Sonic & Knuckles don't exhibit this behaviour.

Sonic 1 (SVN disassembly)

In _inc\MoveSonicInDemo.asm, under @notcredits, replace these lines:

	if Revision=0
		move.b	(a0),d2
			moveq	#0,d2

with this line:

		move.b	v_jpadhold2-v_jpadhold1(a0),d2

In REV00, it would read from $FFF604, which contains the actual controller input instead of the fake controller input simulated by the demo playback, so this is why the player can disrupt a demo by pressing A, B or C; if this value is zero (i.e. if you don't press anything on the controller), the game will think that no buttons were pressed on the previous frame in the demo, which causes the game to emulate presses on every frame. In REV01, the instruction was changed to clear the register so that the controller input is ignored, making the clever press/hold detection that was supposed to happen completely useless. The solution proposed here makes it read the value from $FFF602, which tell what buttons were pressed in the previous frame in the demo.

Sonic 1 (Hivebrain's 2005 disassembly)

In Hivebrain's 2005 disassembly, this code is under loc_4056. Replace this:

		move.b	(a0),d2

with this:

		move.b	-2(a0),d2

Sonic 2 (SVN disassembly and Xenowhirl's 2007 disassembly)

In Sonic 2, the fix implemented in Sonic 1 REV01 was kept and applied to both characters, so we need to change 2 lines. Under MoveDemo_On_P1, replace:

	moveq	#0,d2 ; this was modified from (a0) to #0 in Rev01 of Sonic 1 to nullify the following line


	move.b	Ctrl_1_Held_Logical-Ctrl_1_Held(a0),d2

and under MoveDemo_On_P2, replace:

	moveq	#0,d2


	move.b	Ctrl_2_Held_Logical-Ctrl_2_Held(a0),d2
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 | 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 | Use Dynamic Palettes
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