Actions

SCHG How-to

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

From Sonic Retro

m (Level Select Music Fix)
(Blanked the page)
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.
 
  
===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):
 
<asm>
 
; ---------------------------------------------------------------------------
 
; 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
 
; ===========================================================================
 
 
 
</asm>
 
Notice anything here?
 
 
===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.
 
<asm>
 
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
 
</asm>
 
 
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.
 
 
the results should look like this:
 
 
<asm>
 
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
 
 
</asm>
 
 
===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 that now.
 
 
find:
 
<asm>
 
Title_ClrVram:
 
move.l d0,(a6)
 
dbf d1,Title_ClrVram ; fill VRAM with 0
 
 
bsr.w LevSelTextLoad
 
</asm>
 
 
and add under ''dbf d1,Title_ClrVram ; fill VRAM with 0'', these lines:
 
<asm>
 
move.b  #$81,d0
 
jsr PlaySound
 
</asm>
 
replace #$81 with your choice of song.
 
 
the result should look like:
 
<asm>
 
Title_ClrVram:
 
move.l d0,(a6)
 
dbf d1,Title_ClrVram ; fill VRAM with 0
 
move.b  #$81,d0
 
jsr PlaySound
 
bsr.w LevSelTextLoad
 
</asm>
 
Green Hill Zone music at the level select, how lovely. on the other hand, if you plan on using my Sonic2 Driver port, try using music number $91 and PlayMusic as opposed to PlaySound.
 
 
===Button Fix, Part 2===
 
As you already know, the A button 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 an A button.  we will need $4C (A/Left/Right) instead, so look in our function for:
 
<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?
 
</asm>
 
 
and change it to read out:
 
<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?
 
 
</asm>
 
instead.
 
 
Now we can start working on adding the routine to handle the A button and increase the 16's ($10) part of the sound test:
 
 
locate:
 
<asm>
 
beq.s LevSel_NoMove ; if not, branch
 
move.w ($FFFFFF84).w,d0
 
</asm>
 
 
and add below:
 
<asm>
 
btst #6,d1 ; is A pressed?
 
bne.s LevSel_A ; if not, branch
 
</asm>
 
 
now locate:
 
<asm>
 
bcc.s LevSel_Right
 
moveq #$4F,d0 ; if sound test moves below 0, set to $4F
 
</asm>
 
 
and add this routine under it to add A button support to the level select:
 
<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
 
</asm>
 
 
now the sonic1 level select will behave exactly like that of the one in sonic2 (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 :)
 
[[Category:SCHG How-tos|Sonic2 (Simon Wai Prototype) Level Select for Sonic1]]
 

Revision as of 06:16, 4 July 2011