Resource Management
The game uses two files for resource management:
KRONDOR.RMFacts as an index for the available resourcesKRONDOR.001contains the actual resources
Presumably the disk version would use multiple KRONDOR.00X files, but I have not been able to verify this, since I only have access to the GOG version which seems to be based on the CD-ROM version which had the archive as one file.
KRONDOR.RMF
The RMF file contains a header and then a number of entries corresponding to the number of resources in KRONDOR.001.
The header layout is
| offset | type | value | description |
|---|---|---|---|
| 0x00 | uint32 | 1 | unknown, must be 1 |
| 0x04 | uint16 | 4 | unknown, discarded |
| 0x06 | string | krondor.001 | resource file reference |
| 0x13 | uint16 | 1768 | entries count |
The layout of each entry is:
| offset | type | description |
|---|---|---|
| 0x00 | uint32 | hash key |
| 0x04 | uint32 | offset in resource file (krondor.001) |
For a full list of content in KRONDOR.RMF see https://krondor.ubik-shakespeare.com/krondor-rmf/
KRONDOR.001
The layout of KRONDOR.001 is:
| offset | type | description |
|---|---|---|
| 0 | string (null terminated) | Fixed 13 characters standard DOS 12 character file name + null terminator. i.e. HEADS.BMX\0 |
| 13 | uint32 | data size |
| 17 | raw data | the actual data (may be compressed) |
The full list of content can be found here: https://krondor.ubik-shakespeare.com/krondor-001-archive-contents/
resource_fopen
When the game requires access to a resource, it will simply reference the file, e.g. INT_DYN.BMP into a function we have decided to call resource_fopen which functions much like the standard library fopen except that it abstracts the details on how to load the file and decompress it and simply returns a pointer to the data, like fopen would if the file were accessed directly.
Another feature of this function is that it will first look for the unpacked file in the folder and use that before looking in the packed file.
Compression
The KRONDOR.001 archive stores resource data in raw form — the archive format itself has no compression layer. Instead, compression is handled at the individual file format level. For
example, BMX image files contain a compression type field in their own header that indicates how the pixel data is compressed.
Three compression schemes are used across the game's file formats:
- Type 0 — LZW (Lempel-Ziv-Welch): Dictionary-based compression with a 5-byte header (02 + 4-byte decompressed size).
- Type 1 — LZSS (Lempel-Ziv-Storer-Szymanski): A custom variant using a control byte processed LSB-to-MSB. A set bit means one literal byte follows; a clear bit means a 2-byte
back-reference offset plus a 1-byte length (actual length = stored value + 5). - Type 2 — RLE (Run-Length Encoding): Byte-oriented. If the high bit of the control byte is set, repeat the next byte (control & 0x7F) times. Otherwise, copy the next (control) literal
bytes.
The compression type is encoded as a uint16 field within each file format's header (e.g., at offset 0x02 in a BMX file, after the 0x1066 magic number). A generic decompress() function
dispatches to the appropriate algorithm based on this value.