SPK is the archive format used for storing most of the game resources. There are four known archives: CDA.SPK
which seems to contain speech (and lip synchronisation data), CDN.SPK
probably with scene-specific data, HDN.SPK
contains game music plus world map and some other files, HDNW.SPK
contains mostly 3D models and animations (plus some QGF files).
The archive starts with the resource index: resource category table and per-resource type entries table. All values are little-endian.
Resource category table has magic word 0xFFAACCEE
followed by the table size (including the 16-byte header, should be 144), number of entries (should be 16) and flags (seems to be always 0x200
or 0x10200
). The table contents are pairs of 32-bit words denoting the resource type and offset to its own table.
Resource entries table has magic word 0xFFEEFFEE
followed by the table size (including the 16-byte header, should be 144), number of entries (should be 16) and flags (always 0x404643
?). Depending on resource category table flags there can be two formats: when flags are 0x0001xxxx
the contents are triplets of 32-bit words for resource ID, its offset and size; when flags are 0x0000xxxx
the contents are triplets of zero-terminated filename and 32-bit words for its offset and size.
After the resource tables the actual data in hacked ZIP format follows. The format is the same except for the header signatures: local file header uses 0x05034b50
instead of 0x04034b50
, central directory record signature is 0x03014b50
instead of 0x02014b50
, end of central directory record signature is 0x07054b50
instead of 0x06054b50
(i.e. just high byte incremented in all cases). All entries should be stored uncompressed.
Back in the day (when I was curious and wanted to rip music from the game as well as look what formats it uses) I coded a simple extractor. Now I hacked a small tool to convert SPK back to ZIP instead. It works like supposed, so now I have access to all resource files again.