Although I've written a utility to unpack and repack the Saints Row texture files I haven't explained the format of the file. So here it is for those that are interested.
As with most SR3 files the data is split between 2 files. The cpeg_pc / cvbm_pc file contains the header information. The gpeg_pc / gvbm_pc contains the actual texture data.
The cpeg_pc and cvbm_pc files are the same except that the cvbm_pc files always only contain one texture. The cpeg_pc can in some cases have 0 textures defined, in which case there will not be a corresponding gpeg_pc file.
The format of the cpeg_pc / cvbm_pc files is:
This is a pseudo c header file. Any undefined arrays of the type char i.e. char FOO[]; means that the data is a null terminated c type string.
The gpeg_pc/gvbm_pc file is a collection of DDS texture file data but with the header taken off i.e. remove the first 128 bytes. Each block of texture data is pointed to by the TextureData[TextureNumber].FileOffsetOfData record. It looks like each block of texture data is aligned to 16 bytes.
As with most SR3 files the data is split between 2 files. The cpeg_pc / cvbm_pc file contains the header information. The gpeg_pc / gvbm_pc contains the actual texture data.
The cpeg_pc and cvbm_pc files are the same except that the cvbm_pc files always only contain one texture. The cpeg_pc can in some cases have 0 textures defined, in which case there will not be a corresponding gpeg_pc file.
The format of the cpeg_pc / cvbm_pc files is:
This is a pseudo c header file. Any undefined arrays of the type char i.e. char FOO[]; means that the data is a null terminated c type string.
Code:
// Set up structures used by file.
enum <unsigned int> TEXTURETYPES
{
D3DFMT_DXT1=400,
D3DFMT_DXT3,
D3DFMT_DXT5,
D3DFMT_R5G6B5,
D3DFMT_A1R5G5B5,
D3DFMT_A4R4G4B4,
D3DFMT_R8G8B8,
D3DFMT_A8R8G8B8,
D3DFMT_V8U8,
D3DFMT_CxV8U8,
D3DFMT_A8,
D3DFMT_DXT5alt=701
};
struct TEXTURERECORD
{
unsigned int64 FileOffsetOfData;
unsigned short Width;
unsigned short Height;
TEXTURETYPES TextureEnum;
unsigned char Unk_Flags[6];
unsigned char HasAlpha;
unsigned char Unk_Flags2[12];
unsigned char NumberOfMipLevels;
unsigned int SizeOfData;
unsigned short Unknown3[16]; // Always filled with zeros?
};
struct TEXTURENAME
{
char Name[];
};
// This is the actual start of the file data.
struct FILE
{
char Magic[4]; // Always GEKV
int Version; // Always 13
int SizeOf_cpeg_pc;
int SizeOf_gpeg_pc;
int NumberOfTextures;
short NumberOfTexturesDup;
short Unknown3;
TEXTURERECORD TextureData[NumberOfTextures];
TEXTURENAME TextureName[NumberOfTextures];
} File;
The gpeg_pc/gvbm_pc file is a collection of DDS texture file data but with the header taken off i.e. remove the first 128 bytes. Each block of texture data is pointed to by the TextureData[TextureNumber].FileOffsetOfData record. It looks like each block of texture data is aligned to 16 bytes.