Actions

SCHG How-to

Difference between revisions of "Sonic 2 (Simon Wai Prototype) Level Select in Sonic 1"

From Sonic Retro

(Level Select Music Fix)
m (Text replacement - "\[\[Category:SCHG How-tos.*" to "")
(18 intermediate revisions by 6 users not shown)
Line 1: Line 1:
you probably wonder why sonic2 beta has that level select that looks almost like the sonic1 level select and how sonic2 nick arcade prototype has one that '''is''' the sonic1 level select, well, '''that''' is what we are going to make the one in sonic1 behave like.
+
{{GuideBy|Kram1024}}
 +
 
 +
You probably wonder why Sonic 2 Beta has that level select that looks almost like the Sonic 1 level select, and how Sonic 2 Nick Arcade prototype has one that '''is''' the Sonic 1 level select. Well, '''that''' is what we are going to make the one in Sonic 1 behave like.
  
 
===Overview===
 
===Overview===
First, lets look at an overview of what our level select code looks like in a normal sonic1 (It is from the Hivebrain disassembly):
+
First, let's look at an overview of what our level select code looks like normally in Sonic 1 (this is from the Hivebrain disassembly):
<asm>
+
<syntaxhighlight lang="asm">; ---------------------------------------------------------------------------
; ---------------------------------------------------------------------------
 
 
; Level Select
 
; Level Select
 
; ---------------------------------------------------------------------------
 
; ---------------------------------------------------------------------------
Line 109: Line 110:
  
  
</asm>
+
</syntaxhighlight>
 
Notice anything here?
 
Notice anything here?
  
 
===Button Fix, Part 1===
 
===Button Fix, Part 1===
A lot of stuff we really do not need, as well as the fast that all buttons that are not the D-Pad seem to be used to play a sound or select a level. Lets fix that.
+
A lot of stuff here we really do not need, as well as the fact that all buttons that are not the D-Pad seem to be used to play a sound or select a level. Let's fix that.
<asm>
+
<syntaxhighlight lang="asm">
 
LevelSelect:
 
LevelSelect:
 
move.b #4,($FFFFF62A).w
 
move.b #4,($FFFFF62A).w
Line 145: Line 146:
 
bsr.w PlaySound_Special
 
bsr.w PlaySound_Special
 
bra.s LevelSelect
 
bra.s LevelSelect
</asm>
+
</syntaxhighlight>
  
we do not need the japanese credits code, removed that junk. as for the levels, we want to start them with the start button but not exclusively just the start button, so an andi would be used there. Also, we want start to exit back to the sega screen, and why not some nice music? only B or C should play something on the sound test.
+
We do not need the Japanese credits code, removed that junk. As for the levels, we want to start them with {{start}} but not exclusively just {{start}}, so an andi would be used there. Also, we want {{start}} to exit back to the Sega screen, and why not some nice music? Only {{B}} or {{C}} should play something on the sound test.
  
the results should look like this:
+
The results should look like this:
  
<asm>
+
<syntaxhighlight lang="asm">
 
LevelSelect:
 
LevelSelect:
 
move.b #4,($FFFFF62A).w
 
move.b #4,($FFFFF62A).w
Line 191: Line 192:
 
jmp MainGameLoop ;go to sega screen
 
jmp MainGameLoop ;go to sega screen
  
</asm>
+
</syntaxhighlight>
  
 
===Level Select Music Fix===
 
===Level Select Music Fix===
That fixes the level select so that it runs levels in a sonic2 manner, but it doesnt fix the music. Lets do thar now.
+
That fixes the level select so that it runs levels in a Sonic 2 manner, but it doesn't fix the music. Let's do that now.
  
find:
+
Find:
<asm>
+
<syntaxhighlight lang="asm">
 
Title_ClrVram:
 
Title_ClrVram:
 
move.l d0,(a6)
 
move.l d0,(a6)
Line 203: Line 204:
  
 
bsr.w LevSelTextLoad
 
bsr.w LevSelTextLoad
</asm>
+
</syntaxhighlight>
  
and add under ''dbf d1,Title_ClrVram ; fill VRAM with 0'', t6ese lines:
+
and add under ''dbf d1,Title_ClrVram ; fill VRAM with 0'', these lines:
<asm>
+
<syntaxhighlight lang="asm">
        move.b  #$81,d0
+
move.b  #$81,d0
        jsr PlaySound
+
jsr PlaySound
</asm>
+
</syntaxhighlight>
 
replace #$81 with your choice of song.
 
replace #$81 with your choice of song.
  
 
the result should look like:
 
the result should look like:
<asm>
+
<syntaxhighlight lang="asm">
 
