Difference between revisions of "SNES format"

From Princed Wiki
Jump to: navigation, search
(Created page with "This file describes the format of data in PoP1 for SNES. This document is far from complete. I will continuously add information to it. == The resource tables == There are ...")
 
Line 11: Line 11:
 
! Address !! Count !! Contents
 
! Address !! Count !! Contents
 
|-
 
|-
| 0x20000 || 91 or 92 || Levels, Graphics
+
| 0x20000 || 91 or 92 || Levels, Graphics
 
|-
 
|-
 
| 0x78000 || 1485 || Sprites
 
| 0x78000 || 1485 || Sprites
Line 24: Line 24:
  
 
e.g. 0x14 0x81 0x04 means offset=0x8114, segment=0x04, address=0x04*0x8000+0x0114=0x20114
 
e.g. 0x14 0x81 0x04 means offset=0x8114, segment=0x04, address=0x04*0x8000+0x0114=0x20114
 +
 
Note that some ROM images have a 0x200 byte header.
 
Note that some ROM images have a 0x200 byte header.
  
Line 31: Line 32:
  
 
<pre>
 
<pre>
00: menu/intro font
+
00: menu/intro font tiles (256 uncompressed 2bpp tiles)
01..40: the 10 enviroments
+
01..40: the 10 enviroments (graphics for level types)
 
(each type has four resources: background, blocks background, blocks foreground, palette)
 
(each type has four resources: background, blocks background, blocks foreground, palette)
 
0: 01,02,03,04: blue dungeon
 
0: 01,02,03,04: blue dungeon
Line 42: Line 43:
 
6: 25,26,27,28: red palace
 
6: 25,26,27,28: red palace
 
7: 29,30,31,32: level 20
 
7: 29,30,31,32: level 20
8: 33,34,35,36: jaffar
+
8: 33,34,35,36: Jaffar
 
9: 37,38,39,40: demo red palace
 
9: 37,38,39,40: demo red palace
41..67: the 27 levels: level 1-20, jaffar, demo, training 1-5
+
41..67: the 27 levels: level 1-20, Jaffar, demo, training 1-5
68: sprite palettes
+
41..60: level 1-20
69: screen palettes
+
61: Jaffar's level
70: hitpoint tiles
+
62: demo level
 +
63..67: training 1-5
 +
68: sprite palettes (27*16 colors)
 +
69: screen palettes (33*16 colors)
 +
70: hitpoint tiles (4 uncompressed 4bpp tiles)
 
71: princess room screen
 
71: princess room screen
 
72: princess room arches screen
 
72: princess room arches screen
73: torch tiles
+
73: torch tiles (16 uncompressed 4bpp tiles)
74: ending font
+
74: ending font (stored in the same format as level background graphics)
 
75: Masiya logo screen
 
75: Masiya logo screen
 
76: stars screen (big)
 
76: stars screen (big)
Line 90: Line 95:
  
 
(needs further description)
 
(needs further description)
 +
 +
=== Compressions used for tiles ===
 +
 +
(needs description)
  
 
=== Palettes ===
 
=== Palettes ===
Line 99: Line 108:
 
=== Environments ===
 
=== Environments ===
  
(needs description)
+
{| class="wikitable"
 +
! type !! block width !! block height !! bits per pixel !! number of blocks !! number of tiles !! B in block mapping !! B in tile mapping
 +
|-
 +
| 1. background || 3 || 8 || 2 || 256 || 512 || 8 || 9
 +
|-
 +
| 2. blocks background || 6 || 8 || 4 || 256 || 256 || 8 || 8
 +
|-
 +
| 3. blocks foreground || 3 || 8 || 4 || 256 || 256 || 8 || 8
 +
|}
 +
 
 +
<pre>
 +
2 byte: number of stored blocks
 +
?*2 byte: block mapping
 +
bit 15: 1->incrementing sequence , 0->repeat
 +
1->
 +
middle (15-B) bits: length (0 means 2^(15-B))
 +
bottom B bits: starting value
 +
0->
 +
bit 14: 0->length=1 , 1->length=given
 +
