From CloudModding TWW Wiki

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
0x00
1
GXTexFormat Format The format of the texture image
0x01
1
bool AlphaEnabled
0x02
2
short Width The width of the texture
0x04
2
short Height The height of the texture
0x06
1
GXWrapMode WrapS The wrap mode along the texture's S axis.
0x07
1
GXWrapMode WrapT The wrap mode along the texture's T axis.
0x08
1
bool PalettesEnabled Must be set to true for the palette to be used correctly.
0x09
1
GXTexPalette PaletteFormat The format of the associated palette.
0x0A
2
short PaletteCount The number of entries in the palette data.
0x0C
4
int PaletteOffset The offset to the palette data, relative to the start of this header.
0x10
1
bool MipmapEnable Whether the texture will use mipmaps.
0x11
1
bool DoEdgeLOD
0x12
1
bool BiasClamp
0x13
1
byte MaxAnisotropy
0x14
1
GXTexFilter MinFilter
0x15
1
GXTexFilter MagFilter
0x16
1
byte MinLOD The minimum LOD clamp, scaled by 8. This appears to always be 0, at least.
0x17
1
byte MaxLOD The maximum LOD clamp, scaled by 8. This should practically have the same value as MipmapCount.
0x18
1
byte MipmapCount Apparently unread by the engine itself, it only uses the MipmapEnable flag and the max LOD field.
0x19
1
byte Unknown
0x1A
2
short LODBias The LOD bias of the texture, scaled by 100.
0x1C
4
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