Title_ClrVram:
 
Title_ClrVram:
 
move.l d0,(a6)
 
move.l d0,(a6)
 
dbf d1,Title_ClrVram ; fill VRAM with 0
 
dbf d1,Title_ClrVram ; fill VRAM with 0
        move.b  #$81,d0
+
move.b  #$81,d0
        jsr PlaySound
+
jsr PlaySound
 
bsr.w LevSelTextLoad
 
bsr.w LevSelTextLoad
</asm>
+
</syntaxhighlight>
 +
Green Hill Zone music at the level select, how lovely. On the other hand, if you plan on using [[SCHG_How-to:Port_Sonic_2_Final_Sound_Driver_to_Sonic_1 | my Sonic 2 Sound Driver port]], try using music number $91 and PlayMusic as opposed to PlaySound.
 +
 
 +
===Button Fix, Part 2===
 +
As you already know, {{A}} is not yet fixed, time to fix that button:
 +
 
 +
First, we will have to edit the "LevSel_SndTest" routine. $C (left and right) will not work for detecting {{A}}. We will need $4C (A/Left/Right) instead, so look in our function for:
 +
<syntaxhighlight lang="asm">
 +
LevSel_SndTest: ; XREF: LevSelControls
 +
cmpi.w #$14,($FFFFFF82).w ; is item $14 selected?
 +
bne.s LevSel_NoMove ; if not, branch
 +
move.b ($FFFFF605).w,d1
 +
andi.b #$C,d1 ; is left/right pressed?
 +
</syntaxhighlight>
 +
 
 +
and change it to read out:
 +
<syntaxhighlight lang="asm">
 +
LevSel_SndTest: ; XREF: LevSelControls
 +
cmpi.w #$14,($FFFFFF82).w ; is item $14 selected?
 +
bne.s LevSel_NoMove ; if not, branch
 +
move.b ($FFFFF605).w,d1
 +
andi.b #$4C,d1 ; is left/right/A pressed?
 +
 
 +
</syntaxhighlight>
 +
instead.
 +
 
 +
Now we can start working on adding the routine to handle {{A}} and increase the 16's ($10) part of the sound test:
 +
 
 +
locate:
 +
<syntaxhighlight lang="asm">
 +
beq.s LevSel_NoMove ; if not, branch
 +
move.w ($FFFFFF84).w,d0
 +
</syntaxhighlight>
 +
 
 +
and add below:
 +
<syntaxhighlight lang="asm">
 +
btst #6,d1 ; is A pressed?
 +
bne.s LevSel_A ; if not, branch
 +
</syntaxhighlight>
 +
 
 +
Now locate:
 +
<syntaxhighlight lang="asm">
 +
bcc.s LevSel_Right
 +
moveq #$4F,d0 ; if sound test moves below 0, set to $4F
 +
</syntaxhighlight>
 +
 
 +
and add this routine under it to add {{A}} support to the level select:
 +
<syntaxhighlight lang="asm">
 +
LevSel_A:
 +
btst #6,d1 ; is A button pressed?
 +
beq.s LevSel_Right ; if not, branch
 +
add.w #16,d0 ; add $10 to sound test
 +
cmpi.w #$50,d0         ; addition by Shadow05 to stop the sound test from going above $D0
 +
bcs.s LevSel_Refresh2
 +
moveq #0,d0 ; if sound test moves above $4F, set to 0
 +
</syntaxhighlight>
 +
 
 +
===Button Fix, Part 3 {optional}===
 +
 
 +
Incase you want to make it so when you press B or C you go back 10 just repeat the steps for B.
 +
 
 +
===Play Sounds $94-$9F===
 +
{{GuideBy|SoullessSentinel}}
 +
 
 +
In Sonic 1 you might notice you can't play sounds $94-$9F to fix this find this.
 +
<syntaxhighlight lang="asm">LevSel_NoCheat:
 +
        cmpi.w    #$94,d0    ; is sound $80-$94 being played?
 +
        bcs.s    LevSel_PlaySnd; if yes, branch
 +
        cmpi.w    #$A0,d0    ; is sound $95-$A0 being played?
 +
        bcs.s    LevelSelect; if yes, branch</syntaxhighlight>
 +
Change the line:
 +
<syntaxhighlight lang="asm">        cmpi.w    #$94,d0    ; is sound $80-$94 being played?</syntaxhighlight>
 +
So it reads:
 +
<syntaxhighlight lang="asm">        cmpi.w    #$A0,d0    ; is sound $80-$9F being played?</syntaxhighlight>
 +
