Jet-Set Willy (C64) Room Format
Version 0.1: 23 December 2005
by John Elliott
Disclaimer: I do not guarantee this information to be correct. This is my best guess at what is going on inside Commodore 64 JSW, after wandering around inside it with a disassembler.
C64 JSW is a port of Spectrum JSW1, and for the most part uses similar data formats. The major differences that a player will notice are that ramps are drawn, and behave, as staircases; and that ropes look very blocky.
The rooms are stored in two separate chunks: Rooms 0-29 at 0B000h and Rooms 30-59 at 0E000h. When Willy enters a room, its definition is copied to 0840h.
0000 Room name, 32 bytes 0020 Room layout, 128 bytes, in the same format as Spectrum JSW1. 00A0 8x8 bitmaps for, respectively: 00A0 Water 00A8 Earth 00B0 Fire 00B8 Ramp 00C0 Conveyor 00C8 Item 00D0 Conveyor length / direction (top bit set for L, clear for R) 00D1 Conveyor Y 00D2 Conveyor X 00D3 Ramp Y 00D4 Ramp X 00D5 Ramp length / direction (top bit set for L, clear for R) 00D6 Border colour 00D7 Background colour 00D8 Water foreground colour 00D9 Earth foreground colour 00DA Ramp foreground colour 00DB Conveyor foreground colour 00DC Exit up 00DD Exit down 00DE Exit left 00DF Exit right 00E0 The number of the first guardian for the room. 00E1 Number of guardians in the room. 00E2 Rope flag -- 0FFh if there's a rope in the room. 00E3-00FF Appears to be unused.
As can be seen, the C64 room format allows nearly everything the Spectrum room format does; though air cannot have a bitmap, and cells can't have a different background colour from the room.
The behaviour of room 32 (Halfway Up The East Wall) is hardcoded; the game engine draws conveyor cells manually on top of the ramp.
The items table is at 22C3h, with four bytes per item:
- Room containing the item
- Item X-coordinate
- Item Y-coordinate
- Taken flag - 0 if item untaken
There are at most 80 items.
All guardians are stored in a table at 2443h. Each room uses a consecutive range of guardians from this table. Therefore it isn't possible to share guardians between rooms, unless the guardians in one are a subset of the guardians in the other. In the existing C64 JSW, guardians are not shared at all between rooms. There are 181 entries in the guardian table.
Each guardian table entry is 8 bytes, formed:
DB type ;Bit 7 set for horizontal, clear for vertical. ;Bit 6 set for left/up, clear for right/down. ;Bits 5-0 always 0. DB X ;Initial X, in character cells. DB Y ;Initial Y, in character cells. DB sprite ;Number of first sprite frame. DB bound2 ;Right/lower bound (in character cells) DB msk ;Sprite mask for animation DB vspd ;Vertical speed; seems to be ignored for horizontals DB bound1 ;Left/lower bound (in character cells)
- The game engine supports at most 7 guardians per room.
- Ropes and arrows aren't stored in the guardian table, though the game engine uses the same mechanism to draw them. A rope is actually implemented as three hardware sprites (top, middle and bottom) meaning that a room with a rope can have at most four other guardians, and none of them arrows. The rope sprites are scaled to double size, which explains the blocky appearance of ropes.
- The bathroom toilet uses the last guardian slot, so the bathroom can only have at most 6 guardians. The same applies for Maria in the Master Bedroom.
Guardian colours are stored in a separate table at 29EBh, with 8 bytes per room. The first byte gives Willy's colour; the remaining 7 give the colours of the guardians.
The sprite bitmaps start at 4000h. They are stored in the C64 hardware format; each sprite is 64 bytes long, with the first 63 bytes giving a 24x21 image and the last byte spare. There are 175 sprites in the table; the last 5 are two arrows and three rope segments. A second set of sprites, giving all the different positions of the rope, is at 8100h, with 102 sprites corresponding to 34 possible positions.
Sprite 0 is the foot, Sprite 1 is the barrel, Sprites 2-5 are Maria, and so on.
The 16 arrows in the game are stored in a table at 2403h, with four bytes per entry:
- Room containing arrow. Top bit is set if arrow is currently visible in the room.
- Countdown until arrow appears. The firing sound occurs at count=10; the arrow itself appears at count=0.
- Arrow X-coordinate (low 7 bits) and direction (high bit). If the high bit is set, the arrow is heading left.
- Arrow Y-coordinate, characters.
A room with arrows can only have at most five guardians, because when visible the arrow uses the slot for the sixth. For the same reason, only one arrow can be onscreen at a time.
The font is at 7800h, and has 128 characters, making it 1k long. The characters are, in order:
- 00h: Space
- 01h-1Ah: Capital A-Z
- 1Bh: [
- 1Ch: £ (Pound sign)
- 1Dh: ]
- 1Eh: ↑ (Up arrow)
- 1Fh: ← (Left arrow)
- 20h-26h: Seven cell graphics for the current room: Air, Water, Earth, Fire, Ramp, Conveyor and Item.
- 27h-3Ah: As ASCII, ' to :
- 3Bh-3Eh: A picture of Willy for the lives display.
- 3Fh: Question mark.
- 40h-7Fh: Various line graphic characters.