The "4cc" type is just a group of four characters. An "int" is assumed to be 32 bits and a "word" is 16 bits. A "string" is just a zero terminated C style string. The SYSTEMTIME structure is a structure common to Windows. There is more information here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemtime_str.asp. The files should be decoded as little endian.
|0||4||4cc||A four character identifier for the file. Should be "GK3!"|
|4||4||4cc||Another four character identifier. Should be "Barn"|
|8||2||unsigned word||Minor version of GK3|
|10||2||unsigned word||Major version of GK3|
|12||2||unsigned word||Minor version of the header|
|14||2||unsigned word||Major version of the header|
|16||4||unsigned int||Total size of the barn file|
|20||4||unsigned int||Offset to section directory|
If the barn header version is 1.0, then there will be a header "extension" at this point with additional information.
|24||4||unsigned int||Executable build number|
|28||4||unsigned int||Content build number|
|32||4||unsigned int||Random number for tracking changes|
|36||16||SYSTEMTIME||Barn build time|
|52||16||SYSTEMTIME||Barn's last modified time|
|??||4||unsigned int||Number of directory entries|
After this point is an array of the following structure. The number of these structures is the same as the number of directory entries you just read.
|??||4||4cc||Type of directory (note that this will be in reverse; "Data" and "DDir" will be in the file as "ataD" and "riDD")|
|?? + 4||2||unsigned word||Minor version of directory|
|?? + 6||2||unsigned word||Major version of directory|
|?? + 8||4||unsigned int||Random number|
|?? + 12||4||unsigned int||Directory checksum|
|?? + 16||4||unsigned int||Size of the directory|
|?? + 20||4||unsigned int||Header section offset (relative to the beginning of the barn)|
|?? + 24||4||unsigned int||Data section offset (relative to the beginning of the barn)|
The header section offset is the offset to the beginning of a directory section. The structure of the directory is different depending on what type of directory it is. The DDir directory contains information about which barn file the directory is describing, how many files are in the directory, the size of the file, and much more. The Data directory contains the files themselves. Each barn has only one Data section but may have more than one DDir section.
|??||32||string||Name of the barn file the directory describes (will be blank if it's describing the current barn)|
|?? + 32||4||4cc||ID of the directory section|
|?? + 36||40||string||Description of the data directory|
|?? + 76||4||unsigned int||Random number|
|?? + 80||4||unsigned int||Number of files in the directory|
Next is an array of offsets to information about the files. The number of elements in this array is the number of files in the directory.
|??||4||unsigned int||Offset to entry about a file|
Right after this array is an optional extention of the DDir structure. If the version of the DDir structure is 1.2 then it will also have this structure.
|??||4||unsigned integer||Which disc the barn this directory describes is on|
|?? + 4||4||unsigned integer||Priority code (not sure how this is used)|
Next comes an array of data entries. Each entry contains offsets to the file, file size, the type of compression used on the file, etc. Use the offsets read in before the 1.2 version block to get to the entries.
|??||4||unsigned integer||Size of the file within the barn|
|?? + 4||4||unsigned integer||Offset of the file (relative to the beginning of the data section!)|
|?? + 8||4||unsigned integer||Data entry checksum|
|?? + 12||1||unsigned byte||Entry type (not sure what this is for)|
|?? + 13||1||unsigned byte||Format that the file is in (0 = uncompressed, 1 = ZLib, 2 = LZO)|
|?? + 14||1||unsigned byte||File name length|
|?? + 15||??||string||Name of the file|
That's it (finally!) for the DDir section.
The LZO algorithm used to decompress files is the LZO1X algorithm. The first 4 bytes of an LZO compressed file represent the uncompressed size of the file, and the next 4 bytes represent the compressed size of the file. Each of these fields do not take into account the eight byte header - the sizes are JUST for the file itself.
|??||4||unsigned integer||Size of the full uncompressed file|
|?? + 4||4||unsigned integer||Size of the compressed file|
|?? + 8||??||??||File data|
These two sizes will be necessary to properly decompress the file. Also remember that decompression must begin at the eight byte offset, not at where the barn says the file starts.