|
|
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]]
| |