Hack64 Wiki
Other Titles
Hack64 Wiki
Other Titles
Banjo-Kazooie uses a file-system in which most resources are packed into file blocks throughout the ROM, and are unpacked into RAM when needed. Among these are the model files, each with their own syntax and load-lines. This page's purpose is to cover the syntax and properties of said model files.
Address | Value/Syntax | Description |
---|---|---|
0x00000000 | [00 00 00 0B] | START |
0x00000004 | [aa aa aa aa] | Geometry Layout Offset |
0x00000008 | [bb bb cc cc] | bb=Texture Setup Offset (Usually 00 38), cc=Geo Type* |
0x0000000C | [dd dd dd dd] | Display List Setup Offset |
0x00000010 | [ee ee ee ee] | Vertex Store Setup Offset |
0x00000014 | [00 00 00 00] | ? - Pertains to hitboxes |
0x00000018 | [ff ff ff ff] | Animation Setup |
0x0000001C | [gg gg gg gg] | Collision Setup |
0x00000020 | [hh hh hh hh] | Effects Setup End Address |
0x00000024 | [hh hh hh hh] | Effects Setup |
0x00000028 | [00 00 00 00] | ? |
0x0000002C | [jj jj jj jj] | Animated Textures Offset |
0x00000030 | [kk kk ll ll] | kk= Tri count, ll= vert count |
0x00000034 | [00 00 00 00] | ? |
*Geo Types: 0000=normal, 0002= Trilinear MipMapping (RGBA16), 0004=Env mapping, 0006=Trilinear MipMapping (RGBA16) + Environment Mapping
The Texture Setup begins with a Header of Size 0x08:
Offset within TexSetup | Value/Syntax | Description |
---|---|---|
0x00000000 | [aa aa aa aa] | Size of DataSection in Bytes |
0x00000004 | [cc cc] 00 00 | Texture Count |
Afterwards, an array of Meta-Information Elements follows (Tex MetaSection), where Texture parameters are stored.
Each Meta Element is 0x10 Bytes large, and structured like this:
[dd dd dd dd] [ee ee] 00 00 [ww] [hh] 00 00 00 00
Value/Syntax | Description |
---|---|
[dd dd dd dd] | Offset of TexData from Tex DataSection Start |
[ee ee] | Type* of corresponding TexData |
[ww] [hh] | Width and Height of TexData |
* the types used in BK are the following:
Value | TexType | Palette | Bits / Pixel | Color-Format |
---|---|---|---|---|
0x01 | CI4 | 0x20 | 4 | RGBA5551 |
0x02 | CI8 | 0x200 | 8 | RGBA5551 |
0x04 | RGBA16 | - | 16 | RGBA5551 |
0x08 | RGBA32 | - | 32 | RGBA8888 |
0x10 | IA8 | - | 8 | I4A4 |
External texture indices start at FileID 0x1EF6, 0 indexed.
Example: 00 00 06 00 00 01 00 00 40 40 00 00 00 00 00 00 This sets up a 64x64 CI4 Texture from 0x600 Bytes after the DataSection starts.
And finally, a List of the actual Data Elements follows (Tex DataSection).
Note that there might be additional Data Elements inbetween, if the Texture is mipmapped or animated.
Offset from DLSetup Start | Value/Syntax | Description |
---|---|---|
0x00000000 | [aa aa aa aa 00 00 00 00] | F3DEX Command Count |
0x00000008 | F3DEX | F3DEX Display List |
Offset from VTXSetup Start | Value/Syntax | Description |
---|---|---|
0x00000000 | [aa aa bb bb cc cc] | s16[3] Minimum Coords |
0x00000006 | [dd dd ee ee ff ff] | s16[3] Maximum Coords |
0x0000000C | [gg gg hh hh ii ii] | s16[3] Center Coords |
0x00000012 | [kk kk] | s16 Largest Distance to Center |
0x00000014 | [ll ll] | u16 Vertex Count*2 |
0x00000016 | [mm mm] | s16 Largest Distance to Origin |
Each 16 byte line of the Vertex Setup following the Start denotes where a vertex is stored in 3D space, from where in 2D space its UVs begin being mapped, and which color and opacity alpha values will be applied to these vertices. Pulled from RCP Structures for context.
It is stored like this:
[xx xx yy yy zz zz 00 00 uu uu vv vv rr gg bb aa]
Vertex Structure After Start | Value/Syntax | Description |
---|---|---|
0x00000000 | [xx xx] | *s16 Vertex Position on X Axis |
0x00000002 | [yy yy] | s16 Vertex Position on Y Axis |
0x00000004 | [zz zz] | s16 Vertex Position on Z Axis |
0x00000006 | 00 00 | Padding(?) |
0x00000008 | [uu uu] | s16 UV Coordinates: U Axis |
0x0000000A | [vv vv] | s16 UV Coordinates: V Axis |
0x0000000C | [rr] | u8 Vertex Color Red Values |
0x0000000D | [gg] | u8 Vertex Color Green Values |
0x0000000E | [bb] | u8 Vertex Color Blue Values |
0x0000000F | [aa] | u8 Vertex Color Alpha Values |
*Please note that s16
refers to 'signed short'; a value which may be positive or negative and takes 16 bits of space. Positive signed values range from 0x0000 to 0x7FFF, negative signed values range from 0xFFFF to 0x8000. Whereas u8
refers to an 'unsigned byte' value that may only be a positive integer from 0x00 to 0xFF.
Example: 0014 0062 FFE7 0000 FFE0 0014 9292 92FF
A vertex will be drawn at position (20, 98, -25). UV mapping will begin at -20 coordinates in the U axis and 20 coordinates in the V axis. This vertex will feature a color of #929292 with full opacity alpha of 0xFF or 255.
The animation setup rigs bones to a model and anchors them to the origin, or the parent bone (0xFFFF). It is comprised of two sections: A header, and a bone setup.
Animation Header
Offset from Animation Setup | Value Syntax | Description |
---|---|---|
0x0000 | [aa aa aa aa] | Scaling Factor (float) |
0x0004 | [bb bb] | Bone Count |
0x0006 | [00 00] | Padding / Unk |
Example (74a8.bin, Slappa at address 0x2ca8):
42 34 00 00 00 19 00 00
Sets the scaling factor as 45 (0x42340000) and sets the bone count as 25 (0x19).
Bone Setup
Offset following Animation Header | Value Syntax | Description |
---|---|---|
0x0000 | [xx xx xx xx] | X Position of Bone (float) |
0x0004 | [yy yy yy yy] | Y Position of Bone (float) |
0x0008 | [zz zz zz zz] | Z Position of Bone (float) |
0x000C | [ii ii] | Internal Bone ID |
0x000E | [pp pp] | Parent Bone ID |
Example (74a8.bin, Slappa at address 0x2cb0):
BF 8E 23 70 C3 2D 44 F0 40 FC 92 09 00 05 FF FF
Assigns a bone to the model at coordinates (-1.11, -173.27, 7.89), gives it an Internal Bone ID of 5 (0x5) and connects that bone to Parent Bone -1 (0xFFFF). This case just so happens to be the origin.
The Collision Setup begins with a Header of Size 0x18:
Offset within CollSetup | Value/Syntax | Description |
---|---|---|
0x00000000 | [xx xx yy yy zz zz ] | s16[3] Minimum GeoCube Index |
0x00000006 | [xx xx yy yy zz zz ] | s16[3] Maximum GeoCube Index |
0x0000000C | [vv vv ] | u16 Y Stride - GeoCubes per X-Row |
0x0000000E | [ww ww ] | u16 Z Stride - GeoCubes per XY-Layer |
0x00000010 | [cc cc ] | u16 Total amount of GeoCubes |
0x00000012 | [ss ss ] | u16 GeoCube Scale |
0x00000014 | [tt tt ] | u16 Total amount of Collision Tris |
0x00000016 | [00 00 ] | Padding |
The entire map is split up into 3D GeoCubes that all share the same scale 0xSSSS^3
. They are set up in a 3D matrix, such that the GeoCube (0,0,0) is stretching from the coordinates (0,0,0) to (0xSSSS, 0xSSSS, 0xSSSS). In Memory, the GeoCubes are stored as a 1D array, where the Y and Z strides are used for the pointer arithmetic of referencing the correct cube:
cube_arr[cube_x][cube_y][cube_z] == cube_arr[cube_x + (cube_y * stride_y) + (cube_z * stride_z)] == cube_arr[cube_ID]
Following the Header, we have a list of 0xCCCC GeoCube instances of Size 0x08, looking like this:
Value/Syntax | Description |
---|---|
[aa aa ] | u16 Starting Tri ID |
[cc cc ] | u16 Tri Count |
These are referring to a Subset [start : (start + count))
of Collision Tris from the then following Collision Tri list. This list contains 0xTTTT Collision Triangles, of Size 0x0C, which are structured like this in BK:
Value/Syntax | Description |
---|---|
[aa aa ] | u16 Vertex ID 1 |
[bb bb ] | u16 Vertex ID 2 |
[cc cc ] | u16 Vertex ID 3 |
[uu uu ] | unknown |
[ii ii ii ii ] | u32 Sound + Collision Flags |
Where every Triangle is defined by the 3 indices as 1-2-3, which is important to determine its front facing direction.
The Effects Setup for Level and Actor bins functions very similar to the Effects Setup used in Banjo-Tooie only with fewer effects to use. Effects types only go up to 10 types with several unknowns. Level models can have texture scroll, though actors and objects do not appear to have the same luxury. Some actors like Teehee & Twinklies have “specially assigned” effects. There may be more at play that determines how effects are activated.
Offset from Effects Setup | Value/Syntax | Description |
---|---|---|
0x00 | [aa aa] | Effect Count |
0x02 | [bb bb] | Data Start + Param |
0x04 | [cc cc] | Vertex Count |
0x06 | [dd dd] | Vertex Referenced from Vtx Store following Start |
Effect IDs are
Data Start = 100*Type + Param (decimal)
where param is used to control the speed or amplitude of the effect. For Data Start in the table, param used is 0 and can range from 0-63. Type is taken from
Type | Data Start | Description |
---|---|---|
0 | 0x000 | ?? - Used in the Sandcastle and Furnace Fun |
1 | 0x064 | Texture scrolling (along vertical axis). Param dictates speed [6A - Slow, 78 - Medium, A0 - Fast] |
2 | 0x0C8 | Flickering vertex color, for fake lighting around flames |
3 | 0x12C | Oscillating texture scrolling + vertical bob. Param affects bob height. |
4 | 0x190 | Seems to trigger geometry to move (possibilities include squash, move). Additional param will crash game. |
5 | 0x1F4 | Vertex color regularly gets brighter and dimmer. Param dictates speed of glow. |
6 | 0x258 | ?? - Used in Furnace Fun |
7 | 0x2BC | Rippling wave generation, amplitude controlled by bounding box of affected vertices, speed of wave dictated by param. |
8 | 0x320 | Vertex alpha regularly gets brighter and dimmer. Param dictates speed of glow. |
9 | 0x384 | Adds lightning sound effect, no visible change. Param does not seem to affect sound speed. Could be alpha related. |
Example (10238.bin, GV Model A):
0003 0078 006A 0010 0011 0012 0013 0014 […] 0605 00AA 0015 06AC […] 06C0 0190 0007 0182 […] 018A 0000 0000 0000
Loads 3 (0x03) effects:
There is a 4 or 6 byte padding buffer at the end of most effects setups.
If the model's animated_textures_offset is non-zero, the animated texture list is an array of 4 of the following struct:
Offset | Value/Syntax | Type | Description |
---|---|---|---|
0x00 | [aa aa] | i16 | Frame size (bytes) : 0 if unused |
0x02 | [bb bb] | i16 | Frame count |
0x04 | [cc cc cc cc] | f32 | Framerate (fps) |
Note that in order for textures to be animated, all texture data for each frame must be present in the texture section and stacked sequentially. Only the 1st texture in the data stack is displayed and animated, however it can animate through the texture data stack with 4 different framecounts/framerates. You can determine which textures are being animated by checking the segmented value of the FD Set_T_Img display list command for that texture. For Banjo-Kazooie, the segmented value can be
0xF, 0xE, 0xD, or 0xC
.
This Setup consists of a List of GeoLayout Commands. There is no Header in this Setup.
The Reference-Point Command (0x0A
) appears to be used to determine what Banjo should look at when solving a Jigsaw. The Reference-Point Index is set to 0x1E
in that case, and the Bone-Index is always 0xFFFF
(-1) connecting the Point to the origin. Therefor the XYZ Coordinates that are included in the Command represents the actual Position of the Reference-Point within the Map. If a second Jigsaw is in the same Room, it gets the Index 0x1F
instead, which is the case for the CC and RBB Jigsaws.