middle (14-B) bits: length (0 means 2^(14-B))
 +
bottom B bits: value to repeat
 +
repeat this until you don't have enough values in the output
 +
compressed blocks
 +
for each tile
 +
1 or 2 byte: data
 +
if layer 1 or 3: (big endian)
 +
##0##### ######## -> raw copy (swap the bytes)
 +
001##### -> repeat next two bytes, # times, MUST NOT cross block boundary
 +
011##### -> repeat next two bytes, # times, with increase, MUST NOT cross block boundary
 +
1#1##### -> repeat tile # of current block
 +
if layer 2: (big endian)
 +
##0##### ######## -> raw copy (swap the bytes)
 +
001##### ######## -> repeat next two bytes, # times, MUST NOT cross block boundary
 +
011##### ######## -> repeat next two bytes, # times, with increase, MUST NOT cross block boundary
 +
1#1##### -> repeat tile # of current block
 +
if screen: (little endian)
 +
######## ##0##### -> raw copy
 +
######## 001##### -> repeat next two bytes, # times
 +
######## 011##### -> repeat next two bytes, # times, with increase
 +
2 byte: number of stored tiles
 +
?*2 byte: tile mapping
 +
similar format to block mapping
 +
compressed tiles
 +
for each tile
 +
1 byte: compression mode
 +
? byte: data
 +
if layer 2: in-front-of masks
 +
for each tile:
 +
1 byte: mask mode
 +
01->use default mask (all zeroes)
 +
00->use the following mask
 +
8 bytes: mask
 +
</pre>
 +
 
 +
(needs better description)
  
 
=== Levels ===
 
=== Levels ===
Line 134: Line 197:
 
Parts of the level:
 
Parts of the level:
  
<pre>
+
{| class="wikitable"
Size Contents
+
|-
--------------
+
! Address !! Size !! Contents
720   background layer
+
|-
720   blocks layer
+
| 0x000 || 720 || background layer
720   modifiers layer
+
|-
256   block layer 1 graphics
+
| 0x2D0 || 720 || blocks layer
256   block layer 2 graphics
+
|-
256   block objects
+
| 0x5A0 || 720 || modifiers layer
256   block flags
+
|-
244   room links, starting position, guards
+
| 0x870 || 256 || block layer 1 graphics
256   door events 1
+
|-
256   door events 2
+
| 0x970 || 256 || block layer 2 graphics
</pre>
+
|-
 +
| 0xA70 || 256 || block objects
 +
|-
 +
| 0xB70 || 256 || block flags and background animation info
 +
|-
 +
| 0xC70 || 244 || room links, starting position, guards
 +
|-
 +
| 0xD64 || 256 || door events 1
 +
|-
 +
| 0xE64 || 256 || door events 2
 +
|}
 +
 
 +
Total size = 3940 bytes = 0xF64 bytes
  
 
'''Background layer'''
 
'''Background layer'''
Line 189: Line 264:
 
One byte for each block type. Selects which object should be used for this block type.
 
One byte for each block type. Selects which object should be used for this block type.
  
