Redguard:TEXBSI File Format

A UESPWiki – Sua fonte de The Elder Scrolls desde 1995

Some of the Redguard image data is stored in the TEXBSI.* files found in the FXART game directory. This document explains the format of these files as best that is known. It is assumed that you are at least slightly familiar with hex-editing and base-16 numbers. All of the texture files in the game and in the demo have been tested for any of the 'confirmed' markers.

Format Description

Each texture file is composed of multiple image structures, one following the other. The largest texture files in Redguard contain less than 100 images at the most. The image is always started with a 9 byte name identifier. If the image name is null (i.e., all 00h characters or 0 length) this indicates the end of a texture file. Following the name is a long integer representing the size in bytes the image takes up.

Size Type Info
9 bytes string Name
4 bytes long integer Image Size in bytes

The size is not included for the last image in the file. The image size does not include the 13 bytes taken by name and size fields. The image is then divided into a number of sub-records, typically including the following in that order:

  1. Type
  2. Header
  3. Data
  4. End

The image sub-records have the following structure:

Size Type Info
4 bytes string Name
4 bytes long integer, Motorolal byte order Size in bytes

The size of the sub-record again does not include the 8 bytes of header info. Please note that the sub-record size field is written with the Motorolalbyte order and not the usual Intel byte order. For instance, if we were writing the hex number AABBCCDDh to a file:

Intel Byte Order: DD CC BB AA
Motorolal Byte Order: AA BB CC DD

There are fields with a zero size indicating they contain no data. The possible image sub-records are described below.

Type: 'BSIF' (this or IFHD are required)
Size: Always 0 (Confirmed)
Description: Appears to identify the image as a particular format. Perhaps the 'BattleSpire Image Format'? Requires a following 'BHDR' type sub-record.
Type: 'IFHD' (this or BSIF are required)
Size: Always 44 (Confirmed)
Description: This represents an 'Image Format Header' data structure containing header information for the current image. It appears that this and the 'BSIF' type sub-record cannot exist together.
short u1 always 0001h
short u2[21] always 0000h
Type: 'BHDR' (Required)
Size: Always 26 (Confirmed)
Description: This is an image header structure for the 'BSIF' type image.
short x_offset } Most likely
short y_offset } but unsure?
short width
short height
char u1 (always 00h or 01h)
char u2 (always 00/01/09h)
short u3 (always 0000h)
short u4 (always 0000h)
short num_frames (always 0001-0010h)
short u6 (0000-00FFh, 0041h occurs the most)
short u7 (always 0000h)
short u8 (always 0000h)
char u9 (always 00/80/A3h, mostly 00h)
char u10 (always 00/01/02h, mostly 01h)
short u11 (always 0000/0004h, mostly 0000h)
Type: 'CMAP' (Optional)
Size: 768 (Confirmed)
Description: A color map, or palette, for defining custom colors for the current image. The data is 256 colors written in RGB triplets.
Type: 'DATA' (Required)
Size: Variable
Description: This sub-record contains all the image data. If num_frames in BHDR is 1 then image data is array of width * height bytes (palette indices). If num_frames is >1 the there is first a list of height * num_frames offsets (each one is 32bit integer). Each group of height offsets points to rows of bytes (width in length) for one frame. Offset with value 0 would point at the beginning of the data in DATA sub-record, not the beginning of whole texture file.
Type: 'END ' (Required)
Size: Always 0 (Confirmed)
Description: Always the last sub-record in an image. Note that there is a space after the 'D'.

Thus, a valid image format is composed of the following:

Image Header Required
BSIF or IFHD Required
BHDR Required
CMAP Optional
DATA Required
END Required

Texture Format Review

Here's a brief review of the texture format now that all the important stuff has been explained:

Image #1
Name (9 bytes)
Size (4 bytes)
Sub-Records ('BSIF', 'BHDR', 'END', etc...)
Image #2
Name
Size
Sub-Records
...
Last Image
Name (9 bytes) = (null or empty string)

Thus, if a texture file had no images it would just be 9 bytes in size, consisting of all 00h characters.