Extend the level index past $10 in Sonic 2
From Sonic Retro
Revision as of 12:58, 15 December 2010 by Silent.creature (talk | contribs)
Authoring Notes
(Original guide by kram, current revision that fixes major bugs and extends properly by GARY 'M 9)
(Updated again by kram, adding back custom titlecard mappings howto, due to guide being unfinished, thus finally fixing the "ZONE ZONE" bug. Replace all the empty levels with your new ones.)
(Some implementations by silent.creature. More fixes about level crashes)
Introduction
WARNING: Unless you are working with Xenowhirl's 2007 Sonic 2 disassembly, I [b]strongly[/b] recommend you port the Sonic 1 sound driver first before proceeding. There will be a lot of shifting data and data addition here, and this may even break any array built under Sonic 2 or Sonic 2 Beta sound driver. In Xenowhirl's disassembly, the Sound Driver is assembled within the ROM, so it can handle a massive data shift. This time, I will leave for the reader the option to add data as long as necessary, instead of labeling and inserting all data (maybe not everyone has all the data done, right?)
You probably noticed that all the indexes in the game stop at $10 and when you try to extend it, by extending the MLLB (Main Level Load Blocks), you get weird glitches or even crashes, that is because you haven't extended all the indexes that need to be extended.
Extending the Titlecard index
First we find:
<asm> Obj34_TitleCardData:
dc.b 8, 0, $80, $1B dc.w $240, $120, $B8
dc.b $A, $11, $40, $1C dc.w $28, $148, $D0
dc.b $C, $12, $18, $1C dc.w $68, $188, $D0
dc.b 2, 0, 0, 0 dc.w 0, 0, 0
dc.b 4, $15, $48, 8 dc.w $2A8, $168,$120
dc.b 6, $16, 8, $15 dc.w $80, $F0, $F0
</asm>
and change it to: <asm> Obj34_TitleCardData:
dc.b 8, 0, $80, $1B ; this is the zone string start index and placement dc.w $240, $120, $B8
dc.b $A, $21, $40, $1C ; "ZONE" string index number and placement dc.w $28, $148, $D0
dc.b $C, $22, $18, $1C ; act number start index and placement dc.w $68, $188, $D0
dc.b 2, 0, 0, 0 ; this part of the titlecard is totally unknown, colored backdrop possibly dc.w 0, 0, 0
dc.b 4, $25, $48, 8 ; red strip edge index and placement dc.w $2A8, $168,$120
dc.b 6, $26, 8, $15 ; red "Sonic The Hedgehog" string and placement dc.w $80, $F0, $F0
</asm>
next, find: <asm> loc_13DEE:
jsr sub_13D10(pc) move.b (Current_Zone).w,d0 cmpi.b #$10,d0 beq.s BranchTo9_DeleteObject cmpi.b #6,d0 beq.s BranchTo9_DeleteObject cmpi.b #$E,d0 beq.s BranchTo9_DeleteObject move.b (Current_Act).w,d1 addi.b #$12,d1 cmpi.b #5,d0 bne.s loc_13E18 moveq #$14,d1
loc_13E18:
(...)
</asm>
and change it to: <asm> loc_13DEE:
jsr sub_13D10(pc) move.b (Current_Zone).w,d0 cmpi.b #$10,d0 beq.s BranchTo9_DeleteObject cmpi.b #6,d0 beq.s BranchTo9_DeleteObject cmpi.b #$E,d0 beq.s BranchTo9_DeleteObject cmpi.b #5,d0 beq.s loc_13E17 move.b (Current_Act).w,d1 addi.b #$22,d1 ; Act number mappings (Act 1) bra.w loc_13E18
loc_13E17:
moveq #$24,d1 ; Act number mappings (Act 3). Used for drawing MTZ (0x05) titlecard only
loc_13E18:
(...)
</asm>
In order to easily fix title cards of added 3-acted zones, we inverted the data using the label loc_13E17.
Now we have the offset data of where to load the mappings for the titlecards shifted so that we can now start working on updating the mappings and not have that strange "ZONE ZONE" bug that GARY 'M 9 left behind and I intended to correct.
Next off, in this part of the hack the first thing before converting to a better manageable datatype, we want to replace the byte_15820 handler with a better one. The original pointer format posted here doesn't fit correctly. We need to adjust the pointers to fit data as it was before. The routine itself works, but its data references, not. Let's work on this.
look for: <asm>
- loc_157D2
LoadTitleCard:
bsr.s LoadTitleCard0 moveq #0,d0 move.b (Current_Zone).w,d0 move.b byte_15820(pc,d0.w),d0 lea word_15832(pc),a0 lea (a0,d0.w),a0 move.l #$7BC00002,d0
</asm>
and we want to replace it with: <asm>
- loc_157D2
LoadTitleCard:
bsr.s LoadTitleCard0 moveq #0,d0 move.b (Current_Zone).w,d0 add.w d0,d0 move.w Off_Titlecardtext(pc,d0.w),d0 lea Off_Titlecardtext(pc,d0.w),a0 move.l #$7BC00002,d0
</asm>
That takes care of the loader, now time to update the string data.
find: <asm>
- unknown
byte_15820:
dc.b 0, 0, 0, 0,$10,$10,$98,$20,$2C, 0,$3C,$46,$58,$68,$A8,$7A dc.b $8A, 0 ; 16
- unknown
word_15832:
dc.w $2A06,$3804, 4,$2604, $C04,$1804,$1C02,$FFFF dc.w $2A06,$4004,$3804,$3004,$2604,$1C02,$3C04,$FFFF; 8 dc.w $1804,$1C02,$2604,$4004,$3004,$FFFF,$1804,$1C02; 16 dc.w $C04,$3004, 4,$2604, $804,$FFFF,$1C02,$2604; 24 dc.w $804, 4,$FFFF,$2A06,$5604,$3C04,$4004,$1C02; 32 dc.w $804, 4,$4804,$FFFF, $804, 4,$3C04,$1C02; 40 dc.w $1404,$1804,$4004,$FFFF, $804,$1804,$2A06,$1C02; 48 dc.w 4,$2604,$3004,$4004,$FFFF, 4,$3404,$4404; 56 dc.w $4004,$1C02, $804,$3804,$FFFF,$3C04,$2204,$5604; 64 dc.w $804,$1804, 4,$FFFF,$4C06,$1C02,$1404,$1004; 72 dc.w $3804,$4004,$3C04,$FFFF, $C04, 4,$4004,$1804; 80 dc.w $1404,$FFFF ; 88
</asm>
and replace it with: <asm>
- byte_15820
Off_Titlecardtext:
dc.w Text_EHZ-Off_Titlecardtext ; EHZ Titlecard 00 dc.w Text_LZ-Off_Titlecardtext ; LZ Titlecard 01 dc.w Text_WZ-Off_Titlecardtext ; WZ Titlecard 02 dc.w Text_DHZ-Off_Titlecardtext ; DHZ Titlecard 03 dc.w Text_MTZ-Off_Titlecardtext ; MTZ Titlecard 04 dc.w Text_MTZ-Off_Titlecardtext ; MTZ Titlecard 05 dc.w Text_WFZ-Off_Titlecardtext ; WFZ Titlecard 06 dc.w Text_HTZ-Off_Titlecardtext ; HTZ Titlecard 07 dc.w Text_HPZ-Off_Titlecardtext ; HPZ Titlecard 08 dc.w Text_GCZ-Off_Titlecardtext ; GCZ Titlecard 09 dc.w Text_OOZ-Off_Titlecardtext ; OOZ Titlecard 0A dc.w Text_MCZ-Off_Titlecardtext ; MCZ Titlecard 0B dc.w Text_CNZ-Off_Titlecardtext ; CNZ Titlecard 0C dc.w Text_CPZ-Off_Titlecardtext ; CPZ Titlecard 0D dc.w Text_DEZ-Off_Titlecardtext ; DEZ Titlecard 0E dc.w Text_ARZ-Off_Titlecardtext ; ARZ Titlecard 0F dc.w Text_SCZ-Off_Titlecardtext ; SCZ Titlecard 10 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 11 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 12 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 13 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 14 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 15 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 16 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 17 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 18 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 19 dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 1A dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 1B dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 1C dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 1D dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 1E dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 1F dc.w Text_NZ-Off_Titlecardtext ; NZ Titlecard 20
- word_15832
Text_EHZ:
dc.w $2A06,$3804, 4,$2604, $C04,$1804,$1C02 ;'MRALDHI' dc.w $FFFF
Text_MTZ:
dc.w $2A06,$4004,$3804,$3004,$2604,$1C02,$3C04 ;'MTRPLIS' dc.w $FFFF
Text_HTZ:
dc.w $1804,$1C02,$2604,$4004,$3004 ;'HILTP' dc.w $FFFF
Text_HPZ:
dc.w $1804,$1C02, $C04,$3004, 4,$2604, $804 ;'HIDPALC' dc.w $FFFF
Text_OOZ:
dc.w $1C02,$2604, $804, 4 ;'ILCA' dc.w $FFFF
Text_MCZ:
dc.w $2A06,$5604,$3C04,$4004,$1C02, $804, 4,$4804 ;'MYSTICAV' dc.w $FFFF
Text_CNZ:
dc.w $804, 4,$3C04,$1C02,$1404,$1804,$4004 ;'CASIGHT' dc.w $FFFF
Text_CPZ:
dc.w $804,$1804,$2A06,$1C02, 4,$2604,$3004,$4004 ;'CHMIALPT' dc.w $FFFF
Text_ARZ:
dc.w 4,$3404,$4404,$4004,$1C02, $804,$3804 ;'AQUTICR' dc.w $FFFF
Text_SCZ:
dc.w $3C04,$2204,$5604, $804,$1804, 4 ;'SKYCHA' dc.w $FFFF
Text_WFZ:
dc.w $4C06,$1C02,$1404,$1004,$3804,$4004,$3C04 ;'WIGFRTS' dc.w $FFFF
Text_DEZ:
dc.w $C04, 4,$4004,$1804,$1404 ;'DATHG' dc.w $FFFF
Text_NZ: dc.b $4C06 ; 'W'
dc.w $FFFF ; '<EOF>'
</asm>
This extends the title card index to $20, adds titlecards for Wood Zone, Labyrinth Zone, Dust Hill Zone, Genocide City Zone, and an empty New Zone titlecard for every single level above SCZ, compacts the titlecard text data for all titlecards, and makes it more easier to manage. you will be wondering probably what to do with the mappings. Well that is what is next.