Resource Management

Resource Management

The game uses two files for resource management:

  • KRONDOR.RMF acts as an index for the available resources
  • KRONDOR.001 contains 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.