Contents
- Quick Intro
- General vocabulary
- BTP definitions
- BIN BTP file format
- BIN BTP file example
- CSV BTP file format
- Notes for Super Mario Galaxy
Quick Intro
BTP is JSYSTEM file format used on several Wii games. It is a file that contains the information of texture swap animations that take place on the materials of a BMD/BDL 3D model. This file format description is based on the BTP files found on Super Mario Galaxy. The main page (and the only one at the time) from where some information was found about this file format was in the BTP file format page on The Wind Waker's (TWW) CloudModding wiki.
Due to the incompleteness of information presented on said page I had to test some SMG BTP files (mostly from SMG's Mario model) with the J3D Animation Editor (or JAE) and j3dview programs that can read these files. Even with that, it was a very good and nice starting point (so thanks to the ones involved in the writing process). At the end, I managed to describe most data blocks of this file excluding ones I suppose are used for information separation purposes (I am unsure about this). Data blocks which purpose was not able to be discovered yet are tagged with "Unknown". Also, BTP files store data in Big Endian mode (BTPs from 3D All-Stars store data in Little Endian).
If there is any issue on the information provided please open an issue on this NotABug repository to let me know.
General vocabulary
The types of variables/definitions used in the file format need to be defined for the compression of its structure. Some (almost all) definitions were created as they did not exist in the information consulted. The BTP file format is a file written in Big Endian mode so the functions to read the file must be written considering such data storing convention. The vocabulary needed for the types of variables used in the BTP file format is as follows:
- byte: minimum information unit, 8 bits long.
- u8: unsigned integer, 8 bits long.
- u16: unsigned integer, 16 bits long.
- u32: unsigned integer, 32 bits long.
- char: ASCII character, 1 byte long.
- string: array of chars, null terminated.
- char[NUMBER] array: array of chars that is NUMBER of chars long.
- offset: position of the start of an information block relative to the starting position of another information block.
- padding: array of characters (not null terminated) used to fill the space between data blocks so that the information is aligned in memory in a specific multiple (multiple of 4 or 32, there can be NUMBER of paddings in a file and they may or may not exist). The alignment is taken with respect to the beginning of a section or the beginning of the file. The longest original padding string that has been found on a JSYSTEM file is
This is padding data to alignme
(Taken from CloudModding). - section: contains different types of data together.
- section start: an usual reference to the information that shows when a section starts (char[4]/char[8] array and section size, important for determining some offsets).
- block: specific piece of data, with a type, a length and a purpose, contained in sections.
- unknown: a block which purpose is not known yet (there may be NUMBER of unknowns in a file).
BTP definitions
The list of definitions used on the BTP file format is as follows:
- BTP file: JSYSTEM animation file that appears in Super Mario Galaxy which purpose is to hold information about texture swap animations (mostly used to animate eyes in models).
- BTP header: first 32 bytes of a BTP file containing the BTP file start, the BTP file size (in bytes), the section count and 16 bytes that are unknown.
- BTP file start: first 4 bytes of the BTP file that contain a char[4] array unique to JSYSTEM animation files (
J3D1
). - BTP ID: next to the BTP file start. BTP block that contains a char[4] array unique to BTP files (
btp1
). - TPT1 section: first and only section of the BTP file which is not of a fixed size, starts with 8 bytes containing the TPT1 section start and the TPT1 section size (in bytes). Contains the texture swap animation data and it is basically the BTP file.
- TPT1 section start: first 4 bytes of the TPT1 section that contain a char[4] array unique to this section (
TPT1
). - Loop Mode: integer number in between 0 - 4 describing how the animation is to be played.
- 0 - Once: play the animation only once, stop at the last frame.
- 1 - Once Reset: play the animation once, stop at first frame.
- 2 - Loop: repeat the animation forwards infinitely.
- 3 - Mirror Once: play animation forwards and then backwards only once. Stops at first frame.
- 4 - Mirror Loop: play animation forwards and then backwards infinitely.
- BTP Animation Length: block contained in the TPT1 section that has an u16 with the animation length of the BTP (in frames) to which all materials will end their texture swap animation. It tells how much of the animation data for a material to use for the animation that will actually play in game, in other words, it tells how much to extend or how much to cut the animation of a single material. It does not matter if materials have more/less animation data past this length, the animation for said material will end when this length is reached. In the case the material has animation data up to a frame contained in the animation length, the texture number for this frame will be used to complete the animation of said material to reach the desired animation length (see Fig. 0).
- Animated Material Count: block contained in the TPT1 section containing a u16 describing the number of materials to be animated. In general, the number of materials to be animated is the same as the number of materials that have texture animation data on the BTP.
- Animated Material Length Summation: block contained in the TPT1 section with an u16 containning the sum of all the animation lengths of all materials. It corresponds to the length of the Texture Swap Table.
- Animation Table: table containing the texture swap animation data for each material to be animated. It is located in the TPT1 section and it is composed by a header and the Texture Swap Table.
- Animation Length for a Material: u16 containing the length of the animation for a single material. This animation length isn't determined by the BTP Animation Length, materials can have animation lengths lower/larger than it. The sum of the animation data lengths of all materials on the BTP correspond to the length of the Texture Swap Table (see Fig. 0).
- Material Animation Data Position: u16 containing the position from where to start reading the Texture Swap Table to obtain the texture swap animation data for a material.
- Texture Swap Table: u16 array containing numbers associated to the textures to be used (swapped) in the BTP animation (the numbers correspond to the storage position of each texture in the BMD/BDL file). The length of this table is the sum of the animation durations of each material. All animation data for each material is stored without any division, one after the other. In other words, it is an array of enumerations (enums, of type u16) where each number represents a texture.
- Material Position Table: u16 array containing the numbers associated with each material to be animated in the BTP file (the numbers correspond to the storage position of each material in the BMD/BDL file, it is not an address but an identifier). The order in which these numbers are arranged allows to identify the information in the BTP corresponding to each material to animate. In other words, it is an array of enumerations (enums, of type u16) where each number represents a material.
- Material Name Table: table containing information about the names of the materials to be animated on the BTP file. The order in which the name information of each material is presented corresponds to the order of the materials in the "Material Position Table".
- String weight: defined way to calculate the numeric value of a string. Using the ASCII character table and the length of the string (without counting the null character) the calculation process goes as follows (reading chars from left to right):
STRING_WEIGHT = [FIRST_CHAR_VALUE] * (3^(STRING_LENGTH - 1)) + [SECOND_CHAR_VALUE] * (3^(STRING_LENGTH - 2)) + [THIRD_CHAR_VALUE] * (3^(STRING_LENGTH - 3)) + ... + [LAST_CHAR_VALUE] * (3^(0))
- String:
Body1_v
- String weight:
87298
- Binary rep of string weight:
010101010100000010
(18 bits) - Bits stored in the 2 bytes:
0101010100000010
(16 bits) - Truncated String weight stored in the 2 bytes:
21762
NOTE: the string weight (in the form it has been found on BTPs) is stored in a 2 byte block so when a string weight is greater than 65535
the number gets truncated to the 16 bits that the 2 byte block can hold (the 16 ones that show when reading the string from right to left).
Example:
(Fig. 0 - Ilustration of how the BTP Animation Length affects the animation data for each material to be shown in game, see Animation Length for a Material)
BIN BTP file format
In the following table it is shown the structure of the BTP file format.
BLOCK: Relevant data block number
DESCRIPTION: Description of what the block of data contains
There will be a total of 27 blocks for the important information on a BIN BTP file.
$$
will be used to indicate the start of a section.
BLOCK | DESCRIPTION |
---|---|
$$ | BTP header |
00 | BTP file start (char[4]) |
01 | BTP ID (char[4]) |
02 | BTP file size in bytes (u32) |
03 | Number of sections on the BTP file (u32, always 00 00 00 01?) |
04 | Unknown 1 (16 bytes, always FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF?). |
$$ | TPT1 section |
05 | TPT1 section start (char[4]) |
06 | TPT1 section size in bytes (u32) |
07 | Loop Mode (u8) |
08 | Unknown 2 (1 byte, always FF?) |
09 | BTP Animation Length (u16) |
10 | Animated Material Count (u16) |
11 | Animated Material Length Summation (u16) |
12 | Offset of the TPT1 section with respect to the start of the BTP header (u32, always 00 00 00 20?) |
13 | Offset of the Texture Swap Table with respect to the start of the TPT1 section (u32) |
14 | Offset of the Material Position Table with respect to the start of the TPT1 section (u32) |
15 | Offset of the Material Name Table with respect to the start of the TPT1 section (u32) |
16 |
Start of the Animation Table The following (Number of materials * 8) bytes are:
|
17 |
Start of the Texture Swap Table The following (Number of materials * 2) bytes are:
|
18 | Padding 1 (until the nearest offset that is a multiple of 4) |
19 |
Start of the Material Position Table The next (Number of materials * 2) bytes are:
|
20 | Padding 2 (until the nearest offset that is a multiple of 4) |
21 |
Start of the Material Name Table
|
22 | Unknown 5 (2 bytes, always FF FF?) |
23 |
Information specific to the name of each material to be animated. The following (Number of materials * 4) bytes are:
|
24 |
Start of the string array with the names of the materials to be animated on the BTP file
|
25 | Padding 3 (until the nearest offset that is a multiple of 32) |
26 | END OF FILE |
BIN BTP file example
The following images are from a BTP file from Super Mario Galaxy. Specifically, it is the iceflick.btp
contained on the MarioAnime.arc
file from the ObjectData
folder. This BTP file contains information for 3 materials but there is only relevant data on the EyeLid_v
material (the second one). In the other materials, the texture to be used in the animation is exactly the same on all frames.
(Fig. 1 - iceflick.btp
file opened on ImHex a hex editor, relevant data blocks are colored following the file structure mentioned above in the same order)
(Fig. 2 - Continuation of figure 2's color block names)
Notice how Padding 1
does not exist in this file as the Animation Table finishes on address 19B
. Address 19C
, the address in which more information can be then put, is already a multiple of 4 address. You can see better the behaviour with Padding 2
Also, the BTP Animation Length indicates that the animation of all materials will end after 53 frames so the animation length of all materials is 53 frames. 54 frames is the Animation Length for all materials on this particular BTP so every texture number data of the Texture Swap Table, except the last of each material texture swap data, is used for the actual BTP animation that will show in game.
CSV BTP file format
A normal CSV (Comma Separated Values) file that is humanly readable/editable and that is formatted so that the relevant/important information about the BIN BTP file can be stored on it. This format was got from the j3d animation editor program and, in my opinion, it is a very good intermediate file format for the BIN BTP file.
In Fig. 3 the CSV BTP file equivalent from the iceblick.btp
is shown in a normal text editor with their respective data blocks named. Each data block data purpose can be understood by using the BIN BTP file format table from above.
(Fig. 3 - iceblick.btp
CSV BTP equivalent)
Description of the numbers from Fig. 3:
- 1 - Loop Mode.
- 2 - BTP Animation Length.
- 3 - Not Used, always 0.
- 4 - CSV BTP ID, basically, the way to get that this CSV file is to be associated with a BTP animation.
- 5 - Animation keyframes from the Texture Swap Table: does not show on the original BIN BTP file format but it is useful since it can help you on how to setup the texture swap animation timings manually.
- 6 - Texture Swap Table data for each material to animate on the BTP.
- 7 - Material name (from the material to be animated).
- 8 - Animation Length for a Material.
- 9 - Texture Swap Table data section for a single material.
The j3d animation editor (this program came out first) and bean (I made this one >:]) programs are able to convert BIN BTPs into their respective CSV BTP equivalent and convert said CSV BTPs back to a BIN BTP file.
Notes for Super Mario Galaxy
In this section there will be information about how Super Mario Galaxy handles all of the data blocks mentioned above for a BTP file. Some might need futher investigation and some are just confusing. Either way, if you got more info about how JSYSTEM games treat BTP files open an issue here and let me know!
Details about the tests:
- These tests were done on a Wii console with Riivolution.
- Weird data was put on each block to see how the game reacted to it. The base file was the
blink.btp
animation file found on therosetta.arc
file (Rosalina's model) on theObjectData
folder of the game. The file was modified with the bean tool.
Notes:
GOOD
will be used to indicate that no matter what value is put on an specific data block position, the BTP will behave as intended in the game.HUH?
will be used to indicate that changing the value on a specific data block has some weird properties (that will be explained).DUNNO
will be used to indicate that changing the value on a specific data block has some weird properties (that I don't understand yet how to explain).FATAL
will be used to indicate that if the value on a specific data block is modified from the one (static) that is supposed to be there the game will absolutely crash.
DATA BLOCK | PROPERTIES |
---|---|
BTP file start | FATAL |
BTP ID | FATAL |
BTP file size | GOOD |
BTP section count |
HUH?
|
Unknown 1 | GOOD |
TPT1 section start |
HUH?
|
TPT1 section size | GOOD |
Loop Mode |
HUH?
|
Unknown 2 | GOOD |
BTP Animation Length |
HUH?
If loop mode is set to 2 (loop infinitely).
I would expect the above behaviour to happen as well with the other loop modes (adjusted to what the other loop modes do). |
Animated Material Count |
HUH?
BTP with one material only:
BTP with 2 materials:
This data block is the number of materials to be animated (and it does not have to be equal to the number of materials on the BTP file). If there are 3 materials and Animated Material Count is set to 2 only the first 2 materials on the BTP file will get its animation displayed on game. |
Material Animation Length Summation | GOOD |
TPT1 section offset | DUNNO |
Texture Swap Table offset | DUNNO |
Material Position Table offset | GOOD |
Material Name Table offset | DUNNO |
Animation Length for a Material |
HUH?
|
Material Animation Data Position |
HUH?
|
Unknown 3 |
HUH?
|
Unknown 4 | GOOD |
Texture Swap Number |
HUH?
|
Padding 1 | GOOD |
Material Position on BDL | GOOD |
Padding 2 | GOOD |
Animated Material Count (the repeated one) |
HUH?
|
Unknown 5 | GOOD |
Material String Weight | GOOD |
Material String Offset |
HUH?
|
Material Name String |
HUH?
|
Padding 3 | GOOD |