BNTX_(File_Format) BNTX (Binary NX TeXture) is a file format used on the Nintendo Switch. It contains one or more images, and can also embedded into other file formats such as BFRES, BFFNT and PTCL.
File Format
The file format starts with the following header:
Offset |
Type |
Description
|
0x00 |
Char[8] |
File magic. Always BNTX\0\0\0\0 in ASCII, or 42 4E 54 58 00 00 00 00.
|
0x08 |
UInt32 |
File version.
|
0x0C |
UInt16 |
Byte-order-mark. FE FF for big endian, FF FE for little endian.
|
0x0E |
Byte |
Alignment shift. 2 raised by this value is the alignment required by this file when loaded into memory.
|
0x0F |
Byte |
Target address size. Size of a pointer in bits, thus 64.
|
0x10 |
UInt32 |
File name offset. Points directly to the string, and not to the length unlike all other strings.
|
0x14 |
UInt16 |
A flag which is only used on runtime. One bit sets wether the file is relocated.
|
0x16 |
UInt16 |
Offset to the first section.
|
0x18 |
UInt32 |
Relocation table offset.
|
0x1C |
UInt32 |
Size of the file in bytes.
|
Texture Container
The texture container stores general data about the file.
Offset |
Type |
Description
|
0x00 |
String |
Target platform. "NX " for Switch, "Gen " for computer
|
0x04 |
Int32 |
N = Number of textures.
|
0x08 |
Int64 |
Texture table offset. Points to an Int64[N] which points to the textures.
|
0x10 |
Int64 |
Texture data offset. Points to the texture data.
|
0x18 |
Int64 |
Texture DICT offset. Points to a dictionary containing the texture names.
|
0x20 |
Int64 |
Texture memory pool offset.
|
0x28 |
Int64 |
Current memory pool pointer (set on runtime).
|
0x30 |
UInt32 |
Base memory pool offset (set on runtime).
|
0x34 |
Byte[4] |
Reserved.
|
Texture
Each texture contains texture data for all mipmaps. The texture data is swizzled when used on a Switch.
Offset |
Type |
Description
|
0x00 |
Char[4] |
Section magic. Always BRTI in ASCII.
|
0x04 |
UInt32 |
Next section offset.
|
0x08 |
UInt32 |
Size of this section in bytes.
|
0x0C |
Byte[4] |
Reserved.
|
0x10 |
Byte |
Flag. xxxx ABCD.
- A: res texture
- B: sparse residency
- C: sparse binding
- D: specify texture layout
|
0x11 |
Byte |
Image storage dimension.
Value |
Dimension
|
0x00 |
Undefined
|
0x01 |
1D
|
0x02 |
2D
|
0x03 |
3D
|
|
0x12 |
UInt16 |
Tile mode. Optimal = 0 (swizzled), Linear = 1 (not swizzled).
|
0x14 |
UInt16 |
Swizzle value.
|
0x16 |
UInt16 |
Number of mipmaps, including the main level image.
|
0x18 |
UInt16 |
Number of multi samples.
|
0x1A |
Byte[2] |
Reserved.
|
0x1C |
UInt32 |
Image format.
|
0x20 |
UInt32 |
GPU access flag. Sets the access type of the GPU.
|
0x24 |
Int32 |
Width of texture in pixels.
|
0x28 |
Int32 |
Height of texture in pixels.
|
0x2C |
Int32 |
Depth of texture in pixels. 1 if texture is 2D.
|
0x30 |
UInt32 |
Array length, number of textures in the array. 1 if texture is not an array texture.
|
0x34 |
Byte[8] |
Texture layout. Contains the block height shift, which is used for the swizzling algorithm.
|
0x3C |
Byte[20] |
Reserved.
|
0x50 |
UInt32 |
The total size of all mipmap data.
|
0x54 |
UInt32 |
Texture data alignment. Always 0x200.
|
0x58 |
Byte[4] |
Channel sources for the red, green, blue and alpha channels respectively.
Value |
Channel Source
|
0x00 |
Zero
|
0x01 |
One
|
0x02 |
Red
|
0x03 |
Green
|
0x04 |
Blue
|
0x05 |
Alpha
|
|
0x5C |
Byte |
Texture dimension.
Value |
Dimension
|
0x00 |
1D
|
0x01 |
2D
|
0x02 |
3D
|
0x03 |
Cube
|
0x04 |
1D array
|
0x05 |
2D array
|
0x06 |
2D multisample
|
0x07 |
2D multisample array
|
0x08 |
Cube array
|
|
0x5D |
Byte[3] |
Reserved.
|
0x60 |
Int64 |
Name offset. Points to this texture name.
|
0x68 |
Int64 |
Texture container offset.
|
0x70 |
Int64 |
Image data table offset. Points to an array of Int64 which points to the different levels of the textures.
|
0x78 |
Int64 |
User data offset.
|
0x80 |
Int64 |
Texture pointer. Points to 0x100 unknown bytes, presumably used on runtime.
|
0x88 |
Int64 |
Texture view pointer. Points to 0x100 unknown bytes, presumably used on runtime.
|
0x90 |
Int64 |
Descriptor slot data offset. Unknown data, presumably used on runtime.
|
0x98 |
Int64 |
User data dictionary offset. Points to a dictionary containing the user data names.
|
Texture Data
The texture data starts with a header marker which presumably is not used. The structure, which is 0x10 bytes long, is placed so that the texture data is aligned by the alignment specified in the header. All texture data follows after the header. It has the following structure:
Offset |
Type |
Description
|
0x00 |
Char[4] |
Section magic. Always BRTD in ASCII.
|
0x04 |
UInt32 |
Next section offset.
|
0x08 |
UInt32 |
Size of this section in bytes.
|
0x0C |
Byte[4] |
Reserved.
|
String Table
The string table is a table where all strings are stored. Each string has first the length written, which is a 16-bit integer, and then the string is stored as a null-terminated string. The string length does not include the null byte, and the 16-bit string length value is always aligned by 2. The string sorting algorithm is unknown.
Offset |
Type |
Description
|
0x00 |
Char[4] |
Section magic. Always _STR in ASCII.
|
0x04 |
UInt32 |
Next section offset.
|
0x08 |
UInt32 |
Size of this section in bytes.
|
0x0C |
Byte[4] |
Reserved.
|
0x10 |
Int32 |
Number of strings stored in the string table. The first string is always an empty string ("") and is not included in this count.
|
Dictionary
A dictionary (sometimes known as DICT) is a common structure used in many Nintendo formats such as BFRES and BNTX. It is used for fast name look-up, in order to find a specific array item by its name. It starts with the following structure:
Offset |
Type |
Description
|
0x00 |
Char[4] |
Section magic. Always _DIC in ASCII. Note that in BFRES this magic is set to 00 00 00 00, most likely due to an export error.
|
0x04 |
Int32 |
Number of entries. This does not include the root entry.
|
After, the entries are specified. The root entry follows first, then all other entries are stored. Each entry has the following structure:
Offset |
Type |
Description
|
0x00 |
Int32 |
Ref bit.
|
0x04 |
UInt16[2] |
Child node indices. First the left node, then the right node.
|
0x08 |
Int64 |
Key offset, which points to the key name this entry stores.
|
User Data
User data is a common structure used in many Nintendo formats such as BFRES and BNTX. It allows game designers to store generic data into different files, in order to be used by the game. The data can be used for anything, and is not used by the actual data parser. Each entry has the following structure:
Offset |
Type |
Description
|
0x00 |
Int64 |
Name offset. Points to the name of this user data entry.
|
0x08 |
Int64 |
Data offset. Points to the actual data. What the data actually is depends on the data type.
|
0x10 |
Int32 |
Number of data entries.
|
0x14 |
Byte |
Data type.
Value |
Data Type
|
0x00 |
Int32
|
0x01 |
Float
|
0x02 |
String
|
0x03 |
Byte
|
|
0x15 |
Byte[43] |
Reserved.
|
Relocation Table
Offset |
Type |
Description
|
0x00 |
Char[4] |
Section magic. Always _RLT in ASCII.
|
0x04 |
UInt32 |
Table offset. The offset where this table starts.
|
0x08 |
Int32 |
Number of sections.
|
0x0C |
Byte[4] |
Padding.
|
Offset |
Type |
Description
|
0x00 |
Int64 |
Section pointer, set on runtime.
|
0x08 |
UInt32 |
Section offset.
|
0x0C |
UInt32 |
Section size.
|
0x10 |
UInt32 |
Entry ID.
|
0x14 |
UInt32 |
Number of entries.
|
Offset |
Type |
Description
|
0x00 |
UInt32 |
Entry offset.
|
0x04 |
UInt16 |
Array count.
|
0x06 |
Byte |
Offset count.
|
0x07 |
Byte |
Padding size.
|
Version List
Version |
Found in
|
4.0.0
|
|
4.1.0
|
|
Tools
The following tools can handle BNTX files: