Saturday, 13 August 2016

Interstate 76 and Vehicle Textures

The textures for the vehicles are handled a little unusually.

Basically there are two important file types involved here, a CBK and a VQM file.

The VQM file contains the texture image, and references to the CBK file.

Internally there is a 256 Colour look up table, used by all the game graphics:

The CBK file is actually a set of 16 pixel patterns, at 1 byte/pixel, and each pattern represents a 4 x 4 block of pixels.

The first value in the CBK file is the number of pattern entries in this file, and the remaining data is the list of patterns. Each pattern is a 16 byte entry, of 16 * 1 byte per pixel CLUT references which will be rendered as a 4 x 4 pixel block.

The VQM file references into the CBK file for patterns. The format of the VQM file is
  •     four byte image width
  •     four byte image height
  •     16 byte label, indicating the associated CBK

Then this is followed by pattern references. Each reference is two bytes, and there are actually two different types of references - one using the CBK and one not, based on the most significant bit of the two byte entry.

If the most significant bit is not set then this is a reference to a CBK pattern – fill the next 4x4 block of the output image with the pixel pattern at the CBK file index indicated by "this value & 0x7fff".

Else If the most significant bit is set then this is actually a Colour LUT reference – fill the next 4x4 block  of the output image with the solid colour indicated by the lower byte.

Given that the VQM has up to 15 bits for the pattern reference then in theory it can reference up to 32K patterns in a single CBK, but the largest value I've seen is 4K.

Running through this process filling in 4x4 blocks generates the output image. Other than being careful not to overrun the image boundaries if the dimension is not a 4 pixel multiple this is a straightforward process. The output needs to be flipped and rotated, but that's pretty much it.

I'm kind of surprised by this setup though -  it achieves a consistent 8:1 compression for the textures themselves (2 bytes describe 16 bytes worth of pixels), but it seems a relatively involved way of doing things over an off the shelf image compression scheme, or even RLE coding given the nature of the graphics.