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.