Game Boy format

From Princed Wiki
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 from input;
	if the byte appears in "left":
		count := 1;
		repeat:
			read 4 bits from input through a 8-bit queue into value;
			That is:
				first time, you read a byte from input and use bits 7..4;
				second time, you use bits 3..0 of the already read byte and discard the byte.
			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)

A palette is 64 bytes long, and contains 32 colors, grouped into 8 sets of 4 colors each.

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 background palette: 1 set of 32 colors, referenced from #Level settings
  • 0x09BB4..0x09BF3: level background palette: 1 set of 32 colors, referenced from #Level settings
  • 0x0AEE0..0x0B19F: level background palettes: 11 sets of 32 colors, referenced from #Level settings
  • 0x0B1A0..0x0B31F: level sprite palettes: 6 sets of 32 colors, referenced from #Level settings
  • 0x1137F..0x113AE: title screen background palette
  • 0x12B96..0x12BC5: story frame+text background palette
  • 0x2925C..0x2929B: copyrights screen background palette (Red Orb)

Texts

version story texts table offset copyrights text offset credits texts offsets story text languages
GBC 0x12FEE see #Other graphics (GBC) 0x13016, 0x13033, 0x1304B, 0x13070, 0x1308F German, French, Spanish, English, Italian
GB EU 0x13087 0x130AF 0x131DE, 0x131F9, 0x1321D, 0x1323C, 0x1325D German, English, Spanish, French, Italian
GB JP 0x13087 0x130AF 0x13205, 0x1322A, 0x1324E, 0x1326D, 0x1328E (ununsed), Japanese, (unused), (unused), (unused)

The story texts table contains 20 offsets (2 bytes each) for each 4 occasions (intro 1, intro 2, bad ending, good ending) and for each 5 languages.

Fonts are stored in #Tilesets.

European

The decoding of European texts:

  • Repeat until you meet the end of text marker:
    • Read a byte.
    • Subtract 0x20 and truncate the result to a byte.
    • The lower 6 bits tell the index of the character within the font.
    • The upper 2 bits tell what is after the character:
      • 00 = nothing
      • 01 = new line
      • 10 = space
      • 11 = end of text

The character set:

 !"Ñ$Ç&'®®©+,-./
0123456789:Ù¡=¿?
ÄABCDEFGHIJKLMNO
PQRSTUVWXYZÖÜÀÈÌ
  • This mostly corresponds to range 0x20..0x5F from ASCII, but most symbols were replaced with accented letters or other symbols.
  • The zero is used for Ø in BRØDERBUND's name.
  • The two instances of ® are the top and bottom halves.

Japanese

This is only for story texts, the others are encoded as European.

The decoding of Japanese texts:

  • Repeat until you meet the end of text marker:
    • Read a byte.
    • It can have the following values:
      • 0x00..0x7F = The index of the character within the font.
      • 0xFE = new line
      • 0xFF = end of text

The character set:

 んわらやまはなたさかあゃぁりみ
ひにちしきいぃるゆむふぬつすくう
ゅっれめへねてせけえぇをろよもほ
のとそこおょぉンワラヤマハナタサ
カアャァリミヒニチシキイィルユム
フヌツスクウュッレメヘネテセケエ
ェヲロヨモホノトソコオョォ?!゛
゜」「…、。ゥー60
  • This is different from all encodings that I've seen so far.
  • There is some logic if you compare it with the usual syllable tables:
    • Elsewhere, the syllables are ordered first by consonant (-,K,S,T,N,H,M,Y,R,W), and then by vowel (A,I,U,E,O).
    • Here, the syllables are ordered first by vowel (A,I,U,E,O), and then by consonant, but in reverse order (W,R,Y,M,H,N,T,S,K,-).

Sprites (GBC)

start address size of each item contents
0x28000 2 bytes map offset (b/w)
0x28168 2 bytes map offset (color)
0x282D0 2 bytes tiles offset (b/w)
0x28438 2 bytes tiles offset (color)
0x285A0 1 byte bank for map and tiles (b/w)
0x28654 1 byte bank for map and tiles (color)
0x28708 1 byte X offset in tiles (+ = backwards)
0x287BC 1 byte X hit test?
0x28870 1 byte Y offset in tiles (+ = up)
0x28924 1 byte Y hit test?
0x289D8 2 bytes offset of associated sound effect (in bank 0x0F), see #Sound effects (GBC)
0x28B40 1 byte  ?
0x28BF4 1 byte  ?
0x28CA8 1 byte flags
  • bit 0: unknown
  • bit 1: unknown
  • bit 2: Does the char press the floor? Used with loose floors and buttons.
  • bit 3: unknown
  • Every table has 0xB4 = 180 items.
  • It seems that the Color version can run in b/w mode as well, with different graphics. Change the byte at offset 0x143 to 0x00 for this.
  • Offsets and banks can be all zero, in this case there are no sprites in this group.