<pre>
+
{| class="wikitable"
value object type
+
! value !! object type !! notes
---------------------
+
|-
0x00 (none)
+
| 0x00 || (none)
0x01 (unused)
+
|-
0x02 loose floor
+
| 0x01 || (unused)
0x03 (unused)
+
|-
0x04 open button
+
| 0x02 || loose floor || The modifier selects the animation frame to be displayed. It should be zero.
0x05 close button
+
|-
0x06 door
+
| 0x03 || (unused)
0x07 leveldoor end
+
|-
0x08 mirror
+
| 0x04 || open button || The modifier selects the door event to be triggered.
0x09 skeleton
+
|-
0x0A sword
+
| 0x05 || close button || The modifier selects the door event to be triggered.
0x0B torch
+
|-
0x0C chomper
+
| 0x06 || door || The modifier specifies how much the door is open, in 1/4 pixels.
0x0D guillotine
+
|-
0x0E spike
+
| 0x07 || leveldoor end
0x0F (unused)
+
|-
0x10 crusher
+
| 0x08 || mirror
0x11 (unused)
+
|-
0x12 heal potion
+
| 0x09 || skeleton
0x13 life potion
+
|-
0x14 hurt potion
+
| 0x0A || sword
0x15 upside down potion
+
|-
0x16 slow fall potion
+
| 0x0B || torch || There are four torch objects. They differ in the position of the flames.
0x17 debris
+
|-
0x18 door top
+
| 0x0C || chomper || The modifier selects the animation frame to be displayed. It should be zero.
0x19 fire
+
|-
0x1A potion of warp
+
| 0x0D || guillotine || The modifier selects the animation frame to be displayed. It should be zero.
0x1B down only
+
|-
0x1C kill potion
+
| 0x0E || spike || The modifier selects the animation frame to be displayed. It should be zero.
0x1D torch
+
|-
0x1E spinning log
+
| 0x0F || (unused)
0x1F (unused)
+
|-
0x20 stars
+
| 0x10 || crusher || The modifier selects the animation frame to be displayed. It should be zero.
0x21 torch
+
|-
0x22 torch
+
| 0x11 || (unused)
0x23 teleport
+
|-
0x24 leveldoor begin
+
| 0x12 || heal potion
0x25 (unused)
+
|-
0x26 (unused)
+
| 0x13 || life potion
0x27 lava
+
|-
0x28 skeleton continue
+
| 0x14 || hurt potion
0x29 skull?
+
|-
0x2A conveyor belt >>>
+
| 0x15 || upside down potion
0x2B conveyor belt <<<
+
|-
</pre>
+
| 0x16 || slow fall potion
 +
|-
 +
| 0x17 || debris
 +
|-
 +
| 0x18 || door top
 +
|-
 +
| 0x19 || fire
 +
|-
 +
| 0x1A || potion of warp || The potion of warp will take the player to room 17, tile 11, turned left.
 +
|-
 +
| 0x1B || down only || If added to a block that has floor, the player can fall through it, but can't jump/climb up through it. The modifier selects the animation frame to be displayed. It should be zero. If the modifier is in the 1..4 range, the transparent floor (that you can see after the shadow fight) will appear.
 +
|-
 +
| 0x1C || kill potion
 +
|-
 +
| 0x1D || torch || There are four torch objects. They differ in the position of the flames.
 +
|-
 +
| 0x1E || spinning log || The modifier selects the animation frame to be displayed. It should be zero.
 +
|-
 +
| 0x1F || (unused)
 +
|-
 +
| 0x20 || stars || The modifier selects the animation frame to be displayed. It should be zero.
 +
|-
 +
| 0x21 || torch || There are four torch objects. They differ in the position of the flames.
 +
|-
 +
| 0x22 || torch || There are four torch objects. They differ in the position of the flames.
 +
|-
 +
| 0x23 || teleport || Entering a teleport will take to the other teleport with the same modifier.
 +
|-
 +
| 0x24 || leveldoor begin
 +
|-
 +
| 0x25 || (unused)
 +
|-
 +
| 0x26 || (unused)
 +
|-
 +
| 0x27 || lava || Lava: falling onto this tile from any height will kill the prince.
 +
|-
 +
| 0x28 || skeleton continue || If a skeleton falls into this room then it will appear here.
 +
|-
 +
| 0x29 || skull? || Found on Level 19, in those rooms that have a skull.
 +
|-
 +
| 0x2A || conveyor belt >>>
 +
|-
 +
| 0x2B || conveyor belt <<<
 +
|}
  
Notes:
+
'''Block flags and background animation info'''
  
There are four torch objects. They differ in the position of the flames.
+
One byte for each block type / background block.
 
 
The potion of warp will take the player to room 17, tile 11, turned left.
 
 
 
"skeleton continue" means that if a skeleton falls into this room then it will appear here.
 
 
 
"down only": if added to a block that has floor, the player can fall through it, but can't jump/climb up through it.
 
 
 
If the modifier is in the 1..4 range, the transparent floor you can see after the shadow fight will appear.
 
 
 
Lava: falling onto this tile from any height will kill the prince.
 
 
 
