CC Format

From ModdingWiki
Jump to: navigation, search
CC Format
Format typeArchive
Max files140
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.