From 1248383e466ecbfb91a48f869d1f4bf3425dee26 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sat, 2 Apr 2016 17:04:30 +0200 Subject: [PATCH] Add Daikatana pak file format description to README --- README | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/README b/README index 234a0f9..4afcd84 100644 --- a/README +++ b/README @@ -36,7 +36,54 @@ written one after the other without any space between them. A directory entry is 64 bytes long has entries in the following order: - A 56 byte file name (in ASCII) - - A 4 byte value defining the position if the file + - A 4 byte integer value defining the position if the file as an offset in bytes to the start of the pak file. - A 4 byte integer giving the length of the file in bytes. + +------------------------------------------------------- + + The Daikatana Pak File Format + ----------------------------- + +The Daikatana pak file format is similar to the Quake II one, but +additionally supports compressing files within the pak. +Daikatana only did that for .tga .bmp .wal .pcx and .bsp files and might +expect other files to be uncompressed (in case you want to write a compressor). + +In Daikatana directory entries are 72 bytes long, because they have to +additional 4byte integer fields at the end: + - A 4 byte integer giving the compressed length of the file in bytes, + if it is compressed. + - A 4 byte integer indicating whether the file is compressed + (0: it's not compressed, else it's compressed) + +If the file is compressed, the file length field (the one also defined in +Quake II pak) indicates the uncompressed length of the file, while the +additional "compressed length" field indicates the number of bytes the +compressed data of that file takes in the .pak. + +Compressed files are decompressed like this: + while not done: + read a byte (unsigned char) _x_. + // x is never written to output, only used to determine what to do + if x < 64: + x+1 bytes of uncompressed data follow (just read+write them as they are) + else if x < 128: + // run-length encoded zeros + write (x - 62) zero-bytes to output + else if x < 192: + // run-length encoded data + read one byte, write it (x-126) times to output + else if x < 254: + // this references previously uncompressed data + read one byte to get _offset_ + read (x-190) bytes from the already uncompressed and written output data, + starting at (offset+2) bytes before the current write position + (and add them to output, of course) + else if x == 255: + you're done decompressing (used as terminator) + // but I'd also abort once compressed_length bytes are read, to be sure + +See also https://gist.github.com/DanielGibson/8bde6241c93e5efe8b75e5e00d0b9858 +("Description of Daikatana .pak format")