Meaning of the modifier for each object:
 
 
 
For the loose floor, chomper, guillotine, spike, crusher, down only, spinning log, stars objects,
 
 
 
the modifier selects the animation frame to be displayed. It should be zero.
 
 
 
For the open and close buttons, the modifier selects the door event to be triggered.
 
 
 
For doors, the modifier specifies how much the door is open, in 1/4 pixels.
 
 
 
Teleports: Entering a teleport will take to the other teleport with the same modifier.
 
 
 
'''Block flags'''
 
 
 
One byte for each block type. Determines if the current block type is a floor or a wall.
 
  
 +
Bits 0-1 determine if the current block type is a floor or a wall.
 
If bit 0 is set then this block type is a floor.
 
If bit 0 is set then this block type is a floor.
 
 
If bit 1 is set then this block type is a wall.
 
If bit 1 is set then this block type is a wall.
  
The meaning of other bits (if any) is unknown.
+
Bits 2-7 determine if the current background block is part of an animation group, and if yes, then which one.
 +
(needs further description)
  
 
'''Room links, starting position, guards'''
 
'''Room links, starting position, guards'''
  
<pre>
+
{| class="wikitable"
Size Contents
+
! Address !! Size !! Contents
--------------
+
|-
24*4 Room links
+
| 0xC70 || 24*4 || Room links
1     Starting room
+
|-
1     Starting position in room
+
| 0xCD0 || 1 || Starting room
1     Starting direction
+
|-
1     unused
+
| 0xCD1 || 1 || Starting position in room
24   Guard position in room
+
|-
24   Guard type and direction
+
| 0xCD2 || 1 || Starting direction
4*24 unknown
+
|-
</pre>
+
| 0xCD3 || 1 || unused
 +
|-
 +
| 0xCD4 || 24 || Guard position in room
 +
|-
 +
| 0xCEC || 24 || Guard type and direction
 +
|-
 +
| 0xD04 || 4*24 || unknown
 +
|}
  
Room links: For every room, the room to the left, right, above and below the current room is given, in this order.
+
'''Room links''': For every room, the room to the left, right, above and below the current room is given, in this order.
  
 
The rooms are numbered 0..23.
 
The rooms are numbered 0..23.
Line 301: Line 401:
 
Note: rooms are numbered 0..23, which is different from the DOS version.
 
Note: rooms are numbered 0..23, which is different from the DOS version.
  
Starting room: The room the player starts in. Can be 0..23.
+
'''Starting room''': The room the player starts in. Can be 0..23.
  
Starting position in room: row*10+column. (0..29)
+
'''Starting position in room''': row*10+column. (0..29)
  
Starting direction: 0xFF=left, 0x00=right.
+
'''Starting direction''': 0xFF=left, 0x00=right.
  
Guard position in room: row*10+column (0..29), or 0xFF if there is no guard in this room.
+
'''Guard position in room''': row*10+column (0..29), or 0xFF if there is no guard in this room.
  
Guard type and direction: The bottom 7 bits specify the guard type, the top bit specifes the direction. 1=left, 0=right.
+
'''Guard type and direction''': The bottom 7 bits specify the guard type, the top bit specifes the direction: 1=left, 0=right.
  
<pre>
+
{| class="wikitable"
value guard type
+
! value !! guard type
---------------------
+
|-
0x02 dead purple
+
| 0x02 || dead purple
0x03 skeleton
+
|-
0x04 brown skeleton
+
| 0x03 || skeleton
0x05 golden skeleton
+
|-
0x06 girl
+
| 0x04 || brown skeleton
0x07 fat
+
|-
0x08 shadow
+
| 0x05 || golden skeleton
0x09 green
+
|-
0x0A greenish blue
+
| 0x06 || girl
0x0B blue
+
|-
0x0C red
+
| 0x07 || fat
0x0D purple
+
|-
0x0E blueface
+
| 0x08 || shadow
0x0F red knight
+
|-
0x10 blue knight
+
| 0x09 || green
0x11 monster
+
|-
0x12 Jaffar
+
| 0x0A || greenish blue
0x13 dead
+
|-
</pre>
+
| 0x0B || blue
 +
|-
 +
| 0x0C || red
 +
|-
 +
| 0x0D || purple
 +
|-
 +
| 0x0E || blueface
 +
|-
 +
| 0x0F || red knight
 +
|-
 +
| 0x10 || blue knight
 +
|-
 +
| 0x11 || monster
 +
|-
 +
| 0x12 || Jaffar
 +
|-
 +
| 0x13 || dead
 +
|}
  
 
Other values may display garbage or may even hang the game.
 