At the map offset there is the following data:

  • 1 byte: number of images in sprite group
  • 1 byte: width of each image
  • 1 byte: height of each image
  • for each image:
    • for each row:
      • for each column:
        • 1 byte: 1-based index of tile, or 0 for none

At the tile offset there is the following data:

  • 1 byte: compression marker
  • 1 byte: number of tiles
  • for each tile:
    • 4 bits: compressed size of tile in bytes (first read bits 7..4, then read bits 3..0)
    • Possible values are 9..15, and 0 which means 16.
  • (pad to whole byte using 0 bits, if necessary)
  • for each tile:
    • for each pixel row: (0..7)
      • Read 1 byte.
      • If it's equal to the compression marker, repeat the last two bytes.
      • Otherwise, output the byte, read another byte, and output it as well.

Tiles

The Game Boy (Color) uses 2-bit planar tiles.

Tiles are in this format: (after decompression)

for B=0..7:
	byte B of plane 0
	byte B of plane 1

To get the color index of a pixel, from X and Y coordinates:

color = 0
for P=0..1:
	read bit 7-X of byte Y of plane P of the tile, and write it into bit P of color

This color index can be further modified by colormaps. See #Maps.

Other graphics (GBC)

Tilesets

They use the same compression as sprite tiles.

  • 0x08810: color dungeon
  • 0x09BF4: color palace
  • 0x0AA57: status bar
  • 0x101B8: b/w intro+font
  • 0x113BF: color intro+font
  • 0x1240E: b/w font+frame
  • 0x12BD6: color font+frame
  • 0x20004: b/w spikes
  • 0x20023: b/w spikes?
  • 0x20045: b/w spikes?
  • 0x20066: color spikes
  • 0x20087: color spikes?
  • 0x200AE: color spikes?
  • 0x200D7: ??? dungeon button
  • 0x20143: ??? palace button
  • 0x201B4: ??? dungeon button
  • 0x2021D: ??? palace button
  • 0x22306: b/w dungeon
  • 0x231D2: b/w palace
  • 0x2929C: Red Orb credits

Maps

  • Tilesets are from the list above.
  • Maps are not compressed.
  • Colormaps: the lower 3 bits of each byte contain which 4-color group of the palette (0..7) to use for each tile.
    • I.e. bits 4..2 of the color index come from the colormap, while bits 1..0 come from the tile itself.
tileset offset map offset colormap offset width height contents
0x08810 0x08000 0x083E8 2 5*100 color dungeon tiles
0x09BF4 0x093E4 0x097CC 2 5*100 color palace tiles
0x101B8 0x10050 - 20 18 b/w title
0x113BF 0x1105F 0x11217 20 18 color title
0x1240E 0x122A6 - 20 18 b/w story frame
0x12BD6 0x12876 0x12A2E 20 18 color story frame
0x22306 0x21F1E - 2 5*100 b/w dungeon tiles
0x231D2 0x22DEA - 2 5*100 b/w palace tiles
0x2929C 0x28D5C 0x28FDC 20 32 Red Orb credits

Other

There is an unused sprite group with map offset = 0x3B444, tiles offset = 0x3B523. It seems to show a pile of bones becoming a guard!?

Offsets 0xA9DF..0xAA56 contain various bits that can appear in the status bar. To be used with the tileset at 0x0AA57.

At offset 0xB320 there is some data compressed using the same method as the levels. If forms a nice 32*32 array, and it seems to be used in room drawing.

Sound effects (GBC)

Sound effects are stored at offsets 0x3C000..0x3C0B3.

Format:

  • Read 1 byte:
    • 0x01 = fill sound registers 0xFF10..0xFF14 from the next 5 bytes (sound channel 1)
    • 0x02 = fill sound registers 0xFF16..0xFF19 from the next 4 bytes (sound channel 2)
    • 0x04 = fill sound registers 0xFF20..0xFF23 from the next 4 bytes (sound channel 4)
    • otherwise (usually 0x00) = end

The meaning of each register can be found in various Game Boy hardware specifications.

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

  • (Music?)