Ok, (hopefully) final version of my VPK file format spec follows.
The basic structure of a VPK file is as such:
an unsigned long for block length, followed by a block of data of that many bytes.
If you can zlib inflate the block of data without an error, then the data is compressed. There is no other (known) way to find this out.
The block you need to be concerned with when loading a VPK file is the last block in the file. This block contains the filenames and what block is associated with each file.
The filename block starts with 2 unsigned longs: filename block size, and the number of filenames.
Following the filename block header are the actual filename entries. Filename entries consist of 3 unsigned longs which represent: block start, block length, and filename length. The block start field is an offset into the file. It does not reference the exact beginning of the block; rather, it references the block header, so you can either read that in and then handle the block as you would normally, or just add 4 bytes to the header and use the length given to you in the block length field. The block length field, is, of course, the length of the block (compressed, if it is compressed at all), and the filename length is the length of the filename field. There is no null terminator on the filename, btw.
Now, when you read/decompress one of the file blocks (not the filenames block) there is a header on it. The header consists of 3 things: an unsigned long for the filename length, an unsigned long for the length of the block (this does not include the header unlike the other lengths for the block), and then the filename, again. After this header comes the data for the file.
This should be every single piece of the file format now.
If you have any questions, feel free to ask, as always.
Happy Hacking,
Lord Daeken M. BlackBlade
(Cody W. Brocious)
|