Other values may display garbage or may even hang the game.
Line 339: Line 456:
  
 
<pre>
 
<pre>
(same format as in DOS version)
+
(same format as in DOS version, except that rooms are numbered differently)
 
-------------------------  7  6  5  4  3  2  1  0 <-bits
 
-------------------------  7  6  5  4  3  2  1  0 <-bits
 
byte from door events 1 | NX R1 R0 L4 L3 L2 L1 L0
 
byte from door events 1 | NX R1 R0 L4 L3 L2 L1 L0
Line 360: Line 477:
  
 
big screen=64*56 tiles
 
big screen=64*56 tiles
 +
 +
<pre>
 +
compressed map
 +
similar format as compressed blocks in environments
 +
2 byte: number of stored tiles
 +
compressed tiles (4bpp)
 +
same format as compressed tiles in environments
 +
</pre>
 +
 +
(needs better description)
  
 
=== Sprites ===
 
=== Sprites ===
Line 365: Line 492:
 
Sprites are compressed.
 
Sprites are compressed.
  
(needs further description)
+
<pre>
 +
read 1 byte: width in pixels - 1
 +
read 1 byte: height in pixels - 1
 +
read 1 byte: size in tiles
 +
top 4 bits: height in 16 pixel units
 +
bottom 4 bits: width in 16 pixel units
 +
for each two 8*8 tiles:
 +
read 1 byte: flags
 +
for P = 0 to 7: (plane) (the 8 planes are actually 4 planes of 2 tiles)
 +
create a 64-byte array, representing two tiles; fill it with zeroes
 +
if bit P is set in flags:
 +
read 1 byte: mask
 +
if mask = 255 then:
 +
read 1 byte: mask
 +
read 1 byte: value
 +
for B = 0 to 7: (byte)
 +
if bit B of mask is zero:
 +
put value into byte B of plane P (in the array)
 +
end if
 +
end for
 +
else:
 +
for B = 0 to 7: (byte)
 +
if bit B of mask is zero:
 +
read 1 byte: value
 +
put value into byte B of plane P (in the array)
 +
end if
 +
end for
 +
endif
 +
end if
 +
append the array to the output
 +
end for
 +
end for
 +
</pre>
 +
 
 +
(needs better description)
 +
 
 +
=== Background sprites ===
 +
 
 +
(needs description)
  
 
=== Musics ===
 
=== Musics ===
  
 
(needs description)
 
(needs description)

Revision as of 10:18, 24 May 2013

This file describes the format of data in PoP1 for SNES.

This document is far from complete. I will continuously add information to it.

The resource tables

There are 3 resource tables in the ROM, at the following addresses:

Address Count Contents
0x20000 91 or 92 Levels, Graphics
0x78000 1485 Sprites
0xE8000 36 or 37 Sounds, Musics

A resource table is an array of addresses. Each address is in the following form: A word telling the offset and a byte telling the segment (also called "bank"). Segments are in the range 0x00..0x1F, offsets are in the range 0x8000..0xFFFF. address=segment*0x8000+offset-0x8000

e.g. 0x14 0x81 0x04 means offset=0x8114, segment=0x04, address=0x04*0x8000+0x0114=0x20114

Note that some ROM images have a 0x200 byte header.

The size or type of the resource is not stored.

Contents of the first resource table: (0x20000)

