The current URL is datacrystal.tcrf.net.
Wonder Boy III: Monster Lair (Genesis)/Notes: Difference between revisions
Lelegofrog (talk | contribs) m (Lelegofrog moved page Wonderboy III: Monster Lair (Genesis)/Notes to Wonder Boy III: Monster Lair (Genesis)/Notes: title consistency with TCRF) |
|
(No difference)
|
Revision as of 21:30, 17 May 2024
The following article is a Notes Page for Wonder Boy III: Monster Lair (Genesis).
Gfx format
Gfx data (tiles) are organized by levels (0 to 11). Pointers to each level data are stored from 0x43000 to 0x4302c. Then, for each level, gfx are stored by chunk.
For example, pointer to level 3 chunks is 0x432cc (read at 0x4300c). Then, at 0x432cc, there are pointers to 4 chunks : 0x00000000 (null chunk), 0x432e0, 0x43188, 0x433aa, 0x433aa.
Each chunk is a list of 16 bytes entries, terminated by a 0000 :
- 1 word: number of tiles - 1
- 1 long: pointer to actual data
- 1 word: 1 if gfx uses color indices 0 to 7 (x = 0 in the following), -1 if gfx uses color indices 8 to 15 (x = 1 in the following).
Actual tile data is stored in 3bpp interleaved format:
- 1 byte: a7 a6 a5 a4 a3 a2 a1 a0
- 1 byte: b7 b6 b5 b4 b3 b2 b1 b0
- 1 byte: c7 c6 c5 c4 c3 c2 c1 c0
gives :
- 1 byte (2 pixels): (x a7 b7 c7) (x a6 b6 c6)
- 1 byte (2 pixels): (x a5 b5 c5) (x a4 b4 c4)
- 1 byte (2 pixels): (x a3 b3 c3) (x a2 b2 c2)
- 1 byte (2 pixels): (x a1 b1 c1) (x a0 b0 c0)
Chunk 0 | Chunk 1 | Chunk 2 | Chunk 3 | Chunk 4 | Chunk 5 | |
---|---|---|---|---|---|---|
Level 0 | 0x4303e | 0x43060 | 0x43092 | |||
Level 1 | 0x430d6 | 0x43188 | 0x43192 | 0x43192 | ||
Level 2 | 00000000 | 0x431e0 | 0x43188 | 0x4328a | 0x4328a | |
Level 3 | 00000000 | 0x432e0 | 0x43188 | 0x433aa | 0x433aa | |
Level 4 | 00000000 | 0x433fc | 0x4347e | 0x43188 | 0x43188 | 0x434a8 |
Level 5 | 00000000 | 0x434f6 | 0x43188 | 0x43598 | 0x43598 | |
Level 6 | 00000000 | 0x435e6 | 0x43188 | 0x43698 | 0x43698 | |
Level 7 | 00000000 | 0x436e6 | 0x43188 | 0x43790 | 0x43790 | |
Level 8 | 00000000 | 0x437ee | 0x43188 | 0x438c0 | 0x438c0 | |
Level 9 | 00000000 | 0x43916 | 0x439a8 | 0x439b2 | 0x439b2 | |
Level 10 | 00000000 | 0x439fe | ||||
Level 11 | 0x43034 |
Sprites
For some reason, projectiles sprites are not handled the same way as other (regular) sprites.
Regular Objects
Sprite frames are built using 2 tables for each Sprite.
placementTable contains placement and size information. It starts too with an offset (word) to the frame id, then :
- 1 word: number of HW sprites
- 1 word: 00000000 0000WWHH (W=width, H=height)
- 1 signed byte: delta y
- 1 signed byte: delta x
mapTable contains tile information and flip flags. It starts with an offset (word) to the frame id, then, for each HW sprite, the tile attributes in the standard format pccvhnnn nnnnnnnn (p=priority, c=palette, v=vflip, h=hflip, n=tile id).
Note there's no counter in mapTable table, but there are as many tile attributes as the number of HW sprites given in placementTable.
For example, Leo's tables are located at 0x20588 (placementTable) and 0x202c4 (mapTable). Frame 3 (walking frame) is given by the 4th word of both tables (0xa0 for placementTable and 0x4c for mapTable) which leads to 0x20628 and 0x20310.
The data in the placementTable is then:
- 0003: there are 3 HW sprites
- 1st HW sprite:
- 0009: size is (24, 16)
- 00f0: delta y = -16
- 00f4: delta x = -12
- 2nd HW sprite:
- 0008: size is (24, 8)
- 0000: delta y = 0
- 00f4: delta x = -12
- 3rd HW sprite:
- 0008: size is (24,8)
- 0008: delta y = 8
- 00f4: delta x = -12
The tile information in mapTable is:
- 00c9: 1st HW sprite uses tiles id from 0xc9 to 0xce
- 00cf: 2nd HW sprite uses tiles id from 0xcf to 0xd1
- 00d2: 3rd HW sprite uses tiles id from 0xd2 to 0xd4
Object | Nb of frames | mapTable | placementTable | GFX data |
---|---|---|---|---|
Leo | 20 | 0x202c4 | 0x20588 | 0x473a0 |
Kiwi | 3 | 0x1f06e | 0x1fbc4 | 0x53ab0 |
Carot | 2 | 0x1f074 | 0x1fbca | 0x53bd0 |
Tomato | 3 | 0x1f078 | 0x1fbce | 0x53c90 |
Sweat | 2 | 0x1f07e | 0x1fbd4 | 0x53e70 |
Grape | 2 | 0x1f092 | 0x1fbfc | 0x541e8 |
Lemon | 3 | 0x1f09c | 0x1fc12 | 0x54890 |
Beam capsule | 1 | 0x1f500 | 0x1fbc2 | 0x4d300 |
Missile capsule | 1 | 0x1f502 | 0x1fbc2 | 0x430b2 |
Wide ring capsule | 1 | 0x1f504 | 0x1fbc2 | 0x4d300 |
Spiral capsule | 1, | 0x1f506 | 0x1fbc2 | 0x4d300 |
Fireball capsule | 1 | 0x1f4fe | 0x1fbc2 | 0x4d300 |
Big Fire capsule | 1 | 0x1f4fc | 0x1fbc2 | 0x4d300 |
Whelk | 2 | 0x20e1a | 0x1fdc2 | 0x68c30 |
Whelk death | 1 | 0x20e1e | 0x1fe92 | 0x68c30 |
Snail | 2 | 0x20e26 | 0x1fdc6 | 0x68810 |
Snail death | 1 | 0x20e2a | 0x1fe94 | 0x68810 |
Walrus | 4 | 0x20e38 | 0x1fdca | 0x69290 |
Dead Walrus | 1 | 0x20e40 | 0x1fe96 | 0x69290 |
Octopus | 2 | 0x20e56 | 0x1fdd2 | 0x697e8 |
Climbing Snail | 2 | 0x20e5e | 0x1fdc6 | 0x68a20 |
Dead Climbing Snail | 1 | 0x20e62 | 0x1fe92 | 0x68a20 |
Pelican | 2 | 0x20e6a | 0x1fdd6 | 0x69050 |
Explosion | 2 | 0x21da0 | 0x1feb4 | 0x4d300 |
Moving rock | 1 | 0x1e89a | 0x1fc20 | 0x56450 |
Projectiles
For projectiles, there's only 1 table, starting with offsets, each frame being described :
- 1 word: counter
- 1 word: 00000000 0000WWHH (W=width, H=height)
- 1 signed byte: delta y
- 1 signed byte: delta x
- 1 word: pccvhnnn nnnnnnnn (p=priority, c=color, v=vflip, h=hflip, n=tile id)
Object | Nb of frames | table | GFX data |
---|---|---|---|
Normal shot | 1 | 0x1d528 | 0x4d300 |
Fireball | 2 | 0x1d652 | 0x4d300 |
Spiral Shot | 1 | 0x1d532 | 0x4d300 |
Wide Ring Blaster | 4 | 0x1d5e8 | 0x4d300 |
Beam | 3 | 0x1d66c | 0x4d300 |
Missile(*) | 7 | 0x1d53c | 0x430b2 |
(*) Missile needs to preload its tileset.
Tilemaps
Tilemaps are splitted by chunks of 8*32 tiles. A map is a list of pointers to each chunk, terminated by a -1 signed long (0xffffffff). A special value of 0x0000ffff indicates that you have to insert the exit background (see fig) there.
Each chunk is a list of 8 words offset from this entry to actual data.
Chunk data is encoded up to down, left to right, with a simple RLE scheme; each entry is a word :
- if the word if of the form 0xffXX, then XX is a counter, and the next word is repeated (counter + 1) times,
- else the word is directly written
For example, level 1 background A is located at 0x3224a :
0x3224a : 0002fc9e 0002fc9e 00030548...
up to
0x3237a: ffffffff
First chunk is located at 0x2fc9e :
0x2fc9e: 0010 0026 0046 0066 0086 00a6 00c6 00dc
First column data is at 0x2fc9e + 0x0010 = 0x2fcae, second column data is at 0x2fca0 + 0x26 = 0x2fcc6, etc.
First column data is :
0x2fcae: ff15 0020 235b 235f 2363 2335 c402 c3b4 c3b6 c3b8 ff01 c3ba
which decompress to
0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 235b 235f 2363 2335 c402 c3b4 c3b6 c3b8 c3ba c3ba