As Tribes: Ascend uses the Unreal 3 engine, it makes use of the content cooking functionality that it provides. This compresses the images and stores them all within one file. A second file is used as an index into the main cache file to extract the images. Ascend uses a slight variation of Unreal's cooking methods. In addition to applying standard image compression techniques, they use zlib compression on it before storing it.
The file specifications for the two texture cache files are as follows:
This file contains information about all of the images in the main cache file. Below is the file's structure. The first four bytes state how many files are in the image cache. For each of those images, there is an image data structure which contains the image dimensions, compression information, and the number of mipmaps. For each mipmap, there is a mipmap chunk structure that gives the offsets into the main texture cache file. The first chunk is the main image and has the dimensions found in the image structure fields. The remaining chunk dimensions are found by continually dividing the original dimensions by two.
|File Count||4 bytes||The number of images in the texture cache|
|Image data structure|
|Texture Name||Pascal String (4 byte length field)||The texture file's name|
|Flags||2 bytes||Compression flags|
|Width||2 bytes||The width of the image|
|Height||2 bytes||The height of the image|
|Mipmap Count||4 bytes||The number of mipmap chunks (including the image itself)|
|Mipmap chunk structure|
|Unknown||1 byte||Always set to "1"|
|Offset||4 bytes||The byte offset into the data file|
|Length||4 bytes||The length of the data to read from the data file|
|Decompressed Size||4 bytes||The actual size of the image, uncompressed|
This file contains all of the textures used in the game, and their mipmaps. Each block of data in this file is compressed using zlib compression.
|Zlib header||2 bytes||0x9C78, indicating that the block is under zlib compression|
|Compressed data||Variable||The length of this data comes from the "Length" field of the Mipmap chunk structure above|
After decompressing the entire block (header included) using the "Length" and "Decompressed Size" fields the image data can be found. The images themselves are compressed using DXT compression. Using the "Flags" field from the Mipmap chunk structure, the appropriate DXT decompression routines should be applied.
It is theoretically possible to insert new image data back into the texture cache files. One simply modifies the image, makes smaller copies for the mipmaps, zlib compress each one, append it to the main data file, and update the cache header with the new offsets. No tools exist that currently do this. This is partly because the updater will erase all of the changes when a new patch is released. One person was attempting to use the Unreal Development Kit and have it re-execute the cooking routines on the new images, but they received a Cease and Desist letter from HiRez Studios.