Difference between revisions of "Change the Special Stage characters to use normal DPLCs"
From Sonic Retro
Scarred Sun (talk | contribs) m (Text replacement - "</asm>" to "</syntaxhighlight>") |
Scarred Sun (talk | contribs) m (Text replacement - "<asm>" to "<syntaxhighlight lang="asm">") |
||
Line 5: | Line 5: | ||
==The format explained== | ==The format explained== | ||
To explore the difference between the normal DPLCs and the custom ones used in Sonic 2 Special Stages, I will first explain how normal DPLCs work. For that, the best way is by using a simple example: | To explore the difference between the normal DPLCs and the custom ones used in Sonic 2 Special Stages, I will first explain how normal DPLCs work. For that, the best way is by using a simple example: | ||
− | <asm>Sample_DPLC: | + | <syntaxhighlight lang="asm">Sample_DPLC: |
dc.w DPLC_Entry_0-Sample_DPLC | dc.w DPLC_Entry_0-Sample_DPLC | ||
dc.w DPLC_Entry_1-Sample_DPLC | dc.w DPLC_Entry_1-Sample_DPLC | ||
Line 21: | Line 21: | ||
dc.w (0 << 12) | $005</syntaxhighlight> | dc.w (0 << 12) | $005</syntaxhighlight> | ||
This example shows how the DPLC file starts with an offset table; there is one entry in this table for each mapping frame. Each mapping frame's DPLC has a field indicating how many DPLC entries exist for this frame. The DPLC entries are then in the following format: | This example shows how the DPLC file starts with an offset table; there is one entry in this table for each mapping frame. Each mapping frame's DPLC has a field indicating how many DPLC entries exist for this frame. The DPLC entries are then in the following format: | ||
− | <asm>$STTT</syntaxhighlight> | + | <syntaxhighlight lang="asm">$STTT</syntaxhighlight> |
where S is (number of tiles-1) and TTT is the offset (in tiles) from the start of the art file [http://sonicology.fateback.com/hacks/mappings/sonic2_sonic.htm]. | where S is (number of tiles-1) and TTT is the offset (in tiles) from the start of the art file [http://sonicology.fateback.com/hacks/mappings/sonic2_sonic.htm]. | ||
Line 27: | Line 27: | ||
The second difference is in the format of each DPLC entry: | The second difference is in the format of each DPLC entry: | ||
− | <asm>$STTT</syntaxhighlight> | + | <syntaxhighlight lang="asm">$STTT</syntaxhighlight> |
Here, the S has the same meaning; but TTT is the number of '''words''' from the start of a ''hard-coded offset'' from the start of the art file. Specifically: | Here, the S has the same meaning; but TTT is the number of '''words''' from the start of a ''hard-coded offset'' from the start of the art file. Specifically: | ||
{| align="center" border="1" | {| align="center" border="1" | ||
Line 75: | Line 75: | ||
Next, open up your disassembly and find label 'dword_33AA2'. Delete it and the next 4 lines. Now find label 'loc_33AD8' (2007 disassembly) or 'LoadSSPlayerDynPLC' (Hg disassembly). Just above it, there is a line referring to 'dword_33AA2'. Replace this line with this: | Next, open up your disassembly and find label 'dword_33AA2'. Delete it and the next 4 lines. Now find label 'loc_33AD8' (2007 disassembly) or 'LoadSSPlayerDynPLC' (Hg disassembly). Just above it, there is a line referring to 'dword_33AA2'. Replace this line with this: | ||
− | <asm> move.l #$FF0000,d6 | + | <syntaxhighlight lang="asm"> move.l #$FF0000,d6 |
lea (Obj09_MapRUnc).l,a2</syntaxhighlight> | lea (Obj09_MapRUnc).l,a2</syntaxhighlight> | ||
Now select everything from 'loc_33AD8'/'LoadSSPlayerDynPLC' up until the '''rts''' and replace it by this: | Now select everything from 'loc_33AD8'/'LoadSSPlayerDynPLC' up until the '''rts''' and replace it by this: | ||
− | <asm> moveq #0,d0 | + | <syntaxhighlight lang="asm"> moveq #0,d0 |
move.b mapping_frame(a0),d0 | move.b mapping_frame(a0),d0 | ||
cmp.b (a4),d0 | cmp.b (a4),d0 | ||
Line 106: | Line 106: | ||
rts</syntaxhighlight> | rts</syntaxhighlight> | ||
This takes care of Sonic; time now for Tails. Find label 'dword_349B8' and, once again, delete it and the four lines below it. Then find the next line that references 'dword_349B8' and replace it by this: | This takes care of Sonic; time now for Tails. Find label 'dword_349B8' and, once again, delete it and the four lines below it. Then find the next line that references 'dword_349B8' and replace it by this: | ||
− | <asm> move.l #$FF0000,d6 | + | <syntaxhighlight lang="asm"> move.l #$FF0000,d6 |
lea (Obj10_MapRUnc).l,a2</syntaxhighlight> | lea (Obj10_MapRUnc).l,a2</syntaxhighlight> | ||
Just below this, you will find this line: | Just below this, you will find this line: | ||
− | <asm> moveq #$12,d1</syntaxhighlight> | + | <syntaxhighlight lang="asm"> moveq #$12,d1</syntaxhighlight> |
Replace it by this: | Replace it by this: | ||
− | <asm> moveq #0,d1</syntaxhighlight> | + | <syntaxhighlight lang="asm"> moveq #0,d1</syntaxhighlight> |
In the Special Stage, Tails uses the same DPLC routine as Sonic, so this is enough for Tails too. Time now for Tails' tails. Find label 'dword_34AA0'; delete it and the next 3 lines. | In the Special Stage, Tails uses the same DPLC routine as Sonic, so this is enough for Tails too. Time now for Tails' tails. Find label 'dword_34AA0'; delete it and the next 3 lines. | ||
Now find this line right after: | Now find this line right after: | ||
− | <asm> bsr.w JmpTo43_DisplaySprite</syntaxhighlight> | + | <syntaxhighlight lang="asm"> bsr.w JmpTo43_DisplaySprite</syntaxhighlight> |
Select it and everything below it until the following '''rts''' and delete it. If you are using the Hg disassembly, paste this at that location: | Select it and everything below it until the following '''rts''' and delete it. If you are using the Hg disassembly, paste this at that location: | ||
− | <asm> bsr.w JmpTo43_DisplaySprite | + | <syntaxhighlight lang="asm"> bsr.w JmpTo43_DisplaySprite |
move.l #$FF0000,d6 | move.l #$FF0000,d6 | ||
lea (Obj88_MapRUnc).l,a2 | lea (Obj88_MapRUnc).l,a2 | ||
Line 125: | Line 125: | ||
bra.w LoadSSPlayerDynPLC</syntaxhighlight> | bra.w LoadSSPlayerDynPLC</syntaxhighlight> | ||
If you are using the aging 2007 disassembly, paste this instead: | If you are using the aging 2007 disassembly, paste this instead: | ||
− | <asm> bsr.w JmpTo43_DisplaySprite | + | <syntaxhighlight lang="asm"> bsr.w JmpTo43_DisplaySprite |
move.l #$FF0000,d6 | move.l #$FF0000,d6 | ||
lea (Obj88_MapRUnc).l,a2 | lea (Obj88_MapRUnc).l,a2 |
Revision as of 21:45, 20 December 2015
(Original guide by Flamewing)
The Sonic 2 Special Stages use a custom format for storing characters' Dynamic Pattern Loading Cues (or DPLCs for short). This is inconvenient if you want to edit their art (for example, for making a character hack), especially if you use programs such as SonMapEd, which cannot read this custom format. This guide explains how to use normal DPLCs for the Special Stages. This guide also explores the custom format used for those that want to know how they work.
The format explained
To explore the difference between the normal DPLCs and the custom ones used in Sonic 2 Special Stages, I will first explain how normal DPLCs work. For that, the best way is by using a simple example:
Sample_DPLC:
dc.w DPLC_Entry_0-Sample_DPLC
dc.w DPLC_Entry_1-Sample_DPLC
DPLC_Entry_0:
dc.w 4 ; Number of entries in DPLC
dc.w (3 << 12) | $100
dc.w (2 << 12) | $200
dc.w (0 << 12) | $000
dc.w (1 << 12) | $080
DPLC_Entry_1:
dc.w 3 ; Number of entries in DPLC
dc.w (3 << 12) | $060
dc.w (2 << 12) | $020
dc.w (0 << 12) | $005
This example shows how the DPLC file starts with an offset table; there is one entry in this table for each mapping frame. Each mapping frame's DPLC has a field indicating how many DPLC entries exist for this frame. The DPLC entries are then in the following format:
$STTT
where S is (number of tiles-1) and TTT is the offset (in tiles) from the start of the art file [1].
The custom DPLC scheme used by the Sonic 2 Special Stage characters is very similar to this: you have an offset table at the start of the file. The differences start right away, though: the first difference is that only the first $24 mapping frames have the 'number of entries in DPLC' field; after them, all frames are assumed to have only one DPLC entry.
The second difference is in the format of each DPLC entry:
$STTT
Here, the S has the same meaning; but TTT is the number of words from the start of a hard-coded offset from the start of the art file. Specifically:
Mapping frame | Art offset (in tiles) |
---|---|
$00 to $03 | $0000 |
$04 to $0B | $0058 |
$0C to $0F | $0124 |
$10 to $11 | $0171 |
$12 to $15 | $0183 |
$16 to $1D | $01C0 |
$1E to $21 | $0264 |
$22 to $23 | $029E |
$24 to $2A | $02AE |
$2B to $31 | $02E3 |
$32 or more | $031E |
Additionally, the character art in Special Stages is loaded from main RAM, and it is decompressed at the start of the Special Stage.
Getting rid of it
Editing these DPLCs by hand is an error-prone and time-consuming enterprise, because you have to pay attention to the hard-coded art offsets (or edit them too) and you can only check your work on a built ROM. The easiest way to deal with these mappigns is by not using them.
For starters, grab this file: File:SpecStagS2-DPLC.7z. It contains pre-converted DPLCs for Sonic, Tails and Tails' tails. These still use the single art file for all 3, but the DPLCs have been split and converted from the Special Stage format. Decompress it to the mappings/spriteDPLC dir and make sure that all files are BINCLUDEd in the disassembly. From here on, I will assume that you have labelled these BINCLUDEd DPLCs as 'Obj09_MapRUnc', 'Obj10_MapRUnc' and 'Obj88_MapRUnc'.
Next, open up your disassembly and find label 'dword_33AA2'. Delete it and the next 4 lines. Now find label 'loc_33AD8' (2007 disassembly) or 'LoadSSPlayerDynPLC' (Hg disassembly). Just above it, there is a line referring to 'dword_33AA2'. Replace this line with this:
move.l #$FF0000,d6
lea (Obj09_MapRUnc).l,a2
Now select everything from 'loc_33AD8'/'LoadSSPlayerDynPLC' up until the rts and replace it by this:
moveq #0,d0
move.b mapping_frame(a0),d0
cmp.b (a4),d0
beq.s +
move.b d0,(a4)
add.w d0,d0
adda.w (a2,d0.w),a2
move.w (a2)+,d5
subq.w #1,d5
bmi.s +
-
moveq #0,d1
move.w (a2)+,d1
move.w d1,d3
lsr.w #8,d3
andi.w #$F0,d3
addi.w #$10,d3
andi.w #$FFF,d1
lsl.w #5,d1
add.l d6,d1
move.w d4,d2
add.w d3,d4
add.w d3,d4
jsr (QueueDMATransfer).l
dbf d5,-
+
rts
This takes care of Sonic; time now for Tails. Find label 'dword_349B8' and, once again, delete it and the four lines below it. Then find the next line that references 'dword_349B8' and replace it by this:
move.l #$FF0000,d6
lea (Obj10_MapRUnc).l,a2
Just below this, you will find this line:
moveq #$12,d1
Replace it by this:
moveq #0,d1
In the Special Stage, Tails uses the same DPLC routine as Sonic, so this is enough for Tails too. Time now for Tails' tails. Find label 'dword_34AA0'; delete it and the next 3 lines.
Now find this line right after:
bsr.w JmpTo43_DisplaySprite
Select it and everything below it until the following rts and delete it. If you are using the Hg disassembly, paste this at that location:
bsr.w JmpTo43_DisplaySprite
move.l #$FF0000,d6
lea (Obj88_MapRUnc).l,a2
lea (Tails_LastLoadedDPLC).w,a4
move.w #tiles_to_bytes(ArtTile_ArtNem_SpecialTails),d4
moveq #0,d1
bra.w LoadSSPlayerDynPLC
If you are using the aging 2007 disassembly, paste this instead:
bsr.w JmpTo43_DisplaySprite
move.l #$FF0000,d6
lea (Obj88_MapRUnc).l,a2
lea ($FFFFF7DF).w,a4
move.w #$62C0,d4
moveq #0,d1
bra.w loc_33AD8
If you did everything right, you can now build the ROM and the Special Stage will be using the normal DPLC format, and you can easily edit it at your heart's contents.