Then rebuild the ROM.
 +
 
 +
And now the sound test will have the music slots going up to $9F, instead of $94, however attempts to play empty music slots will crash the sound driver, and possibly lock up the emulator. So, make sure you include a song in every slot.
 +
 
 +
===Notes===
 +
*The disassembly's comments are incorrect. The correct ID ranges are $80-$93 and $94-$9F.
 +
*If you play sounds $94-$9F without inserting any music the game will crash!
  
[[Category:SCHG How-tos|Sonic2 (Simon Wai Prototype) Level Select for Sonic1]]
+
===Conclusion===
 +
Now the Sonic 1 level select will behave exactly like that of the one in Sonic 2 (Simon Wai prototype, except for night mode and split screen, those can be added manually if you get such a system working). Enjoy your alternative level select :)
 +
{{S1Howtos}}
 +
|{{PAGENAME}}]]

Revision as of 10:50, 25 August 2018

(Original guide by Kram1024)

You probably wonder why Sonic 2 Beta has that level select that looks almost like the Sonic 1 level select, and how Sonic 2 Nick Arcade prototype has one that is the Sonic 1 level select. Well, that is what we are going to make the one in Sonic 1 behave like.

Overview

First, let's look at an overview of what our level select code looks like normally in Sonic 1 (this is from the Hivebrain disassembly):

; ---------------------------------------------------------------------------
; Level	Select
; ---------------------------------------------------------------------------

LevelSelect:
		move.b	#4,($FFFFF62A).w
		bsr.w	DelayProgram
		bsr.w	LevSelControls
		bsr.w	RunPLC_RAM
		tst.l	($FFFFF680).w
		bne.s	LevelSelect
		andi.b	#$F0,($FFFFF605).w ; is	A, B, C, or Start pressed?
		beq.s	LevelSelect	; if not, branch
		move.w	($FFFFFF82).w,d0
		cmpi.w	#$14,d0		; have you selected item $14 (sound test)?
		bne.s	LevSel_Level_SS	; if not, go to	Level/SS subroutine
		move.w	($FFFFFF84).w,d0
		addi.w	#$80,d0
		tst.b	($FFFFFFE3).w	; is Japanese Credits cheat on?
		beq.s	LevSel_NoCheat	; if not, branch
		cmpi.w	#$9F,d0		; is sound $9F being played?
		beq.s	LevSel_Ending	; if yes, branch
		cmpi.w	#$9E,d0		; is sound $9E being played?
		beq.s	LevSel_Credits	; if yes, branch

LevSel_NoCheat:
		cmpi.w	#$94,d0		; is sound $80-$94 being played?
		bcs.s	LevSel_PlaySnd	; if yes, branch
		cmpi.w	#$A0,d0		; is sound $95-$A0 being played?
		bcs.s	LevelSelect	; if yes, branch

LevSel_PlaySnd:
		bsr.w	PlaySound_Special
		bra.s	LevelSelect
; ===========================================================================

LevSel_Ending:				; XREF: LevelSelect
		move.b	#$18,($FFFFF600).w ; set screen	mode to	$18 (Ending)
		move.w	#$600,($FFFFFE10).w ; set level	to 0600	(Ending)
		rts	
; ===========================================================================

LevSel_Credits:				; XREF: LevelSelect
		move.b	#$1C,($FFFFF600).w ; set screen	mode to	$1C (Credits)
		move.b	#$91,d0
		bsr.w	PlaySound_Special ; play credits music
		move.w	#0,($FFFFFFF4).w
		rts	
; ===========================================================================

LevSel_Level_SS:			; XREF: LevelSelect
		add.w	d0,d0
		move.w	LSelectPointers(pc,d0.w),d0 ; load level number
		bmi.w	LevelSelect
		cmpi.w	#$700,d0	; check	if level is 0700 (Special Stage)
		bne.s	LevSel_Level	; if not, branch
		move.b	#$10,($FFFFF600).w ; set screen	mode to	$10 (Special Stage)
		clr.w	($FFFFFE10).w	; clear	level
		move.b	#3,($FFFFFE12).w ; set lives to	3
		moveq	#0,d0
		move.w	d0,($FFFFFE20).w ; clear rings
		move.l	d0,($FFFFFE22).w ; clear time
		move.l	d0,($FFFFFE26).w ; clear score
		rts	
; ===========================================================================

LevSel_Level:				; XREF: LevSel_Level_SS
		andi.w	#$3FFF,d0
		move.w	d0,($FFFFFE10).w ; set level number

