Game Boy format

From Princed Wiki
Revision as of 06:38, 18 December 2016 by David (talk | contribs) (guards, start on level)
Jump to: navigation, search

This document describes the format of data in Prince of Persia 1 for the Game Boy (GB) and the Game Boy Color (GBC).

General

Byte order: Little-endian (Intel) byte order is used, unless noted otherwise.

Numbering of bits: The least significant bit of a byte is bit 0, the most significant bit of a byte is bit 7.

Addresses: The Game Boy (Color) uses banked ROM.

  • Offsets 0x0000..0x3FFF always refer to the first 16 kB of the ROM.
  • Offsets 0x4000..0x7FFF refer to the currenly paged 16 kB bank.
    • Linear Address = Bank * 0x4000 + (Offset - 0x4000) = (Bank << 14) | (Offset & 0x3FFF)

Versions:

  • Game Boy Color, Europe
  • Game Boy, Europe
  • Game Boy, Japan
  • Game Boy, USA

Levels

The level table

Offset:

  • GBC: 0x1DC2C..0x1DC51, 19 levels
  • GB (EU/JP/US): 0x1E189..0x1E1A8, 16 levels

For each level, there is a 2-byte offset, to be understood in the same Bank where the table is (Bank 7).

The levels are numbered as:

  • Level 0: Various. (Palace in the #Level settings, i.e. used for princess room.)
    • Room 1: menu (select new game, continue, or training)
    • Room 2: password (linked from room 1)
    • Room 5: princess room (intro and cutscenes) (the starting position points here)
    • Room 6: language select (EU only) (also exists in the JP version, but not used)
    • Room 8 (GBC): left of princess room (linked from room 5)
  • Levels 1-14 match the DOS version.
  • Level 15 (GBC): Princess room. (ending)
  • Level 16 (GBC) / Level 15 (GB): Same offset as level 0. (But it's dungeon in the #Level settings, i.e. used for the other rooms of that level.)
  • Level 17 (GBC): Training part 1.
  • Level 18 (GBC): Training part 2.

Compression

  • 1 byte: Number of replacement pairs.
  • For each replacement pair:
    • 1 byte: "left"
    • 1 byte: "right"
  • 2 byte: Length after decompression.
  • Compressed data follows:
repeat while you don't have enough output bytes:
	read 1 byte;
	if the byte appears in "left":
		count := 1;
		repeat:
			read 4 bits through a 8-bit queue into value; // TODO: explain this better
			count := count + value;
		while value = 0xF;
		output the byte, repeated count times;
	else if the byte appears in "right":
		output the corresponding "left" byte;
	else:
		output the byte as is;
	end if;
end repeat;

Level format

Tiles:

  • For each 24 rooms:
    • For each 30 tiles:
      • 1 byte: Tile. The bottom 5 bits are the tile type (0x00..0x1F); the top 3 bits are the modifier (0..7). See #Tile types.
    • Or: A single 0xFF byte, meaning that all tiles are 0x00. (This is a second layer of compression.)

Room links:

  • For each 24 rooms:
    • For each direction in left, right, above, below:
    • 1 byte: The room adjacent in that direction.
      • Bottom 7 bits: room number. (1..24, or 0 for no room.)
      • Top 1 bit (GBC): if 1, the next level will start when the prince exits the room in that direction. (Used on levels 6, 12, 14, 17.)

Starting place:

  • 1 byte: Starting room. (1..24)
  • 1 byte: Starting tilepos. (0..29)
  • 1 byte: Starting direction. (0x00=right, 0xFF=left)

Guards:

  • For each 24 rooms:
    • 1 byte: Guard info. The bottom 7 bits are the tilepos. (0..29, or 30 if there is no guard) The top 1 bit is the direction. (0=right, 1=left)

Door links:

  • For each door link:
    • 1 byte: button room (1..24)
    • 1 byte: button tilepos (0..29)
    • 1 byte: effect: 0 = close, 1 = open
    • 1 byte: target room (1..24)
    • 1 byte: target tilepos (0..29)
  • 1 byte: 0xFF, marks the end of door links and level data.

Tile types

These mostly match the DOS version.

Modifiers were usually copied from (the bottom 3 bits of) the modifiers the DOS levels, even for tiles where this makes no difference. For example, many empty tiles have 7 as modifier where the DOS level had 0xFF.

tile id tile type modifiers and notes
0x00 empty 0 = nothing, 1 or 2 = wall pattern (in dungeon), 3 = window
0x01 floor 0 = nothing, 1 = wall pattern (in dungeon)
0x02 spikes
0x03 column
0x04 gate 1 = open, 2 = closed, others = open (not used)
0x05 mirror after jump Palace only. Not used in level data: 0x0D becomes this after the prince jumps through it. Same as 0x0D, except: No reflection. No black rectangle. The prince won't lose HP if he jumps through it.
0x06 close button The modifier is ignored, door links are stored differently from the DOS version.
0x07 gate top with floor 0 = with arch, 1 = black, 2 = with pattern
0x08 big column bottom
0x09 big column top
0x0A potion 0 = used in password room (+1 hp), 1 = heal (+1 hp), 2 = life, 3 = float, 4 = appears on level 9 where the DOS version has the flip potions (+1 hp), 5 = hurt (-1 hp), 6 or 7 = (not used) (+1 hp)
0x0B loose floor
0x0C gate top without floor 0 = with arch, 1 = black, 2 = with pattern
0x0D mirror Palace only. Not used in level data: Placed on level 4 when the exit door opens. Different from DOS: it occupies the right edge of the tile, and the rest is covered by a black rectangle to cover the reflection. Reflection appears only on level 4 room 4.
0x0E broken floor
0x0F open button The modifier is ignored, door links are stored differently from the DOS version.
0x10 level door left 0 = open (language/menu rooms), 2 = closed (regular levels), others = open (not used)
0x11 level door right
0x12 chomper
0x13 torch
0x14 wall
0x15 skeleton
0x16 sword Dungeon only.
0x17 mirror left Palace only. Not used in level data. Placed on left side of mirror to cover the mirror image, and there it appears as a black rectangle.
0x18 balcony Appears as a regular floor. Used on level 6 and 14 where the DOS version has the right half of balconies.
0x19 arch column
0x1A arch down Palace only.
0x1B small arch Palace only.
0x1C big arch left Palace only.
0x1D big arch right Palace only.
0x1E torch with broken floor Not used in level data: a regular torch becomes this when a loose floor lands on it.
0x1F shadow floor Appears only when you step on it. Used on level 12.

Level settings

GB:

  • 0x000CE..0x000DC: guard HPs, indexed by level
  • 0x000DD..0x000EB: guard move(?) probability, indexed by level
  • 0x000EC..0x000FA: guard move(?) delay, indexed by level
  • 0x1E1A9..0x1E1B8: Level types: 0 = dungeon, 1 = palace
  • 0x1E1B9..0x1E1C8: type of level entry?
    • 0x05 = short run (level 1)
    • 0x08 = long run (level 13)
    • 0x2C = fall (level 7)
    • 0x67 = standing (most levels)
    • 0x7B = princess (level 0)

GBC:

  • 0x00041..0x00047: guard colors, indexed by HP
  • 0x000BA..0x000CC: guard HPs, indexed by level
  • 0x000CD..0x000DF: guard move(?) probability, indexed by level
  • 0x000E0..0x000F2: guard move(?) delay, indexed by level
  • 0x1DC52..0x1DC64: Level types: 0 = dungeon, 1 = palace, 2 = dungeon (training), 3 = palace (princess room)
  • 0x1DC65..0x1DC8A: level palette selection (2-byte offsets, to be understood in Bank 2)
    • 0x47D0 = (dungeon) blue (level 1, 12, 13, 16)
    • 0x5BB4 = (palace) orange (level 4)
    • 0x6EE0 = (dungeon) red (level 17, 18)
    • 0x6F20 = (palace) pink (level 0, 14, 15)
    • 0x6F60 = (dungeon) green (level 7)
    • 0x6FA0 = (dungeon) brown (level 2)
    • 0x6FE0 = (dungeon) purple (level 3)
    • 0x7020 = (dungeon) teal (level 8)
    • 0x7060 = (dungeon) maroon (level 9)
    • 0x70A0 = (palace) green (level 6)
    • 0x70E0 = (palace) blue (level 5)
    • 0x7120 = (palace) red (level 10)
    • 0x7160 = (palace) yellow (level 11)
  • 0x1DC8B..0x1DCB0: sprite palette selection (2-byte offsets, to be understood in Bank 2)
    • 0x71A0 = (most levels)
    • 0x71E0 = (level 6, 7)
    • 0x7220 = (level 5)
    • 0x7260 = (level 10)
    • 0x72A0 = (level 11)
    • 0x72E0 = (level 14)
  • 0x1DCB1..0x1DCC3: Type of level entry:
    • 0x05 = short run (level 1, 15, 18)
    • 0x08 = long run (level 13)
    • 0x2E = fall (level 7)
    • 0x6A = standing (most levels)
    • 0xA4 = princess (level 0)

Palettes (GBC)

Each color is stored on 16 bits (2 bytes):

  • Bits 0..4: Red Intensity. (0x00..0x1F)
  • Bits 5..9: Green Intensity. (0x00..0x1F)
  • Bits 10..14: Blue Intensity. (0x00..0x1F)
  • Bit 15: Unused.

Offsets:

  • 0x087D0..0x0880F: level palette: 1 set of 32 colors, referenced from #Level settings
  • 0x09BB4..0x09BF3: level palette: 1 set of 32 colors, referenced from #Level settings
  • 0x0AEE0..0x0B19F: level palettes: 11 sets of 32 colors, referenced from #Level settings
  • 0x0B1A0..0x0B31F: sprite palettes: 6 sets of 32 colors, referenced from #Level settings
  • 0x1137F..0x113AE: title screen palette
  • 0x12B96..0x12BC5: intro text palette
  • 0x2925C..0x2929B: copyrights screen palette (Red Orb)

Various hacks

GBC:

meaning offset size default value new value
Starting minutes 0x0191 1 byte 0x3C = 60
Starting HP (for both new game and training) 0x080D 1 byte 0x03 = 3
Training level number - 1 0x0664 1 byte 0x10 = 16 = level 17
Skip most of the intro and start the training level directly. 0x02E3 3 bytes 0xCD 0x5F 0x20 0xC3 0x63 0x06
Skip Red Orb screen. 0x023E 2 bytes 0x38 0xF7 0x18 0x19

TODO

  • Sprites
  • Texts
  • (Sounds and music?)