BTI
BTI is a format used for storing texture image data. It can be found alone as a .bti file, or as an embedded image in the TEX1 chunk of the BMD/BDL model format.
The format is simply a header followed by the image data. The image data can be encoded in several different ways, and the header specifies which format the image data is in.
Header
Offset | Size | Type | Name | Description |
---|---|---|---|---|
|
|
GXTexFormat | Format | The format of the texture image |
|
|
bool | AlphaEnabled | |
|
|
short | Width | The width of the texture |
|
|
short | Height | The height of the texture |
|
|
GXWrapMode | WrapS | The wrap mode along the texture's S axis. |
|
|
GXWrapMode | WrapT | The wrap mode along the texture's T axis. |
|
|
bool | PalettesEnabled | Must be set to true for the palette to be used correctly. |
|
|
GXTexPalette | PaletteFormat | The format of the associated palette. |
|
|
short | PaletteCount | The number of entries in the palette data. |
|
|
int | PaletteOffset | The offset to the palette data, relative to the start of this header. |
|
|
bool | MipmapEnable | Whether the texture will use mipmaps. |
|
|
bool | DoEdgeLOD | |
|
|
bool | BiasClamp | |
|
|
byte | MaxAnisotropy | |
|
|
GXTexFilter | MinFilter | |
|
|
GXTexFilter | MagFilter | |
|
|
byte | MinLOD | The minimum LOD clamp, scaled by 8. This appears to always be 0, at least. |
|
|
byte | MaxLOD | The maximum LOD clamp, scaled by 8. This should practically have the same value as MipmapCount. |
|
|
byte | MipmapCount | Apparently unread by the engine itself, it only uses the MipmapEnable flag and the max LOD field. |
|
|
byte | Unknown | |
|
|
short | LODBias | The LOD bias of the texture, scaled by 100. |
|
|
int | TextureDataOffset | The offset to the texture data, relative to the start of this header. |
As Embedded Image
The BTI format can be stored in models and particle banks as an embedded image. When this is the case, the headers for each embedded image are stored together, one after another. After the last header is the image data corresponding to each header in an uninterrupted stream.
This is where the "TextureDataOffset" variable in the header is useful. This offset specifies where the image data starts in relation to the start of the image data's header. In other words, to find the image data for a given header, you go to the start of the header and move forward the number of bytes given by TextureDataOffset.
Texture Formats
This is the list of formats that the image data can be encoded in.
ID | Format | Bits per Pixel | Block Width | Block Height | Block Size | Type/Description |
---|---|---|---|---|---|---|
0x00 | I4 | 4 | 8 | 8 | 32 | Gray |
0x01 | I8 | 8 | 8 | 8 | 32 | Gray |
0x02 | IA4 | 8 | 8 | 4 | 32 | Gray + Alpha |
0x03 | IA8 | 16 | 4 | 4 | 32 | Gray + Alpha |
0x04 | RGB565 | 16 | 4 | 4 | 32 | Color |
0x05 | RGB5A3 | 16 | 4 | 4 | 32 | Color + Alpha |
0x06 | RGBA32 | 32 | 4 | 4 | 64 | Color + Alpha |
0x08 | C4 | 4 | 8 | 8 | 32 | Palette |
0x09 | C8 | 8 | 8 | 4 | 32 | Palette |
0x0A | C14X2 | 16 (14 used) | 4 | 4 | 32 | Palette |
0x0E | CMPR | 4 | 8 | 8 | 32 | Mini palettes in each block, RGB565, or transparent. |
Palette Formats
The C4, C8, C14X2, and CMPR image formats all use palettes to store color data. For C4, C8, and C14X2, the palette format will be specified in the PaletteFormat variable in the image's header. CMPR stores palettes within the compressed blocks of image data. Below is a table containing the 3 possible palette formats.
ID | Format | Bits per Pixel | Block Width | Block Height | Block Size | Type/Description |
---|---|---|---|---|---|---|
0x00 | IA8 | 16 | 4 | 4 | 32 | Gray + Alpha |
0x01 | RGB565 | 16 | 4 | 4 | 32 | Color |
0x02 | RGB5A3 | 16 | 4 | 4 | 32 | Color + Alpha |