PlayLevel:				; XREF: ROM:00003246�j ...
		move.b	#$C,($FFFFF600).w ; set	screen mode to $0C (level)
		move.b	#3,($FFFFFE12).w ; set lives to	3
		moveq	#0,d0
		move.w	d0,($FFFFFE20).w ; clear rings
		move.l	d0,($FFFFFE22).w ; clear time
		move.l	d0,($FFFFFE26).w ; clear score
		move.b	d0,($FFFFFE16).w ; clear special stage number
		move.b	d0,($FFFFFE57).w ; clear emeralds
		move.l	d0,($FFFFFE58).w ; clear emeralds
		move.l	d0,($FFFFFE5C).w ; clear emeralds
		move.b	d0,($FFFFFE18).w ; clear continues
		move.b	#$E0,d0
		bsr.w	PlaySound_Special ; fade out music
		rts	
; ===========================================================================
; ---------------------------------------------------------------------------
; Level	select - level pointers
; ---------------------------------------------------------------------------
LSelectPointers:
		binclude	misc\ls_point.bin
		align 2
; ---------------------------------------------------------------------------
; Level	select codes
; ---------------------------------------------------------------------------
LevelSelectCode_J:
		binclude	misc\ls_jcode.bin
		align 2

LevelSelectCode_US:
		binclude	misc\ls_ucode.bin
		align 2
; ===========================================================================

Notice anything here?

Button Fix, Part 1

A lot of stuff here we really do not need, as well as the fact that all buttons that are not the D-Pad seem to be used to play a sound or select a level. Let's fix that.

LevelSelect:
		move.b	#4,($FFFFF62A).w
		bsr.w	DelayProgram
		bsr.w	LevSelControls
		bsr.w	RunPLC_RAM
		tst.l	($FFFFF680).w
		bne.s	LevelSelect
		andi.b	#$F0,($FFFFF605).w ; is	A, B, C, or Start pressed?
		beq.s	LevelSelect	; if not, branch
		move.w	($FFFFFF82).w,d0
		cmpi.w	#$14,d0		; have you selected item $14 (sound test)?
		bne.s	LevSel_Level_SS	; if not, go to	Level/SS subroutine
		move.w	($FFFFFF84).w,d0
		addi.w	#$80,d0
		tst.b	($FFFFFFE3).w	; is Japanese Credits cheat on?
		beq.s	LevSel_NoCheat	; if not, branch
		cmpi.w	#$9F,d0		; is sound $9F being played?
		beq.s	LevSel_Ending	; if yes, branch
		cmpi.w	#$9E,d0		; is sound $9E being played?
		beq.s	LevSel_Credits	; if yes, branch

LevSel_NoCheat:
		cmpi.w	#$94,d0		; is sound $80-$94 being played?
		bcs.s	LevSel_PlaySnd	; if yes, branch
		cmpi.w	#$A0,d0		; is sound $95-$A0 being played?
		bcs.s	LevelSelect	; if yes, branch

LevSel_PlaySnd:
		bsr.w	PlaySound_Special
		bra.s	LevelSelect

We do not need the Japanese credits code, removed that junk. As for the levels, we want to start them with Start but not exclusively just Start, so an andi would be used there. Also, we want Start to exit back to the Sega screen, and why not some nice music? Only B or C should play something on the sound test.

The results should look like this:

LevelSelect:
		move.b	#4,($FFFFF62A).w
		bsr.w	DelayProgram
		bsr.w	LevSelControls
		bsr.w	RunPLC_RAM
		tst.l	($FFFFF680).w
		bne.s	LevelSelect
		move.w	($FFFFFF82).w,d0
		cmpi.w	#$14,d0		; have you selected item $14 (sound test)?
		bne.s	LevSelLevCheckStart; if not, go to	Level/SS subroutine
		cmpi.b	#$80,($FFFFF605).w ; is	Start pressed?
		beq.s	LevSelStartPress	; if true, branch
		cmpi.b	#$20,($FFFFF605).w ; is	B pressed?
		beq.s	LevSelBCPress	; if not, branch
		cmpi.b	#$10,($FFFFF605).w ; is	C pressed?
		beq.s	LevSelBCPress	; if not, branch
		bra.s	LevelSelect
; ===========================================================================
LevSelLevCheckStart:				; XREF: LevelSelect
		andi.b	#$80,($FFFFF605).w ; is	Start pressed?
		beq.s	LevelSelect	; if not, branch
		bra.s	LevSel_Level_SS

LevSelBCPress:				; XREF: LevelSelect
		move.w	($FFFFFF84).w,d0
		addi.w	#$80,d0
		cmpi.w	#$94,d0		; is sound $80-$94 being played?
		bcs.s	LevSel_PlaySnd	; if yes, branch
		cmpi.w	#$A0,d0		; is sound $95-$A0 being played?
		bcs.s	LevelSelect	; if yes, branch

