(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.
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:
where S is (number of tiles-1) and TTT is the offset (in tiles) from the start of the art file .
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:
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.
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:
Replace it by this:
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:
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 (TailsTails_LastLoadedDPLC).w,a4 move.w #tiles_to_bytes(ArtTile_ArtNem_SpecialTails_Tails),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.
|SCHG How-To Guide: Sonic the Hedgehog 2 (16-bit)|
|Fix Demo Playback | Fix a Race Condition with Pattern Load Cues | Fix Super Sonic Bugs | Use Correct Height When Roll Jumping | Fix Jump Height Bug When Exiting Water | Fix Spin Dash Code and Add Spin Dash Speeds | Fix Screen Boundary Spin Dash Bug | Correct Drowning Bugs | Fix Camera Y Position for Tails | Fix Tails Subanimation Error | Fix Tails' Respawn Speeds | Fix Accidental Deletion of Scattered Rings | Fix Ring Timers | Fix Rexon Crash | Fix Monitor Collision Bug | Fix EHZ Deformation Bug | Correct CPZ Boss Attack Behavior | Fix Bug in ARZ Boss Arrow's Platform Behavior | Fix ARZ Boss Walking on Air Glitch | Fix ARZ Boss Sprite Behavior | Fix Multiple CNZ Boss Bugs | Fix HTZ Background Scrolling Mountains | Fix OOZ Launcher Speed Up Glitch | Fix DEZ Giant Mech Collision Glitch | Fix Boss Deconstruction Behavior | Fix Speed Bugs|
|Remove the Air Speed Cap | Disable Floor Collision While Dying | Modify Super Sonic Transformation Methods & Behavior | Enable/Disable Tails in Certain Levels | Collide with Water After Being Hurt | Retain Rings When Returning at a Star Post | Improve the Fade In\Fade Out Progression Routines | Fix Scattered Rings' Underwater Physics | Insert LZ Water Ripple Effect | Restore Lost CPZ Boss Feature | Prevent SCZ Tornado Spin Dash Death | Improve ObjectMove Subroutines | Port S3K Rings Manager | Port S3K Object Manager | Port S3K Priority Manager | Edit Level Order with ASM | Alter Ring Requirements in Special Stages | Make Special Stage Characters Use Normal DPLCs | Speed Up Ring Loss Process|
|Create Insta-kill and High Jump Monitors | Create Clone and Special Stage Monitors | Port Knuckles|
|Port Sonic 1 Sound Driver | Port Sonic 2 Clone Driver | Port Sonic 3 Sound Driver | Expand the Music Index to Start at $00 (Sonic 2 Clone Driver Version)|
|Extending the Game|
|Extend the Level Index Past $10 | Extend the Level Select | Extend Water Tables | Add Extra Characters | Free Up 2 Universal SSTs|