Difference between revisions of "Sonic 2 (Simon Wai Prototype) Level Select in Sonic 1"
From Sonic Retro
m (Text replacement - "\[\[Category:SCHG How-tos.*" to "") |
|||
(23 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
− | + | {{GuideBy|Kram1024}} | |
− | ==Overview== | + | 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. |
− | First, | + | |
− | <asm> | + | ===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): |
+ | <syntaxhighlight lang="asm">; --------------------------------------------------------------------------- | ||
; Level Select | ; Level Select | ||
; --------------------------------------------------------------------------- | ; --------------------------------------------------------------------------- | ||
Line 109: | Line 110: | ||
− | </ | + | </syntaxhighlight> |
Notice anything here? | Notice anything here? | ||
− | A lot of stuff we really do not need, as well as the | + | ===Button Fix, Part 1=== |
− | <asm> | + | 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. |
+ | <syntaxhighlight lang="asm"> | ||
LevelSelect: | LevelSelect: | ||
move.b #4,($FFFFF62A).w | move.b #4,($FFFFF62A).w | ||
Line 144: | Line 146: | ||
bsr.w PlaySound_Special | bsr.w PlaySound_Special | ||
bra.s LevelSelect | bra.s LevelSelect | ||
− | </ | + | </syntaxhighlight> |
− | + | 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: | |
− | <asm> | + | <syntaxhighlight lang="asm"> |
LevelSelect: | LevelSelect: | ||
move.b #4,($FFFFF62A).w | move.b #4,($FFFFF62A).w | ||
Line 190: | Line 192: | ||
jmp MainGameLoop ;go to sega screen | jmp MainGameLoop ;go to sega screen | ||
− | </ | + | </syntaxhighlight> |
− | That fixes the level select so that it runs levels in a | + | ===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: | |
− | <asm> | + | <syntaxhighlight lang="asm"> |
Title_ClrVram: | Title_ClrVram: | ||
move.l d0,(a6) | move.l d0,(a6) | ||
Line 201: | Line 204: | ||
bsr.w LevSelTextLoad | bsr.w LevSelTextLoad | ||
− | </ | + | </syntaxhighlight> |
− | and add under ''dbf d1,Title_ClrVram ; fill VRAM with 0'', | + | and add under ''dbf d1,Title_ClrVram ; fill VRAM with 0'', these lines: |
− | <asm> | + | <syntaxhighlight lang="asm"> |
− | + | move.b #$81,d0 | |
− | + | jsr PlaySound | |
− | </ | + | </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 | |
− | + | 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! | ||
− | + | ===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.
Contents
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 but not exclusively just , so an andi would be used there. Also, we want to exit back to the Sega screen, and why not some nice music? Only or 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, 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 . 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 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 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 :)
|Sonic 2 (Simon Wai Prototype) Level Select in Sonic 1]]