Actions

SCHG How-to

Difference between revisions of "Port Sonic 2's Level Select to Sonic 1"

From Sonic Retro

(Make changes to the Title Screen)
(Make changes to the Title Screen)
Line 103: Line 103:
 
</asm>
 
</asm>
 
looks like checks for the cheat being active, but no screen change code, lets fix that.
 
looks like checks for the cheat being active, but no screen change code, lets fix that.
 +
<asm>
 +
Title_ChkLevSel:
 +
tst.b ($FFFFFFE0).w ; check if level select code is on
 +
beq.w PlayLevel ; if not, play level
 +
btst #6,($FFFFF604).w ; check if A is pressed
 +
beq.w PlayLevel ; if not, play level
 +
move.b #$2C,($FFFFF600).w ; => LevelSelectMenu
 +
rts
 +
</asm>
 +
then we remove:
 +
<asm>
 +
 +
Title_ClrScroll:
 +
move.l d0,(a1)+
 +
dbf d1,Title_ClrScroll ; fill scroll data with 0
 +
 +
move.l d0,($FFFFF616).w
 +
move #$2700,sr
 +
lea ($C00000).l,a6
 +
move.l #$60000003,($C00004).l
 +
move.w #$3FF,d1
 +
 +
Title_ClrVram:
 +
move.l d0,(a6)
 +
dbf d1,Title_ClrVram ; fill VRAM with 0
 +
 +
bsr.w LevSelTextLoad
 +
 +
; ---------------------------------------------------------------------------
 +
; 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 #$26,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 #$E1,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>
  
 
==Insert the new screens for Level Select, Options, and 2 Player VS==
 
==Insert the new screens for Level Select, Options, and 2 Player VS==
  
 
[[Category:SCHG How-tos|{{PAGENAME}}]]
 
[[Category:SCHG How-tos|{{PAGENAME}}]]

Revision as of 09:29, 26 February 2011

You probably saw an old method of adding the sonic 2 level select to sonic 1 on SSRG by Esreal, well time we added it the exact same way Sonic 2 does it.

Edit the Main Game Mode Array

the main game mode array in sonic 1 does not have entries for the sonic 2 menu system, we will add them here.

main game loop

first we update the main game loop: <asm> MainGameLoop: move.b ($FFFFF600).w,d0 ; load Game Mode andi.w #$1C,d0 jsr GameModeArray(pc,d0.w) ; jump to apt location in ROM bra.s MainGameLoop </asm>

notice that $1C up there? that prevents us from adding new entries, Sonic 2 use $3C there, so we will update it to: <asm> MainGameLoop: move.b ($FFFFF600).w,d0 ; load Game Mode andi.w #$3C,d0 jsr GameModeArray(pc,d0.w) ; jump to apt location in ROM bra.s MainGameLoop </asm>

Main Game Mode Array

Yes, we can add the new game modes now, in Sonic 1 we have: <asm> bra.w SegaScreen ; Sega Screen ($00)

===========================================================================

bra.w TitleScreen ; Title Screen ($04)

===========================================================================

bra.w Level ; Demo Mode ($08)

===========================================================================

bra.w Level ; Normal Level ($0C)

===========================================================================

bra.w SpecialStage ; Special Stage ($10)

===========================================================================

bra.w ContinueScreen ; Continue Screen ($14)

===========================================================================

bra.w EndingSequence ; End of game sequence ($18)

===========================================================================

bra.w Credits ; Credits ($1C)

===========================================================================

rts

===========================================================================

</asm> the rts is meant to mark the end of the screen set. Lets look at the one in Sonic 2: <asm> GameModesArray: ;; bra.w SegaScreen ; $00 SEGA screen mode bra.w TitleScreen ; $04 Title screen mode bra.w Level ; $08 Demo mode bra.w Level ; $0C Zone play mode bra.w SpecialStage ; $10 Special stage play mode bra.w ContinueScreen ; $14 Continue mode bra.w TwoPlayerResults ; $18 2P results mode bra.w LevelSelectMenu2P ; $1C 2P level select mode bra.w JmpTo_EndingSequence ; $20 End sequence mode bra.w OptionsMenu ; $24 Options mode bra.w LevelSelectMenu ; $28 Level select mode

===========================================================================

</asm> the rts isnt there because the list cannot get as high as $3C and the normal locations for the screens, are at the credits and ending slots, that just wont do, so we will have them load from slots after the normal ones. Slots $20, $24, $28, and $2C are open, so we will make our changes: <asm> bra.w SegaScreen ; Sega Screen ($00)

===========================================================================

bra.w TitleScreen ; Title Screen ($04)

===========================================================================

bra.w Level ; Demo Mode ($08)

===========================================================================

bra.w Level ; Normal Level ($0C)

===========================================================================

bra.w SpecialStage ; Special Stage ($10)

===========================================================================

bra.w ContinueScreen ; Continue Screen ($14)

===========================================================================

bra.w EndingSequence ; End of game sequence ($18)

===========================================================================

bra.w Credits ; Credits ($1C)

===========================================================================

bra.w TwoPlayerResults ; 2 Player Results ($20)

===========================================================================

bra.w LevelSelectMenu2P ; 2 Player Level Select ($24)

===========================================================================

bra.w OptionsMenu ; Options Menu ($28)

===========================================================================

bra.w LevelSelectMenu ; Level Select ($2C)

===========================================================================

</asm>

Make changes to the Title Screen

this part probably isn't that big, remember what screen number we gave the level select? Now we get to set this in the title screen code so that it will load just like it does in sonic 2, sonic 3, s&k, sonic2k, and sonic3k, lets look at the offending code: <asm> Title_ChkLevSel: tst.b ($FFFFFFE0).w ; check if level select code is on beq.w PlayLevel ; if not, play level btst #6,($FFFFF604).w ; check if A is pressed beq.w PlayLevel ; if not, play level moveq #2,d0 bsr.w PalLoad2 ; load level select pallet lea ($FFFFCC00).w,a1 moveq #0,d0 move.w #$DF,d1

</asm> looks like checks for the cheat being active, but no screen change code, lets fix that. <asm> Title_ChkLevSel: tst.b ($FFFFFFE0).w ; check if level select code is on beq.w PlayLevel ; if not, play level btst #6,($FFFFF604).w ; check if A is pressed beq.w PlayLevel ; if not, play level move.b #$2C,($FFFFF600).w ; => LevelSelectMenu rts </asm> then we remove: <asm>

Title_ClrScroll: move.l d0,(a1)+ dbf d1,Title_ClrScroll ; fill scroll data with 0

move.l d0,($FFFFF616).w move #$2700,sr lea ($C00000).l,a6 move.l #$60000003,($C00004).l move.w #$3FF,d1

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

bsr.w LevSelTextLoad

---------------------------------------------------------------------------
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 #$26,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 #$E1,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>

Insert the new screens for Level Select, Options, and 2 Player VS