Monty Python & the Quest for the Holy Grail Formats Description
.bin (archive) format
The archive contains all resources for a whole scene (or screen of the game).
Archive starts with 88-byte header that contains 7LB\x01\x02
in the beginning and \x02\x00
at the end and just zeroes inside. This is followed by 138-byte block with some unknown data and then there are 32-bit little-endian absolute offsets and sizes for every resource category.
Resource type 0 is a table of contents for assets. This table of contents consists of 10-byte records with 16-bit asset type, 32-bit offset and 32-bit size. More about assets later.
Resource type 3 is some short (couple dozens of bytes) binary data with unknown purpose.
Resource type 4 is a list of strings containing mostly original file names and some internal variables and function names.
Resource type 5 seems to be a compiled scene script containing the actions and which levels to transit to.
Resource type 6 is palette with each colour stored as 32-bit word. The palette seems to be stored not for all colours and it also seems to be rotated. For most images formula (idx + 226) & 0xFF
gives proper results but it does not work for some rare images.
Resource type 7 is a list of strings containing exclusively internal commands and variables like xBeginAnimation
or <Dynamic0232>
.
Other resource types are either not present or not known.
Most of .bin
file is occupied by assets of different types. Here’s the list of known asset types:
- type 1 — images;
- type 2 — movies (actually stored as two consequent entries, one for movie data and one for index);
- type 4 — music in MIDI format;
- type 9 — audio;
- type 10 — some short binary data;
- type 11 — unknown;
- type 12 — some binary data (always 6 bytes long?);
- type 13 — some short binary data;
- type 14 — some binary data (always 944 bytes long?);
- type 15 — some usually short binary data;
- type 16 — some usually short binary data;
- type 17 — some usually short binary data;
- type 18 — some usually short binary data (always 20 bytes long?).
Image format
Images are stored in palettised format and can be compressed with either RLE or LZW.
Image header (in 16-bit words):
- header size (always 20);
- coded width;
- display width;
- height;
- compression (0x00/0x02 = LZW, 0x80 = RLE);
- some image offset?
- some image offset?
- looks like some global counter;
- always zero?
- always zero?
RLE compression is simple: read byte, if it’s in range 0x00-0x7F then repeat next byte that amount of times, if it’s in range 0x80-0xFE then read 0x7F-0x01 bytes from the stream, if it’s 0xFF then read actual copy length byte from the stream and copy that amount of bytes.
LZW compression stores data in chunks prefixed with 16-bit word. 0xE000
means stream end. Top 3 bits mean LZW index length (0 = no LZW, just copy data verbatim, 2 = 10 bits, 3 = 11 bits, 4 = 12 bits, the rest are forbidden), low 13 bits are compressed chunk length. LZW indices are stored MSB first, maximum code means end of stream.
Music format
Music is stored as MIDI events. File starts with 32-bit size field and unknown 16-bit word, the rest are events in 4-byte format that contain either 1-3 byte MIDI message or delay until the next event. Essentially you can treat it as 32-bit word and if top bit is unset you can use midiOutShortMsg()
to send it and if top bit is set then clear it and use the value for the delay until next message.
Audio format
Audio is compressed with IMA ADPCM top nibble first.
Header format:
- 32-bit file size
- 16-bit always zero?
- 16-bit always one?
- 32-bit unknown
WAVEFORMAT
for uncompressed audio
The rest is compressed audio data.
Movie data
Movie data takes two assets of type 2, the first one with all movie data concatenated together and the following one with 8-byte records for each frame: 16-bit type, 16-bit size and 32-bit offset. Type 0 means keyframe, type 1 means inter-frame (usually uses compression method 0x02 and colour zero means unchanged pixel, type 2 means IMA ADPCM compressed audio data without header.