[Tutorial] How to add 'Ending Sequence' option to Level Select in Sonic 1 (Newer disassemblies)

Mildanner

Newcomer
If you are using a current version of the disassembly, you notice that there's a extra code that ressembles the Ending sequence and it is not in level select. It was used for the Japanese cheat code, also... You can still interact with it.

In your sonic.asm file, search for the label LevSel_Level_SS and replace the entire routine with this
Code:
LevSel_Level_SS:
        andi.l  #$FFFF,d0                ; clear top half of d0 to ensure it is clean
        add.l   d0,d0                    ; double selected line for word-based indexing
        lea     LevSel_Ptrs(pc),a0       ; load the pointer table address into a0
        move.w  (a0,d0.l),d0             ; read the level pointer using a0 and d0.l
        bmi.w   LevelSelect              ; if it's an invalid entry ($8000), branch back
 
        cmpi.w  #$4000,d0                ; check if Ending Sequence dummy value is selected
        beq.s   LevSel_Ending            ; if yes, branch to the ending sequence!
 
        cmpi.w  #id_SS<<8,d0             ; check if selected level Special Stage
        bne.s   LevSel_Level             ; if not, branch
 
        move.b  #id_Special,(v_gamemode).w ; set screen mode to $10 (Special Stage)
        clr.w   (v_zone_act).w           ; clear level
        move.b  #3,(v_lives).w           ; set lives to 3
        moveq   #0,d0                    ; set d0 to 0
        move.w  d0,(v_rings).w           ; clear rings
        move.l  d0,(v_time).w            ; clear time
        move.l  d0,(v_score).w           ; clear score
        if Revision<>0
        move.l  #5000,(v_scorelife).w    ; extra life is awarded at 50000 points
        endif
        rts
Done, there's another one. Go to the LevSel_SelectionMade and simply change the cmpi code part to $15 (The number can be still changed even if newer or older disassembly).

After changing your code, it will look like this (It was used to be $14 if sound test is selected)
Code:
LevSel_SelectionMade:
        move.w  (v_levselitem).w,d0      ; get currently selected line
        cmpi.w  #$15,d0                  ; have you selected item $15 (sound test)?
        bne.s   LevSel_Level_SS          ; if not, go to Level/SS/Ending subroutine
 
        move.w  (v_levselsound).w,d0     ; get currently selected sound test entry
        addi.w  #$80,d0                  ; make it $80-based
 
        ; 9E/9F shortcuts with hidden Japanese Credits cheat
        tst.b   (f_creditscheat).w       ; is hidden 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, go to Ending Sequence
        cmpi.w  #$9E,d0                  ; is sound $9E being played?
        beq.s   LevSel_Credits           ; if yes, go to Credits
If you are using a new version of the disassembly, levsel_line_count was added so you can simply change that to 22.

In older disassemblies, this wasn't existed.

The text seens functional, go to the LevSel_Ptrs: label and insert this below the Final zone pointer code.
Code:
        dc.w $4000        ; Ending sequence
For the text, search for LevelMenuText and insert this below the FINAL ZONE text. (For alternative text, you want to leave it only one word Ending instead of Ending Sequence.)
Code:
        dc.b "ENDING SEQUENCE         "
I hope you enjoy your good ending in the level select, a way to skip the game jokes aside.

Thank you for following and reading this guide and happy hacking! 😃
 
Last edited:
Back
Top