00: menu/intro font tiles (256 uncompressed 2bpp tiles)
01..40: the 10 enviroments (graphics for level types)
	(each type has four resources: background, blocks background, blocks foreground, palette)
	0: 01,02,03,04: blue dungeon
	1: 05,06,07,08: pink palace
	2: 09,10,11,12: grey palace
	3: 13,14,15,16: red dungeon
	4: 17,18,19,20: green palace
	5: 21,22,23,24: brown dungeon
	6: 25,26,27,28: red palace
	7: 29,30,31,32: level 20
	8: 33,34,35,36: Jaffar
	9: 37,38,39,40: demo red palace
41..67: the 27 levels: level 1-20, Jaffar, demo, training 1-5
	41..60: level 1-20
	61: Jaffar's level
	62: demo level
	63..67: training 1-5
68: sprite palettes (27*16 colors)
69: screen palettes (33*16 colors)
70: hitpoint tiles (4 uncompressed 4bpp tiles)
71: princess room screen
72: princess room arches screen
73: torch tiles (16 uncompressed 4bpp tiles)
74: ending font (stored in the same format as level background graphics)
75: Masiya logo screen
76: stars screen (big)
77: torture screen (big)
78: garden screen (big)
79: title screen
80: title things screen
81: pattern screen
82: game name screen
83: main menu background screen
84: where Jafar walks screen (big)
85: ending: prince at sultan screen
86: ending: prince and princess at window with people screen
87: ending: prince and princess at window with sundown screen
88: ending: sundown screen
89: ending: sundown 2 screen
90: Japanese characters screen
91: Konami logo screen (Europe/USA versions only)

Contents of the second resource table: (0x78000)

0000..1248: regular sprites

1249..1394: sprites that are put into the background (traps, buttons, doors), 48*64 pixels

1395..1484: masks, 48*64 pixels

Contents of the third resource table: (0xE8000)

(needs description)

Resource formats

Tiles

The SNES uses planar tiles, which can be 2- or 4-bit.

(needs further description)

Compressions used for tiles

(needs description)

Palettes

The SNES uses 5:5:5 RGB palettes, each entry is a word in the following format:

0bbbbbgggggrrrrr

Environments

type block width block height bits per pixel number of blocks number of tiles B in block mapping B in tile mapping
1. background 3 8 2 256 512 8 9
2. blocks background 6 8 4 256 256 8 8
3. blocks foreground 3 8 4 256 256 8 8
2 byte: number of stored blocks
?*2 byte: block mapping
	bit 15: 1->incrementing sequence , 0->repeat
	1->
		middle (15-B) bits: length (0 means 2^(15-B))
		bottom B bits: starting value
	0->
		bit 14: 0->length=1 , 1->length=given
		middle (14-B) bits: length (0 means 2^(14-B))
		bottom B bits: value to repeat
	repeat this until you don't have enough values in the output
compressed blocks
	for each tile
		1 or 2 byte: data
		if layer 1 or 3: (big endian)
			##0##### ######## -> raw copy (swap the bytes)
			001##### -> repeat next two bytes, # times, MUST NOT cross block boundary
			011##### -> repeat next two bytes, # times, with increase, MUST NOT cross block boundary
			1#1##### -> repeat tile # of current block
		if layer 2: (big endian)
			##0##### ######## -> raw copy (swap the bytes)
			001##### ######## -> repeat next two bytes, # times, MUST NOT cross block boundary
			011##### ######## -> repeat next two bytes, # times, with increase, MUST NOT cross block boundary
			1#1##### -> repeat tile # of current block
		if screen: (little endian)
			######## ##0##### -> raw copy
			######## 001##### -> repeat next two bytes, # times
			######## 011##### -> repeat next two bytes, # times, with increase
2 byte: number of stored tiles
?*2 byte: tile mapping
	similar format to block mapping
compressed tiles
	for each tile
		1 byte: compression mode
		? byte: data
if layer 2: in-front-of masks
	for each tile:
		1 byte: mask mode
		01->use default mask (all zeroes)
		00->use the following mask
			8 bytes: mask

(needs better description)

Levels

Levels are compressed.

I'll try to explain the algorithm:

