Difference between revisions of "SEGA Genesis format"
(Created page with "This file describes the format of data in Prince of Persia 1 for the SEGA Genesis, also known as the SEGA Mega Drive. The game has two versions: One for the USA (Genesis), an...") |
|||
Line 16: | Line 16: | ||
'''Compression''': The European version of the game uses RNC compression for some graphics. | '''Compression''': The European version of the game uses RNC compression for some graphics. | ||
− | This is a popular library by Rob Northen Computing. | + | This is a popular library by Rob Northen Computing. |
− | '''Hardware''': You can find some documentation about the SEGA Genesis | + | '''Hardware''': You can find some documentation about the SEGA Genesis at Zophar's Domain. |
== Levels == | == Levels == |
Revision as of 12:04, 13 November 2016
This file describes the format of data in Prince of Persia 1 for the SEGA Genesis, also known as the SEGA Mega Drive.
The game has two versions: One for the USA (Genesis), and one for Europe (Mega Drive). They have data at different offsets, and I will always note which offsets are for which versions.
Contents
General
Byte order: Big-endian (Motorola, network) byte order is used, unless noted otherwise. This is the native endianity of the Motorola 68k CPU in the SEGA Genesis.
Numbering of bits: The least significant bit of a byte is bit 0, the most significant bit of a byte is bit 7.
Addresses: Since the CPU is 32-bit, there are no segments, banks, paging, or anything like that. You can just use each address as it is. (Only the bottom 24 bits are used by the hardware. The top 8 bits are usually 0, though.)
Compression: The European version of the game uses RNC compression for some graphics. This is a popular library by Rob Northen Computing.
Hardware: You can find some documentation about the SEGA Genesis at Zophar's Domain.
Levels
The level table
Starting address
Game version | Starting address | Number of levels |
---|---|---|
USA | 0x6A5C | 13 levels |
Europe | 0x358C2 | 17 levels |
Contents for each level
The table stores 20 bytes about each level:
Size | Contents |
---|---|
2 bytes | Level's height, in pixels. Must be a multiple of 192, the height of a room. Divide by 64 to get the height in tiles. |
2 bytes | Level's width, in pixels. Must be a multiple of 320, the width of a room. Divide by 32 to get the width in tiles. |
2 bytes | Size of each level map, in tiles (bytes). (width * height) |
4 bytes | Start address of level's #Graphics map. |
4 bytes | Start address of level's #Objects map. |
2 bytes | Y coordinate of the top of the starting room, in pixels. Subject to the same restrictions as level height. |
2 bytes | X coordinate of the left of the starting room, in pixels. Subject to the same restrictions as level width. |
2 bytes | Level type: 0=dungeon, 1=palace. |
TODO: Starting position within starting room?
Maps
Both maps store tiles in column-major order. That is, you start from the top-left corner of the level, and go down. After you finished a column, you continue at the top of the next column.
Note that maps are not split into rooms (only when displayed), and therefore there are no room links or room numbers.
Graphics map
Each byte tells which #Level graphics block is to be displayed here. The same index is used for both layers.
Objects map
Each byte tells what object is in the corresponding tile.
The possible values are:
0x00: empty 0x01: wall 0x02: floor (and all objects below include a floor) 0x03: opener button (*) 0x04: closer button (*) 0x05: gate (*) 0x06: loose floor (*) 0x07: spikes (*) 0x08: chomper (*) 0x09: potion (*) 0x0A: level door (*) 0x0B: sword
Further info about objects marked with (*) (and also guards) can be found in the #Object tables.
Object tables
type of object | USA address | Europe address | bytes per object |
---|---|---|---|
opener buttons | 0x1E592 | 0x4E8F6 | 14 |
closer buttons | 0x1EBFC | 0x4F138 | 14 |
spikes | 0x25F94 | 0x56612 | 8 |
potions | 0x27BAE | 0x581B0 | 10 |
chompers | 0x228DE | 0x52D86 | 10 |
loose floors | 0x1CD3E | 0x4CF3C | 10 |
gates | 0x5B96 | 0x61CE | 12 |
level doors | 0x41DE | 0x46C2 | 10 |
guards | 0x1FAC | 0x2B02 | 24 |
Each table has a header. The header contains 6 bytes per level:
- 2 bytes for the number of objects on that level,
- 4 bytes for the start address of the sub-table of the objects on this level. (It's 0 if the count is 0.)
(The two bytes before the header always contain 0x4E75. This is the RTS instruction that ends the preceding subroutine.)
The contents of each table depend on the type of the object.
All coordinates are in pixels.
opener and closer buttons
- 2 bytes: 1
- 2 bytes: Y coordinate (bottom)
- 2 bytes: X coordinate (left)
- 2 bytes: 0
- 2 bytes: first triggered gate: 0-based index into gates table, or 0xFFFF = exit door
- 2 bytes: second triggered gate, or 0xFFFD for none
- 2 bytes: third triggered gate, or 0xFFFD for none
spikes
- 2 bytes: 1
- 2 bytes: Y coordinate (bottom)
- 2 bytes: X coordinate (left)
- 2 bytes: 0xFFFF
potions
- 2 bytes: bubble colors: 1 (red) or 3 (green)
- 2 bytes: Y coordinate (bottom)
- 2 bytes: X coordinate (left)
- 2 bytes: 0
- 2 bytes: effect:
- 0 = heal
- 1 = life
- 2 = hurt
- 3 = slow-fall
chompers
- 2 bytes: 1
- 2 bytes: Y coordinate (top)
- 2 bytes: X coordinate (left)
- 2 bytes: 0
- 2 bytes: 0
loose floors
- 2 bytes: 1
- 2 bytes: Y coordinate (bottom)
- 2 bytes: X coordinate (left)
- 2 bytes: 0
- 2 bytes: 0
gates
- 2 bytes: state: 0=closed, 3=open
- 2 bytes: Y coordinate (top)
- 2 bytes: X coordinate (left edge of the gate's tile, but the gate is on the right edge of this tile)
- 2 bytes: state: 0=closed, 0x0C=open
- 2 bytes: state: 0=closed, 0xFFFF=open
- 2 bytes: unknown, 0 or 1
level doors
- 2 bytes: type: 0=start, 2=exit door
- 2 bytes: Y coordinate (top)
- 2 bytes: X coordinate (left)
- 2 bytes: 0
- 2 bytes: 0
guards
- 2 bytes: 0
- 2 bytes: Y coordinate (bottom)
- 2 bytes: X coordinate (left)
- 2 bytes: direction: 0=left, 0x800=right
- 2 bytes: 0
- 4 bytes: guard sprite (values below are for USA / Europe)
- 0x23838 / 0x53C8C = regular guard
- 0x23954 / 0x53DA2 = skeleton
- 0x23DD8 / 0x54226 = fat
- 0x24000 / 0x54448 = shadow
- 0x241B2 / 0x545FA = Jaffar
- 2 bytes: guard type
- 0 = regular guard
- 1 = skeleton
- 2 = fat
- 3 = shadow
- 4 = Jaffar
- 2 bytes: skill
- 2 bytes: hit points
- 2 bytes: 0
- 2 bytes: 0
Level graphics
USA:
Level type | Palette addr | Tiles addr | Blocks addr | Number of tiles |
---|---|---|---|---|
0 (dungeon) | 0x47B20 | 0x40AC0 | 0xDCEE | 898 |
1 (palace) | 0x4E680 | 0x47B40 | 0x154EE | 858 |
Europe:
Level type | Palette addr | Tiles addr | Blocks addr | Number of tiles |
---|---|---|---|---|
0 (dungeon) | 0x7976C | 0x732D6 | 0x3DEEC | 898 |
1 (palace) | 0x7FA38 | 0x797AC | 0x456EC | 858 |
Palettes
A palette contains 16 colors. Each color is stored on 16 bits (2 bytes), in X:R:G:B = 4:4:4:4 bits format. (This means that a palette takes up 32 bytes.)
But each level graphics has two palettes, so there are 32 colors (64 bytes) at the pointed address!
Tiles
Each tile has 8*8 pixels. Each pixel is stored on 4 adjacent bits. (This means that each tile takes up 32 bytes.)
Within a byte, bits 7..4 store the left pixel, and bits 3..0 store the right pixel. (There is no interleaving or separated planes, as on some other hardware. (SNES, etc.))
Color 0 is transparent!
Blocks
There are 2*256 blocks. The first 256 are for the back layer, the next 256 for the front layer. Block with the same index from the two layers are always used together.
Each block is 4 tiles (32 pixels) wide and 8 tiles (64 pixels) high.
Each tile-position is stored on 2 bytes (16 bits):
bits | mask | meaning |
---|---|---|
15 | 0x8000 | Priority. 0 = behind sprites, 1 = in front of sprites. |
14..13 | 0x6000 | Palette index (0-3). For level graphics, only 0 and 1 are used, corresponding to the two palettes mentioned in #Palettes. |
12 | 0x1000 | Vertical flip. |
11 | 0x0800 | Horizontal flip. |
10..0 | 0x07FF | Tile number. |
TODO
- Texts
- Sprites
- Full-screen images
- Sound samples?
- (Music???)