LevSel_PlaySnd:
		bsr.w	PlaySound_Special
		bra.s	LevelSelect
		
LevSelStartPress:				; XREF: LevelSelect
		move.b	#$00,$FFFFF600
		jmp MainGameLoop ;go to sega screen

Level Select Music Fix

That fixes the level select so that it runs levels in a Sonic 2 manner, but it doesn't fix the music. Let's do that now.

Find:

Title_ClrVram:
		move.l	d0,(a6)
		dbf	d1,Title_ClrVram ; fill	VRAM with 0

		bsr.w	LevSelTextLoad

and add under dbf d1,Title_ClrVram ; fill VRAM with 0, these lines:

		move.b  #$81,d0
		jsr PlaySound

replace #$81 with your choice of song.

the result should look like:

Title_ClrVram:
		move.l	d0,(a6)
		dbf	d1,Title_ClrVram ; fill	VRAM with 0
		move.b  #$81,d0
		jsr PlaySound
		bsr.w	LevSelTextLoad

Green Hill Zone music at the level select, how lovely. On the other hand, if you plan on using my Sonic 2 Sound Driver port, try using music number $91 and PlayMusic as opposed to PlaySound.

Button Fix, Part 2

As you already know, A is not yet fixed, time to fix that button:

First, we will have to edit the "LevSel_SndTest" routine. $C (left and right) will not work for detecting A. We will need $4C (A/Left/Right) instead, so look in our function for:

LevSel_SndTest:				; XREF: LevSelControls
		cmpi.w	#$14,($FFFFFF82).w ; is	item $14 selected?
		bne.s	LevSel_NoMove	; if not, branch
		move.b	($FFFFF605).w,d1
		andi.b	#$C,d1		; is left/right	pressed?

and change it to read out:

LevSel_SndTest:				; XREF: LevSelControls
		cmpi.w	#$14,($FFFFFF82).w ; is	item $14 selected?
		bne.s	LevSel_NoMove	; if not, branch
		move.b	($FFFFF605).w,d1
		andi.b	#$4C,d1		; is left/right/A pressed?

instead.

Now we can start working on adding the routine to handle A and increase the 16's ($10) part of the sound test:

locate:

		beq.s	LevSel_NoMove	; if not, branch
		move.w	($FFFFFF84).w,d0

and add below:

		btst	#6,d1		; is A pressed?
		bne.s	LevSel_A	; if not, branch

Now locate:

		bcc.s	LevSel_Right
		moveq	#$4F,d0		; if sound test	moves below 0, set to $4F

and add this routine under it to add A support to the level select:

LevSel_A:
		btst	#6,d1		; is A button pressed?
		beq.s	LevSel_Right	; if not, branch
		add.w	#16,d0		; add $10 to sound test
		cmpi.w	#$50,d0	        ; addition by Shadow05 to stop the sound test from going above $D0
		bcs.s	LevSel_Refresh2
		moveq	#0,d0		; if sound test	moves above $4F, set to	0

Button Fix, Part 3 {optional}

Incase you want to make it so when you press B or C you go back 10 just repeat the steps for B.

Play Sounds $94-$9F

(Original guide by SoullessSentinel)

In Sonic 1 you might notice you can't play sounds $94-$9F to fix this find this.

LevSel_NoCheat:
        cmpi.w    #$94,d0    ; is sound $80-$94 being played?
        bcs.s    LevSel_PlaySnd; if yes, branch
        cmpi.w    #$A0,d0    ; is sound $95-$A0 being played?
        bcs.s    LevelSelect; if yes, branch

Change the line:

        cmpi.w    #$94,d0    ; is sound $80-$94 being played?

So it reads:

        cmpi.w    #$A0,d0    ; is sound $80-$9F being played?

Then rebuild the ROM.

And now the sound test will have the music slots going up to $9F, instead of $94, however attempts to play empty music slots will crash the sound driver, and possibly lock up the emulator. So, make sure you include a song in every slot.

Notes

  • The disassembly's comments are incorrect. The correct ID ranges are $80-$93 and $94-$9F.
  • If you play sounds $94-$9F without inserting any music the game will crash!

Conclusion

Now the Sonic 1 level select will behave exactly like that of the one in Sonic 2 (Simon Wai prototype, except for night mode and split screen, those can be added manually if you get such a system working). Enjoy your alternative level select :)

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)

|Sonic 2 (Simon Wai Prototype) Level Select in Sonic 1]]