procedure decompress_a_part(input:stream of bytes,output:stream of bytes,LEN:integer)
 clear output
 repeat while you don't have LEN bytes in the output:
  read a byte to X
  if X>=128 then
   copy X-128 bytes from input to output
  else
   read a byte to Y, if Y=0 then Y:=256
   if X=1: read a byte to D, write D to output Y times
   if X=2: read a byte to D, write D,D+1,D+2,... to output, Y bytes total
   if X=3: read a byte to D, write D,D-1,D-2,... to output, Y bytes total
   if X=4: read a byte to A, copy Y bytes from the A-th byte of the output to after the end of the output
   if X=5: read a 2-byte integer to A, copy Y bytes from the A-th byte of the output to after the end of the output
   // note that the source and destination may overlap in the above two cases
   otherwise: error
  end if
 end repeat
end procedure

You have to call the above procedure with these values of LEN, and concatenate the outputs: 720,720,720,256,256,256,256,244,256,256
Each input part begins directly after the end of the previous.
Calling with LEN=3940 at once won't work, because at the X=4 and X=5 cases, A is counted from the beginning of the current part, not the beginning of the whole level data.

Parts of the level:

Address Size Contents
0x000 720 background layer
0x2D0 720 blocks layer
0x5A0 720 modifiers layer
0x870 256 block layer 1 graphics
0x970 256 block layer 2 graphics
0xA70 256 block objects
0xB70 256 block flags and background animation info
0xC70 244 room links, starting position, guards
0xD64 256 door events 1
0xE64 256 door events 2

Total size = 3940 bytes = 0xF64 bytes

Background layer

One byte for each tile. Selects which background graphics should be used for this tile.

Blocks layer

One byte for each tile. Selects which block should be used for this tile.

Informations about blocks are found in the four parts whose names begin with "block".

Some blocks are used for special purposes:

Block 255 is used for nonexistent rooms. (Room link=255) It is usually a wall.

Block 254 is used for buttons that are permanently triggered by a dead guard or loose floor. It is usually a floor.

Reason: Button blocks don't have floor graphics, because the button object draws it for them.

If a button is triggered permanently, it needs to be changed into a regular floor, which does need floor graphics.

The only way this can be done is placing a different block into the place of the button.

Modifiers layer

One byte for each tile. Selects which modifier should be used for this tile.

Its meaning depends on the object used.

Block layer 1 graphics

One byte for each block type. Selects which background graphics should be used for this block type.

Block layer 2 graphics

One byte for each block type. Selects which foreground graphics should be used for this block type.

Block objects

One byte for each block type. Selects which object should be used for this block type.

value object type notes
0x00 (none)
0x01 (unused)
0x02 loose floor The modifier selects the animation frame to be displayed. It should be zero.
0x03 (unused)
0x04 open button The modifier selects the door event to be triggered.
0x05 close button The modifier selects the door event to be triggered.
0x06 door The modifier specifies how much the door is open, in 1/4 pixels.
0x07 leveldoor end
0x08 mirror
0x09 skeleton
0x0A sword
0x0B torch There are four torch objects. They differ in the position of the flames.
0x0C chomper The modifier selects the animation frame to be displayed. It should be zero.
0x0D guillotine The modifier selects the animation frame to be displayed. It should be zero.
0x0E spike The modifier selects the animation frame to be displayed. It should be zero.
0x0F (unused)
0x10 crusher The modifier selects the animation frame to be displayed. It should be zero.
0x11 (unused)
0x12 heal potion
0x13 life potion
0x14 hurt potion
0x15 upside down potion
0x16 slow fall potion
0x17 debris
0x18 door top
0x19 fire
0x1A potion of warp The potion of warp will take the player to room 17, tile 11, turned left.
0x1B down only If added to a block that has floor, the player can fall through it, but can't jump/climb up through it. The modifier selects the animation frame to be displayed. It should be zero. If the modifier is in the 1..4 range, the transparent floor (that you can see after the shadow fight) will appear.
0x1C kill potion
0x1D torch There are four torch objects. They differ in the position of the flames.
0x1E spinning log The modifier selects the animation frame to be displayed. It should be zero.
0x1F (unused)
0x20 stars The modifier selects the animation frame to be displayed. It should be zero.
0x21 torch There are four torch objects. They differ in the position of the flames.
0x22 torch There are four torch objects. They differ in the position of the flames.
0x23 teleport Entering a teleport will take to the other teleport with the same modifier.
0x24 leveldoor begin
0x25 (unused)
0x26 (unused)
0x27 lava Lava: falling onto this tile from any height will kill the prince.
0x28 skeleton continue If a skeleton falls into this room then it will appear here.
0x29 skull? Found on Level 19, in those rooms that have a skull.
0x2A conveyor belt >>>
0x2B conveyor belt <<<

