Shadow Dancer, The Secret of Shinobi:Notes
A French version of this page, maybe more up-to-data, is available here. I intend to translate it, but feel free to do it yourself if you can.
This page contains notes about an attempt to hack the game, replacing graphics and maps to make the game similar to the arcade classic Shinobi.
I intend to study :
- how to edit sprites graphical data (mostly done)
- how to alter character behaviour (to do)
- how to edit sprites collision boxes (to do)
- how to edit tiles and maps (mostly done)
- how to edit collisions with maps (in progress)
The terminology used here is mostly borrowed from the document entitled Sega Genesis VDP documentation by Charles MacDonald (available on RHDN), refered by [CMD] :
- a pattern is a 8*8 16 colors tile, aimed to be loaded in VRAM (see [CMD])
- a sprite is made from 1*1 to 4*4 contiguous pattern(s), with palette, flipping and link attributes (see [CMD])
- a multisprite is made from several sprites, with position relatives to an origin (not in [CMD])
- a ROM address is between 00000 and 80000, a RAM address between FF0000 and FFFFFF
- a stage pointer table is read as follow : if you're at mission m and sub-mission s
- the m-th word is an offset from the beginning of the table ; you get to addr
- the s-th word from this position in an offset from addr to the relevant entry of the table
Palettes are organized as groups of 4 palettes (from 0 to 3)
There two sets of groups.
One is loaded for special events in the game (title screen, mission screen), the other is particular as each stage.
The table is located at 0x12FA8. It starts with a stage pointer table. Then, each entry is made of 4 words that are all offsets from the beginning of the entry, to the 16 words giving the palette.
It is read by routine at 0x12CC8
They are stored in a table starting with word offsets from the beginning of the table to the entry. Then each entry is a word offset from the beginning of the entry to the palette itself.
It is read by routine at 0x12CFE
special_id | description 00 | Sega logo 01 | Opening 02 | Start Stage Screen / After Stage Scoring 03 | Start Mission Screen 04 | Bonus Stage ??
This section describes how the Joe Musashi and the ennemies "sprites" (in fact, multisprites) are loaded.
A whole set of patterns is loaded at once at RAM address FF9300. Only relevant patterns will later be loaded in VRAM. The set is Nemesis-compressed at ROM address 23540. Nemesis compression is a well-known compression scheme which is described here.
Loading in VRAM
Patterns are loaded at the beginning of each stage. Their are loaded from a table stored at 0x1AD36. It begins with a list of 56 word-offsets to the actual entry.
An entry is :
- a word, counting the number N of group of patterns to load
- then, for each group, 14 bytes of data, of the form :
93xx 94xx 95xx 96xx 97xx cccccccc
The first 5 words are sent to the VDP control port to set VDP registers $13 to $17. In particular, you can get the RAM adress from which the patterns are loaded, and the number of words to copy. The last long is the "copy" command sent to the VDP control port. You can get from it the position in VRAM where to copy patterns.
The multisprite data is stored in a table at 0x69370. It begins with a sequence of 59 word-offsets to the relevant entries (why 59 and not 56 like the loading table ? I don't know).
Then each entry is:
- a byte, whose bit format is :
n is the number of sprites constituting the multisprite. d forces the program to skip :
- the next 6 bytes if d = 0
- the next 12 bytes if d = 1
- the next 16 bytes if d = 2
- nothing if d = 3
- then, for each sprite, a sequence of 6 bytes :
XX YY PP TTTT
- XX and YY are the coordinates of the sprite, relative to the hot-spot of the multisprite (signed bytes)
- TTTT has bit-format :
- tt tttttttt is the id of the first pattern in the sprite ( >= 0x7A0)
- f is 1 if the sprite must be horizontally flipped
- pp is a set of flags :
- hh and vv are the size of the sprite in number of patterns - 1 (hh = 0 : 1 pattern or 8 pixels wide, hh = 3 : 4 patterns or 32 pixels wide)
The sprite are then built by copying patterns from the first, in column-first order (the normal way to build sprites for the MD, see [CMD]).
|Internal Data for Shadow Dancer|