DISCLAIMER: This file comes with no guarantee as to its accuracy, and must not be used to break the law in any way. I accept no responsibility for any problems relating to this document, use at your own risk.

X-Isle File Formats

These formats might be generic CryTek engine file formats, but I've only tested them on the demo of X-Isle. Written and researched by Andres.

Image files:
  CryTek Compressed Textures (.cct): Model textures, normal maps, bumpmaps, and pre-rendered billboards of models.
  CryTek Terrain Textures (.ctc): Terrain textures (DXT1 compressed)
  .h16: Terrain heightmap. 1024x1024 array of 16bit integers (unsigned?).

Models:
  CryTek Geometry File (.cgf): Meshes of all objects (static and dinos).
  .cbb: Unknown. Array of 52 byte structures (floats), size related to mesh.num_verts
  .cbi: Unknown. Array of ints.

Dinosaurs:
 
.caf, .cal, .cct (see Images), .cgf (see Models), .cid, .csf

Misc:
  .lst: Unknown. struct { uint size; byte unknown[size][0x14]; }

CryTek Compressed Textures (.cct)

Contains a single DXT compressed texture plus mipmaps.. If the filename ends with "_unm" the color components store a normal map, and the alpha channel stores the corresponding bump/heightmap.

struct CCTFile {
  char[4] magic = "cctf";
  uint    type;           // 1 = DXT1 compressed, 0,2,3 = DXT3 compressed
  uint    unknown;        // = 0x830F sometimes. Related to type?

  array of {  // texture and its mipmaps down to 1x1, texture and larger mipmaps first
    uint width;
    uint height;
    uint dataSize;        // for DXT1 it should be width*height/2, for DXT3 width*height

    byte data[dataSize];  // raw DXT compressed data
  }
}
      --- OR ---
struct CCTFile {
  char[4] magic = "hilo";
  uint width;
  uint height;
  uint unknown = 0x02;       // bytes per texel?

  byte data[width*height*2]; // some sort of bumpmap data, hi and lo bytes being signed (ie. -128 to 127)
}

CryTek Terrain Textures (.ctc)

Contains an array of square terrain texture tiles. First uint of file is the width/height of the textures (128 in X-Isle demo). Followed by an array of raw data for DXT1 compressed textures + mipmaps ie. 128*128/2 bytes for first texture, 64*64/2 for first mipmap, ..., 8 bytes for 4x4 mipmap, 8 bytes for 2x2 mipmap (8 bytes as must store full DXT1 block), 8 bytes for 1x1 mipmap, 128*128/2 bytes for second texture, ... . Size of array is unknown, read until end of file. (X-Isle demo "cover.ctc" contains 508 textures.)

CryTek Geometry File (.cgf)

Contain a bunch of static meshes. Joint information for dinosaurs is stored elsewhere (format of which is not known).

struct CGFFile {
  char[6]  magic = "CryTek";
  byte[10] unknown;
  uint data_dir_offset; // position in file of DataDirectory block

}

// Describes what's in this file
struct DataDirectory {
  uint num_entries;
  array of struct {
    uint16 data_type; // 0x0000 = mesh

                      // 0x0004 = object/instance?
                      // 0x0006 = material
                      // 0x0007 = ?
    byte unknown[6];  // = {0xCC,0xCC,0x01,0x02,0x00,0x00}
    uint data_offs;   // position in file of data block

  } block_info[num_entries];
}

// MeshBlock.triangle[].material_num seems to index into this array of materials.
// I'm not sure if there can be more than one material block, or what that would mean.
struct MaterialBlock {
  uint16 data_type = 0x0006;
  byte unknown[6];  // = {0xCC,0xCC,0x01,0x02,0x00,0x00}

  uint num_mats;
  array of struct {
    char[32] mat_name;
    byte[32] ? = 0x00, 0x00, ...;
    byte[10] ?;
    char[32] diffuse_map;
    char[32] opacity_map;
    char[32] bump_map;
    byte[14] ?;
  } material[num_mats];
}


// Stores names for the meshes, plus some unknown stuff.
// I think num_objs = number of mesh blocks, and they correspond one-to-one in order
// of the mesh blocks in the data directory.
// I'm not sure if there can be more than one object block, or what that would mean.
struct ObjectBlock {
  uint16 data_type = 0x0004;
  byte unknown[6];  // = {0xCC,0xCC,0x01,0x02,0x00,0x00}
  uint num_objs;
  array of struct {
    char[16] object_name;
    byte[48] unknown;
  } object[num_objs];
}


// Basic textured mesh
struct MeshBlock {
  uint16 data_type = 0x0000;
  byte unknown[6];  // = {0xCC,0xCC,0x01,0x02,0x00,0x00}
  uint unknown2;    // = 0x00 always?

  uint unknown3;    // ?
  uint num_verts;
  uint num_tverts;
  uint num_tris;
  uint unknown1 = 0x00;
  uint unknown2 = 0x00;

  array of struct {
    float3 pos;
    float3 normal;
  } vertex[num_verts];

  array of struct {
    uint vert_num[3];
    uint material_num;
    uint unknown = 0x01;
  } triangle[num_tris];

  float2 tvert[num_tverts];
}

Page created: 11-Aug-2003