Improving Sonic 2's level select

Discussion in 'Tutorials' started by ADudeCalledLeo, Jun 15, 2019.

  1. ADudeCalledLeo

    ADudeCalledLeo Newcomer Member

    Joined:
    Oct 21, 2017
    Messages:
    11
    Location:
    Null Space
    Here's a ROM with all the following changes applied: https://www.dropbox.com/s/zsnnytoxrnwbhzz/Sonic 2 Improved Level Select.bin?dl=0

    Adding a way to change character
    Go to "LevelSelect_DrawSoundNumber", and duplicate the entire routine, renaming the label to "LevelSelect_DrawPlayerOption". In your newly duplicated routine, change:
    Code:
        move.l    #vdpComm(VRAM_Plane_A_Name_Table+planeLocH40(34,18),VRAM,WRITE),(VDP_control_port).l
        move.w   (Sound_test_sound).w,d0
    to:
    Code:
        move.l    #vdpComm(VRAM_Plane_A_Name_Table+planeLocH40(4,24),VRAM,WRITE),(VDP_control_port).l
        move.w   (Player_option).w,d0
    Then, go to "LevelSelect_MarkFields", and scroll down until you see this bit of code:
    Code:
        cmpi.w    #$15,(Level_select_zone).w
        bne.s    +    ; rts
        bsr.w    LevelSelect_DrawSoundNumber
    +
        rts
    Change it to:
    Code:
        cmpi.w    #$15,(Level_select_zone).w
        beq.w   LevelSelect_DrawSoundNumber
        bra.w   LevelSelect_DrawPlayerOption
    
    The currently selected character will now be drawn on the level select. It'll be drawn highlighted, unless the Sound Test option is selected.
    Now to add a way to actually change it. Go to "LevSelControls_SwitchSide", and just before the "rts", add this code:
    Code:
    ;LevSelControls_SwitchPlayerOption:
        btst    #button_C,(Ctrl_1_Press).w    ; is C pressed?
        beq.s    +                ; if not, branch
        addq.w    #1,(Player_option).w        ; select next character
        cmpi.w    #2,(Player_option).w        ; did we go over the limit?
        bls.s    +                ; if not, branch
        clr.w    (Player_option).w        ; reset to 0
    +
    This will make it so that if you press C on anything that's not the Sound Test, the next character will be selected, wrapping around to 0 if you go over the maximum.
    The number in the cmpi.w line should be the number of characters in your hack. If you added Knuckles, for example, you'd change that number to be 3 instead of 2.

    Improving the sound test
    Go to the 3rd + label after "LevSelControls_CheckLR". You should see the following line there:
    Code:
        andi.w    #button_B_mask|button_C_mask,d1
    Replace it with:
    Code:
        andi.w    #button_C_mask,d1
    Now, only pressing C will cause the sound to be played.
    Then, go back to the 3rd + label and directly after it, add the following code:
    Code:
        btst    #button_B,d1
        beq.s    +
        subi.b    #$10,d0
        andi.b    #$7F,d0
    
    +
    This will make it so that pressing B will lower the 2nd digit by 1.

    The sound test in the options screen can also be improved in the same way.
    Go to the 5th + label after "OptionScreen_Controls" You should see the following line there:
    Code:
        andi.w    #button_B_mask|button_C_mask,d1
    Replace it with:
    Code:
        andi.w    #button_C_mask,d1
    Then, go to the + label just before the one you're at and replace everything up to the 5th + label with:
    Code:
        cmpi.b    #2,(Options_menu_box).w
        bne.s    ++
    
        btst    #button_A,d0
        beq.s    +
        addi.b    #$10,d2
        andi.b    #$7F,d2
    
    +
        btst    #button_B,d0
        beq.s    +
        subi.b    #$10,d2
        andi.b    #$7F,d2
    
    +
    A tiny side effect of this fix is that the "maximum" bit in the "OptionsScreen_Choices" entry for the sound test will go unused.

    NOTE: If you've made the sound IDs start at 0 instead of $80, remove the "andi.b #$7F" lines. These lines limit the sound test number to a maximum of $7F.

    Return to the level select after pressing Start+A
    Go to "Pause_Loop", and change the line:
    Code:
        move.b    #GameModeID_TitleScreen,(Game_Mode).w ; set game mode to 4 (title screen)
    To:
    Code:
        move.b    #GameModeID_LevelSelect,(Game_Mode).w ; set game mode to $28 (level select)
    This will make the game return to the level select rather than the title screen when pressing Start+A.
    However, staring a new level after returning from a level causes some issues, since the level select doesn't completely reset level data (since it relies on the title screen resetting them, as there was no way to get to the level select without going through the title screen).
    To fix these issues, go to "MenuScreen_LevelSelect", and before "bsr.w Pal_FadeFromBlack" add:
    Code:
        clr.b    (Water_fullscreen_flag).w
    This prevents a palette issue when returning to the level select while the entire screen is underwater. Then, go to "LevelSelect_StartZone", and after "move.w d0,(Current_ZoneAndAct).w", add:
    Code:
        moveq    #PLCID_Std1,d0
        bsr.w    RunPLC_ROM
    This reloads Sonic's lives counter, as well as a few other graphics. Then, after "move.b d0,(Continue_count).w", add:
    Code:
        move.b    d0,(Last_star_pole_hit).w
        move.b    d0,(Last_star_pole_hit_2P).w
    This makes the game think that no checkpoints have been reached, meaning that you'll always start at the beginning of the level properly.
     
    Last edited: Jun 16, 2019
  2. TheFieldWarrior

    TheFieldWarrior Well-Known Member Member

    Joined:
    Oct 9, 2015
    Messages:
    91
    Location:
    United Kingdom
    There are three bugs which are the result of making Start+A return to the level select. I checked your example build to see if I messed up somewhere in the tutorial and it appears these bugs occur in your build as well. The common theme with these bugs is that the game doesn't reset data when switching to another character from the level select

    1. If you select Tails on the level select, enter a level, return to the level select, switch to Sonic and enter a level his life icon still shows Tails'

    2. If you enter act 2 of a zone, go far enough, return to the level select and pick a different zone (or act 1 of the same zone) the start positioning is screwed up causing you to start far into the stage, this also messes with levels with water (CPZ2 and ARZ) as the water covers the entire zone. It also causes Tails' sprites to show up as a glitched up Sonic

    3. If you hit a checkpoint, return to the level select and then enter the same level again you'll start at the checkpoint you hit earlier, if you decide to enter a different level then the starting position gets screwed up again this time putting you in the coordinates of the checkpoint
     
    ProjectFM and MarkeyJester like this.
  3. ADudeCalledLeo

    ADudeCalledLeo Newcomer Member

    Joined:
    Oct 21, 2017
    Messages:
    11
    Location:
    Null Space
    Guide has been updated with (untested!) fixes to these issues. ROM has not been rebuilt yet.
     
    Last edited: Jun 16, 2019
    TheFieldWarrior likes this.