Block flags and background animation info

One byte for each block type / background block.

Bits 0-1 determine if the current block type is a floor or a wall. If bit 0 is set then this block type is a floor. If bit 1 is set then this block type is a wall.

Bits 2-7 determine if the current background block is part of an animation group, and if yes, then which one. (needs further description)

Room links, starting position, guards

Address Size Contents
0xC70 24*4 Room links
0xCD0 1 Starting room
0xCD1 1 Starting position in room
0xCD2 1 Starting direction
0xCD3 1 unused
0xCD4 24 Guard position in room
0xCEC 24 Guard type and direction
0xD04 4*24 unknown

Room links: For every room, the room to the left, right, above and below the current room is given, in this order.

The rooms are numbered 0..23.

255 means that no room is in the given direction.

For the "above" link, 254 means the same, plus that the 4-pixel part of the room above (which would have walls) is not shown.

This is used for special "outdoor" rooms.

Note: rooms are numbered 0..23, which is different from the DOS version.

Starting room: The room the player starts in. Can be 0..23.

Starting position in room: row*10+column. (0..29)

Starting direction: 0xFF=left, 0x00=right.

Guard position in room: row*10+column (0..29), or 0xFF if there is no guard in this room.

Guard type and direction: The bottom 7 bits specify the guard type, the top bit specifes the direction: 1=left, 0=right.

value guard type
0x02 dead purple
0x03 skeleton
0x04 brown skeleton
0x05 golden skeleton
0x06 girl
0x07 fat
0x08 shadow
0x09 green
0x0A greenish blue
0x0B blue
0x0C red
0x0D purple
0x0E blueface
0x0F red knight
0x10 blue knight
0x11 monster
0x12 Jaffar
0x13 dead

Other values may display garbage or may even hang the game.

Door events 1 and 2

(same format as in DOS version, except that rooms are numbered differently)
-------------------------  7  6  5  4  3  2  1  0 <-bits
byte from door events 1 | NX R1 R0 L4 L3 L2 L1 L0
byte from door events 2 | R4 R3 R2  0  0  0  0  0

R4 R3 R2 R1 R0: The number of the room. (0..23)

L4 L3 L2 L1 L0: The location in the room. (0..29)

NX: If zero then trigger next door event, if one then don't.

Screens

Screens are compressed.

(needs further description)

screen=32*28 tiles

big screen=64*56 tiles

compressed map
	similar format as compressed blocks in environments
2 byte: number of stored tiles
compressed tiles (4bpp)
	same format as compressed tiles in environments

(needs better description)

Sprites

Sprites are compressed.

read 1 byte: width in pixels - 1
read 1 byte: height in pixels - 1
read 1 byte: size in tiles
	top 4 bits: height in 16 pixel units
	bottom 4 bits: width in 16 pixel units
for each two 8*8 tiles:
	read 1 byte: flags
	for P = 0 to 7: (plane) (the 8 planes are actually 4 planes of 2 tiles)
		create a 64-byte array, representing two tiles; fill it with zeroes
		if bit P is set in flags:
			read 1 byte: mask
			if mask = 255 then:
				read 1 byte: mask
				read 1 byte: value
				for B = 0 to 7: (byte)
					if bit B of mask is zero:
						put value into byte B of plane P (in the array)
					end if
				end for
			else:
				for B = 0 to 7: (byte)
					if bit B of mask is zero:
						read 1 byte: value
						put value into byte B of plane P (in the array)
					end if
				end for
			endif
		end if
		append the array to the output
	end for
end for

(needs better description)

Background sprites

(needs description)

Musics

(needs description)