SCHG How-to:Add the options menu into Sonic 3 & Knuckles
From Sonic Retro
Revision as of 04:24, 6 July 2022 by Makotoyuki (talk | contribs)
since Mustapha's guide uses a pre-assembled rom AND uses Sonic 3 alone since Sonic 3 & Knuckles does not contain these leftovers (making me wonder why it's in S3K's section in the first place), AND because Nik Pi wants me to do this tutorial, i'm gonna tell you now how to add the S2 options menu into S3K. this guide is for the Github disasm of Sonic & Knuckles, and will (probably) work on 'S3 Complete' (a version of S3K that has the redundancies stripped out)
you'll need:
- s3.asm
- sonic3k.asm
open s3.asm and go to:
MenuScreen_Options:
lea (RAM_start).l,a1
lea (MapEni_S2Options).l,a0
move.w #$70,d0
bsr.w Eni_Decomp
lea (RAM_start+$160).l,a1
lea (MapEni_S2Options).l,a0
move.w #$2070,d0
bsr.w Eni_Decomp
clr.b (Options_menu_box).w
bsr.w OptionScreen_DrawSelected
addq.b #1,(Options_menu_box).w
bsr.w OptionScreen_DrawUnselected
addq.b #1,(Options_menu_box).w
bsr.w OptionScreen_DrawUnselected
clr.b (Options_menu_box).w
clr.b (Level_started_flag).w
clr.w (Anim_Counters).w
lea (AniPLC_SONICMILES).l,a2
jsr (AnimateTiles_DoAniPLC).l
moveq #4,d0
bsr.w LoadPalette
moveq #signextendB(mus_DataSelect),d0
bsr.w Play_Sound
; more code
copy all of the subroutines until you reach
off_6878: dc.l TextOptScr_0
you will also need to copy
CheckCheats:
move.w (Level_select_cheat_counter).w,d0
adda.w d0,a0
move.w (Sound_test_sound).w,d0
cmp.b (a0),d0
bne.s loc_6E88
addq.w #1,(Level_select_cheat_counter).w
tst.b 1(a0)
bne.s loc_6E8E
move.w #$101,(a1)
moveq #signextendB(sfx_RingRight),d0
jsr (Play_Sound_2).l
loc_6E88:
move.w #0,(Level_select_cheat_counter).w
loc_6E8E:
move.w (Debug_mode_cheat_counter).w,d0
adda.w d0,a2
move.w (Sound_test_sound).w,d0
cmp.b (a2),d0
bne.s loc_6EC8
addq.w #1,(Debug_mode_cheat_counter).w
tst.b 1(a2)
bne.s locret_6ECE
tst.w d2
bne.s loc_6EBA
move.b #$F,(Continue_count).w
moveq #signextendB(mus_Continue),d0
jsr (Play_Sound).l
bra.s loc_6EC8
; ---------------------------------------------------------------------------
loc_6EBA:
move.w #7,(Emerald_count).w
moveq #signextendB(mus_Emerald),d0
jsr (Play_Sound).l
loc_6EC8:
move.w #0,(Debug_mode_cheat_counter).w
locret_6ECE:
rts
TextOptScr_PlayerSelect:
levselstr "* PLAYER SELECT *"
TextOptScr_SonicAndMiles:
levselstr "SONIC AND MILES"
TextOptScr_SonicAndTails:
levselstr "SONIC AND TAILS"
TextOptScr_SonicAlone:
levselstr "SONIC ALONE "
TextOptScr_MilesAlone:
levselstr "MILES ALONE "
TextOptScr_TailsAlone:
levselstr "TAILS ALONE "
TextOptScr_VsModeItems:
levselstr "* VS MODE ITEMS *"
TextOptScr_AllKindsItems:
levselstr "ALL KINDS ITEMS"
TextOptScr_TeleportOnly:
levselstr "TELEPORT ONLY "
TextOptScr_SoundTest:
levselstr "* SOUND TEST *"
TextOptScr_0:
levselstr " 00 "
and
MenuScreenTextToRAM:
moveq #0,d1
move.b (a1)+,d1
loc_6542:
move.b (a1)+,d0
move.w d0,(a2)+
dbf d1,loc_6542
rts
and you MIGHT need to copy
S2LevelSelectCodeDat:
dc.b $19, $65, 9, $17, 0
S2ContinueCodeDat:
dc.b 1, 1, 2, 4, 0
DebugCodeDat:
dc.b 1, 3, 5, 7, 0
AllEmeraldsCodeDat:
dc.b 2, 4, 5, 6, 0
copy all these to sonic3k.asm you can paste them wherever you like, i personally like to keep them where they were in s3.asm (right before SpecialStage) build now and you'll get tons of errors when trying to build sonic & knuckles most of them are to do with short addressing, so let's get that out of the way you'll need to alter any (Options_menu_box).w's to (Options_menu_box).l, there are ~18 occurences then there's 1 other short addressing occurence this time with 'Current_zone_2p', do the same as to Options_menu_box but it's not over yet! build sk again and you'll find 3 other errors: 2 out of range errors (depending on where you place the subroutines you might not get these) and 1 symbol double defined error. all have to do with 'loc_6696', so to avoid complications, change the label in your subroutines to any valid label (i go with loc_6696b)
you might think 'that's it, right? surely it should bui-' nope, the cake isn't yet eaten. build after you've resolved these errors and you'll get a SWOTH of errors in their place. most of them have to do with 'symbol undefined' but there is 1 (and there will be another one later) involving Update_SSMap being out of range now. let's go fix that.
VInt_1C:
bsr.w Rotate_SSPal
bsr.w Do_ControllerPal
bsr.w Update_SSMap
tst.w (Demo_timer).w
beq.w +
subq.w #1,(Demo_timer).w
+
jmp (Set_Kos_Bookmark).l
note: there might be 2 errors in this subroutine however there's only 1 shown. let's fix both though
for a start, create 2 new subroutines: (you can name them anything as long as it's a new name that another label doesn't use)
JmpTo_Rotate_SSPal: jmp Rotate_SSPal
JmpTo_Update_SSMap: jmp Update_SSMap
then, change VInt_1C to use them both:
VInt_1C:
bsr.w JmpTo_Rotate_SSPal
bsr.w Do_ControllerPal
bsr.w JmpTo_Update_SSMap
then let's resolve the symbol unknown errors. first let's fix MapEni_S2Options
MapEni_S2Options:
binclude "General/Sprites/S2Menu/Enigma Map/Options Screen.bin"
even
place it anywhere
remember Options_menu_box and Current_zone_2p? yeah well those don't exist in S3K's RAM they do exist in S3's RAM however and are readily usable, all we need to do is copy them open s3.constants.asm and sonic3k.constants.asm and from s3.constants.asm copy:
phase _tempFF88
Current_zone_2P ds.b 1 ; left over from Sonic 2
Current_act_2P ds.b 1 ; left over from Sonic 2
Options_menu_box = _tempFF8C ; byte ; left over from Sonic 2
_unkFF98 = _tempFF98 ; word ; unused
dephase
copy these into sonic3k.constants.asm anywhere now, if you get new errors after this, resolve them. after that, you WILL encounter this:
> > > sonic3k.asm(1978):9: error: symbol undefined
> > > done1360
> > > bmi.s $$done
> > > ~~~~~~
> > > sonic3k.asm(2007):9: error: symbol undefined
> > > done1361
> > > bmi.s $$done
> > > ~~~~~~
> > > sonic3k.asm(2376):9: error: symbol undefined
> > > enoughBits1397
> > > bcc.s $$enoughBits ; branch if a new word doesn't need to be read
> > > ~~~~~~~~~~~~
> > > sonic3k.asm(2399):9: error: symbol undefined
> > > justEnough1397
> > > beq.s $$justEnough ; if the word has been exactly exhausted, branch
> > > ~~~~~~~~~~~~
> > > sonic3k.asm(2571):9: error: symbol undefined
> > > freeSlotFound1412
> > > beq.s $$freeSlotFound
> > > ~~~~~~~~~~~~~~~
> > > sonic3k.asm(2621):9: error: symbol undefined
> > > modulesLeft1416
> > > bne.s $$modulesLeft
> > > ~~~~~~~~~~~~~
> > > sonic3k.asm(2628):9: error: symbol undefined
> > > decompressionStarted1416
> > > bmi.s $$decompressionStarted
> > > ~~~~~~~~~~~~~~~~~~~~~~
there are more errors, and just when you think it's the end they just keep coming. you have to replace all of the symbols with unique names, there's just no other way that i know of
now it should let you build, but wait!! you forgot 1 thing!! how do you access the menu?? for now we're just gonna make it replace the level select menu. the middle options box will lead you the level select menu anyway. go to loc_4270 and replace #$28 with #$24 then go to Gamemodes replace gamemode $24's pointer with MenuScreen_Options. gamemode $24 should be marked with a comment 'NOW that should be-' shush obviously it's not the end i mean it works but THIS is likely what you're gonna see, except without a BG and font (image from the S3K polish project i've been working on): in fact, how i got the BG and font loaded is by copying the beginning of MenuScreen_S2Options and adding it to the beginning of MenuScreen_Options
SCHG How-To Guide: Sonic the Hedgehog 3 and Knuckles |
---|
Fixing Bugs |
Fix Blue Knuckles | Fix Tails' Respawn Speeds | Fix Super Sonic Bugs |
Design Choices |
Fix Scattered Rings' Underwater Physics | Edit Level Select Text & Pointers | Work with Water | Make the Slots Bonus Game Rotate Smoothly |
Adding Features |
Restore (Sonic 2) Options Menu |
|Add the options menu into Sonic 3 & Knuckles]]