CC Format
Format type | Archive |
---|---|
Max files | 140 |
File Allocation Table (FAT) | Beginning |
Filenames? | Yes, hashed |
Metadata? | None |
Supports compression? | Yes |
Supports encryption? | No |
Supports subdirectories? | No |
Hidden data? | No |
Games |
The CC Format is how files in the game King's Bounty are stored. Files in this format have the ".CC" extension, which probably stands for "crude" or "compact" compression. It's a group file format with compression (similar to .zip file) with a simple file allocation table in its header.
The game will check the current directory for files only if they weren't found in the CC file first. However, stand-alone files are still expected to be compressed and include UINT32LE length, see Compression below.
File format
The first 1122 (or less) bytes of the file consists of file entries, with the remainder containing the data. Each file entry takes 8 bytes, and consists of the filename hash, it's offset and compressed length.
Signature
There is no known signature for this format. One method to identify files is to read in the file entries (as there is a fixed maximum of these, all 1122 bytes must be present for the file to be valid) and confirm that each file offset refers to a location after a previous file offset (that is not the requirement of the format, but that is how the original CC files are composed), and that offset is within file boundary.
Header
Data type | Name | Description |
---|---|---|
UINT16LE | numFiles | Number of entries |
struct FileEntry | entries[] | Array of entries |
The 1122 bytes available makes enough room for 140 files. However, the largest amount actually seen - 136 files in 416.CC.
File entry
A file entry is laid out as follows.
Data type | Name | Description |
---|---|---|
UINT16LE | hash | Filename hash |
UINT24LE | offset | File offset from start of group file |
UINT24LE | size | Size of compressed data |
Note the weird 24-bit data type. It is indeed an unsigned integer composed from 3 bytes in little endian order.
The hash key for a filename could be calculated as follows:
//word is UINT16LE
word cc_filename_hash(char *filename)
{
word key = 0;
byte next;
while ((next = *filename++))
{
next &= 0x7F;
if (next >= 0x60)
next -= 0x20;
/* Swap high and low bytes */
key = ((key >> 8) & 0x00FF) | ((key << 8) & 0xFF00);
/* Rotate left by 1 bit */
key = (key << 1) | ((key >> 15) & 0x0001);
key += next;
}
return key;
}
As the filenames themselves are not stored in the group file, only their hashes are, we must have a prepared list of filenames handy. The game keeps it in the EXE file.
The files are:
// Add .4, .16 or .256 extension to those: char *graf_files[] = { //Troops "peas","spri","mili","wolf","skel","zomb","gnom","orcs","arcr","elfs", "pike","noma","dwar","ghos","kght","ogre","brbn","trol","cavl","drui", "arcm","vamp","gian","demo","drag", //Villains "mury","hack","ammi","baro","drea","cane","mora","barr","barg","rina", "ragf","mahk","auri","czar","magu","urth","arec", "knig","pala","sorc","barb","nwcp","title","select", "tileseta","tilesetb","tilesalt","cursor","town","cstl","plai", "frst","dngn","cave","comtiles","view","endpic" }; // Use as is: char *extra_files[] = { "KB.CH", // 1bpp 8x8 font file "LAND.ORG", // world map "TIMER.DRV", "SOUND.DRV", "CGA.DRV", "EGA.DRV", "TGA.DRV", "HGA.DRV", "MCGA.DRV", };
The .4, .16 and .256 files are graphics, kept in King's Bounty Graphics Format.
All files are compressed.
Compression
At each offset, a data chunk is located:
Data type | Name | Description |
---|---|---|
UINT32LE | size | Size of uncompressed data |
BYTE | lzwData[] | Compressed data |
The data is compressed by LZW compression with the following characteristics:
- Codeword takes from 9 to 12 bits (as in Commander Keen)
- 0x0100 codeword instructs dictionary reset and not error
The dictionary reset is performed like this:
the dictionary is cleared (the bit step is made 9 bits again) one more value is being read from input that value is written to output as-is that value is NOT saved into the dictionary
Credits
Originally devised by the openkb project, with best regards to the modding community.