Nitro Files

From wiki.vg
Revision as of 20:51, 21 September 2024 by imported>Cruiseliu
Jump to navigation Jump to search

Nitro Studio Files Specification

Current status

This specification is far from complete, and it may contain errors, since it is the result of reverse-engineering.

  • 11 August 2007 - First published by kiwi.ds@gmail.com
  • 16 April 2019 - Published on the apicula github wiki
  • 19 April 2019 - Added information from LowLines' ConsoleTool doc


0. Introduction

Most 3D models found in Nintendo DS games use the following set of Nitro files:

  • `NSBMD` (Nitro Model), which stores polygon models.
  • `NSBTX` (Nitro Texture), which stores texture image and palette data.
  • `NSBCA` (Nitro Character Animation), which stores skeletal animation data.
  • `NSBTP` (Nitro Texture Pattern anim), which stores texture-swap animations.
  • `NSBTA` (Nitro Texture Animation), which stores UV-change animations.
  • `NSBMA` (Nitro Material Animation), which stores material-swap animations.
  • `NSBVA` (Unknown)

0.1 Terminology

File format is explained in C-style struct declaration. The following types of variables are used:

<syntaxhighlight lang="c"> s8 1 byte // signed char s16 2 bytes // signed short s32 4 bytes // signed long u8 1 byte // unsigned char u16 2 bytes // unsigned short u32 4 bytes // unsigned long text n bytes // ASCII char string

// The general format for every data field outlined here is

----- ----- ;// ----------------------------------

Offset Size Type ;// Description


----- ----- ;// ----------------------------------

0x00 4 u32  ;// Example </syntaxhighlight>


0.2 Nitro Standard File Header

Many files (besides sound-related) found in DS ROMs share this header structure:

<syntaxhighlight lang="c"> /*

    • This is the standard DS Nitro header format: any nitro file starts with this.
  • /

typedef struct Nitro_Header {

   0x00    4   text;// File identifier: can be 'SDAT', 'BMD0', 'BTX0', 'BCA0', etc...
   0x04    4   u32 ;// Magic stamp: is either 0x0001FEFF or 0x0002FEFF
   0x08    4   u32 ;// Size of this file (including this struct)
   0x0C    2   u16 ;// Size of this structure (always 16)
   0x0E    2   u16 ;// Amount of Blocks
   ---- Offsets (repeats * Amount of Blocks)
       0x00    4   u32 ;// Block offset #1
       0x04    4   u32 ;// Block offset #2
       etc

}; </syntaxhighlight>


0.3 General Data Sub-header

In addition to the Standard File Header, the following format of "sub-header" is encountered often in NSB__ files:

<syntaxhighlight lang="c"> /*

    • This is the format of the general-purpose headers that are used in many places within nitro files.
  • /

typedef struct Header {

   0x00    1   u8  ;// dummy 0
   0x01    1   u8  ;// Amount of objects
   0x02    2   u16 ;// Size of this Header
   ---- Unknown Section
       ---- Sub-Header
           0x00    2   u16 ;// Size of this Sub-Header, always = 8
           0x02    2   u16 ;// Size of this Unknown Section
           0x04    4   u32 ;// Constant = 0x0000017f
       ---- Unknown Data (repeats * Amount of objects)
           0x08    4   u32 ;// Unknown
           0x0C    4   u32 ;// ...
           etc
   ---- Data Info Section
       ---- Sub-Header
           0x00    2   u16 ;// Size of each Data entry, usually = 4
           0x02    2   u16 ;// Size of this Data Info Section
       ---- Data (repeats * Amount of objects)
           0x04    n   ??? ;// The Data stored here is used for several different things, explained when used.
           0x04+n  n   ??? ;// ...
           etc
   ---- Name Section (repeats * Amount of objects)
       0x00    16  text;// Name of Model
       0x10    16  text;// ...
       etc

}; </syntaxhighlight>


1. NSBMD Format

It has one or two blocks - 'MDL0' and 'TEX0'.

'MDL0' block is usually found at offset 0x14 (depending on how many block_offsets there are before it)

The 'MDL0' block can potentially be followed by a 'TEX0' block, or otherwise the 'TEX0' block is defined in an external NSBTX file.

1.1 'MDL0' Block

<syntaxhighlight lang="c"> NSBMD


struct Nitro_Header;// File identifier is 'BMD0' (Basic Model Data)

typedef struct Block_MDL0 {

   0x00    4   u32 ;// Block identifier: 'MDL0' (Model Block)
   0x04    4   u32 ;// Block size
   struct Header;// Model Header: one Header object for each model
   {// The 'Data' for this Header is like so:
       0x00    4   u32 ;// The offset of Model_1, relative to the start of Block_MDL0
   }
   ---- Model_1 (All offsets are relative to this Model_1 section)
       0x00    4   u32 ;// Size of Model_1 (including these 4 bytes)
       0x04    4   u32 ;// Offset of Additional Model Data
       0x08    4   u32 ;// Offset of Texture & Palette Offset
       0x0C    4   u32 ;// Offset of Display List Start
       0x10    4   u32 ;// Offset of Display List End
       0x14    1   u8  ;// Unknown
       0x15    1   u8  ;// Unknown
       0x16    1   u8  ;// Unknown
       0x17    1   u8  ;// Amount of Objects
       0x18    1   u8  ;// Amount of Materials
       0x19    1   u8  ;// Amount of Polygons
       0x1A    2   u16 ;// Unknown
       0x1C    4   u32 ;// Model scale?
       0x20    4   u32 ;// Bound scale?
       0x24    2   u8  ;// Amount of Vertices
       0x26    2   u8  ;// Amount of Surfaces
       0x28    2   u8  ;// Amount of Triangles
       0x2A    2   u8  ;// Amount of Quads
       0x2C    2   s16 ;// Bounding box X (signed fixed point 1.3.12)
       0x2E    2   s16 ;// Bounding box Y (signed fixed point 1.3.12)
       0x30    2   s16 ;// Bounding box Z (signed fixed point 1.3.12)
       0x32    2   s16 ;// Bounding box Width  (signed fixed point 1.3.12)
       0x34    2   s16 ;// Bounding box Height (signed fixed point 1.3.12)
       0x36    2   s16 ;// Bounding box Depth  (signed fixed point 1.3.12)
       0x38    4   u32 ;// Runtime use data
       0x3C    4   u32 ;// Runtime use data
       struct Header;// Object Header: one Header object for each Polygonal Object
       {// The 'Data' for this Header is like so:
           0x00    4   u32 ;// The offset of Object Definition, relative to the start of this Object Header
       }
       ---- Object Definition (repeats * Amount of objects)
           In each definition:
           0x00    1   u8  ;// Transform Flag byte
           0x01    1   u8  ;// Unknown
           0x02    1   u8  ;// Unknown
           0x03    1   u8  ;// Unknown
           // The Transform Flag byte is set up like so:
           //     bits: 7.......0
           //        0b NNNN PSRT
           //
           // T:  if set, Translation = Identity (No Translation)
           //     if = 0, then 12 bytes follow:
           //          0x04    4   s32 ;// Translation X (signed fixed point 1.3.12)
           //          0x08    4   s32 ;// Translation Y (signed fixed point 1.3.12)
           //          0x0C    4   s32 ;// Translation Z (signed fixed point 1.3.12)
           // R:  if set, Rotation = Zero (No Rotation)
           //     if = 0, then depends on the 'P' bit.
           // S:  if set, Scale = Identity (No Scale)
           //     if = 0, then 12 bytes follow:
           //          0x04    4   s32 ;// Scale X (signed fixed point 1.3.12)
           //          0x08    4   s32 ;// Scale Y (signed fixed point 1.3.12)
           //          0x0C    4   s32 ;// Scale Z (signed fixed point 1.3.12)
           // P:  if = 0 and R = 0, then 16 bytes follow:
           //          0x00    4   s32 ;// Rotation A
           //          0x04    4   s32 ;// Rotation B
           //          0x08    4   s32 ;// Rotation C
           //          0x0C    4   s32 ;// Rotation D
           //     if set, Pivot exists- so 4 bytes follow:
           //          0x04    2   s16 ;// value A (signed fixed point 1.3.12)
           //          0x06    2   s16 ;// value B (signed fixed point 1.3.12)
           //     NNNN = Pivot matrix type (0..8)
           //     0:  | 1  0  0|  1:  | 0  1  0|  2:  | 0  0  1|
           //         | 0  A  B|      | A  0  B|      | A  B  0|
           //         | 0  B -A|      | B  0 -A|      | B -A  0|
           //
           //     3:  | 0  A  B|  4:  | A  0  B|  5:  | A  B  0|
           //         | 1  0  0|      | 0  1  0|      | 0  0  1|
           //         | 0  B -A|      | B  0 -A|      | B -A  0|
           //
           //     6:  | 0  A  B|  7:  | A  0  B|  8:  | A  B  0|
           //         | 0  B -A|      | B  0 -A|      | B -A  0|
           //         | 1  0  0|      | 0  1  0|      | 0  0  1|
       ---- Bone/Skeleton Section
           0x00    ?   definitions;
           // Each definition consists of 1 Command Byte + Parameters. Each Parameter is 1 byte.
           // 
           // Command  Params  Description
           // 0x06     3       params: Object ID, Parent ID, dummy 0
           // 0x26     4       params: Object ID, Parent ID, dummy 0, Stack ID
           // 0x46     4       params: Object ID, Parent ID, dummy 0, Stack ID
           // 0x66     5       params: Object ID, Parent ID, dummy 0, Stack ID, Restore ID
           // 
           // 0x00     0       NOP (empty command)
           // 0x01     0       End of Bone/Skeleton Section
           // 0x02     2       params: Node ID, Visibility
           // 0x03     1       Set Polygon Stack ID?
           // 0x04     3       params: Material ID, 0x5, Polygon ID
           // 0x05     1       ??
           // 0x06     3       params: Object ID, Parent ID, Dummy 0
           // 0x07     1       ??
           // 0x08     1       ??
           // 0x09     8       ??
           // 
           // 0x0B     0       BEGIN (indicate begin of Polygon/Material pairing)
           // 0x2B     0       END (indicate end of Polygon/Material pairing)
           // 
           // These are Material/Polygon pairing commands, 4 bytes.
           // The lower nibble of 2nd Paramter must be 5.
           // 0x04     3       Material ID, 05, Polygon ID
           // 0x24     3       ...
           // 0x44     3       ...
       ---- Texture & Palette Offset
           0x00    2   u16 ;// Offset of Texture Section (relative to Texture & Palette Offset)
           0x02    2   u16 ;// Offset of Palette Section (relative to Texture & Palette Offset)
       ---- Material Section
           struct Header;// Material Header: one Header object for each material
           {// The 'Data' for this Header is like so:
               0x00    4   u32 ;// The offset of Material Definition, relative to the start of this Material Section
           }
           ---- Texture Section
               struct Header;// Texture Header: one Header object for each texture
               {// The u32 'Data' for this Header is like so:
                   0x00    2   u16 ;// Offset of Matching Data (relative to Texture & Palette Offset)
                   0x02    2   u16 ;// Amount of associated Materials (a texture can be in more than one material)
               }
           ---- Palette Section
               struct Header;// Palette Header: one Header object for each palette
               {// The u32 'Data' for this Header is like so:
                   0x00    2   u16 ;// Offset of Matching Data (relative to Texture & Palette Offset)
                   0x02    2   u16 ;// Amount of associated Materials (a palette can be in more than one material)
               }
           ---- Material Definition (repeats * Amount of Materials)
               ;// Usually 48 bytes for each material
       ---- Polygon Section
           struct Header;// Polygon Header: one Header object for each material
           {// The 'Data' for this Header is like so:
               0x00    4   u32 ;// The offset of Polygon Definition, relative to the start of this Polygon Section
           }
           ---- Polygon Definition (repeats * Amount of Polygons)
               0x00    4   u32 ;// 
               0x04    4   u32 ;// 
               0x08    4   u32 ;// Offset of Display List, relative to Polygon Definition, see below
               0x0c    4   u32 ;// Size of Display List
               0x10    4   u32 ;// 
               0x14    4   u32 ;// 
               0x18    4   u32 ;// Offset of Display List, relative to Polygon Definition, see below
               0x1c    4   u32 ;// Size of Display List
               ...
           ---- Display List
               // The Display List is actually packed geometry command.
               // See the DStek specification for more information:
               // http://www.akkit.org/info/gbatek.htm#ds3dvideo
   ---- Model_2
       ...

}; </syntaxhighlight>


2. NSBTX Format

The NSBTX file format stores texture image and palette information.

2.1 'TEX0' Block

The 'TEX0' Block can be found in certain NSBMD files, not just in NSBTX files.

<syntaxhighlight lang="c"> NSBTX


struct Nitro_Header;// File identifier is 'BTX0' (Basic Texture)

typedef struct Block_TEX0 {

   0x00    4   u32 ;// Block identifier: 'TEX0' (Texture Block)
   0x04    4   u32 ;// Block size
   ---- Texture Header
       0x08    4   u32 ;// Padding (= 0)
       0x0C    2   u16 ;// Texture Data Size (bitshift << 3)
       0x0E    2   u16 ;// Texture Info Offset (0x3C)
       0x10    4   u32 ;// Padding (= 0) 
       0x14    4   u32 ;// Texture Data Offset
       0x18    4   u32 ;// Padding (= 0) 
       0x1C    2   u16 ;// Compressed Texture Data Size (bitshift << 3)
       0x1E    2   u16 ;// Compressed Texture Info Offset (0x3C)
       0x20    4   u32 ;// Padding (= 0)
       0x24    4   u32 ;// Compressed Texture Data Offset
       0x28    4   u32 ;// Compressed Texture Info Data Offset
       0x2C    4   u32 ;// Padding (= 0)
       0x30    4   u32 ;// Palette Data Size (bitshift << 3)
       0x34    4   u32 ;// Palette Info Offset
       0x38    4   u32 ;// Palette Data Offset
   ---- Texture Info Section
       struct Header;// Texture Header: one Header object for each texture
       {// The u32 'Data' for this Header is like so:
           0x00    2   u16 ;// (bitshift << 3) Texture Offset, relative to the start of Texture Data
           0x02    2   u16 ;// Parameters
           // The format is:
           // bit:  15..............0
           //    0 b --CFFFHHHWWW----
           // where:
           // C = Palette ID
           // F = Format (0-7)
           // H = Height (8 << Height)
           // W = Width (8 << Width)
           // 
           // To Calculate the Data Size of a Texture:
           // Bit Depth = Format:<0, 8, 2, 4, 8, 2, 8, 16>
           // Width * Height * BitDepth / 8
           0x04    1   u8  ;// Width (should match W << 3)
           0x05    1   u8  ;// Unknown (is 0x00 or 0x80)
           0x06    1   u8  ;// Height? (can be 0, 1, 2, 4, 8)
           0x07    1   u8  ;// Unknown (is 0x80)    
       }
   ---- Palette Info Section
       struct Header;// Palette Header: one Header object for each palette
       {// The u32 'Data' for this Header is like so:
           0x00    2   u16 ;// (bitshift << 3) Palette Offset, relative to the start of Palette Data
           0x00    2   u16 ;// Unknown (is 0 or 1)
       }
   ---- Texture Data Section
   ---- Compressed Texture Data Section
   ---- Compressed Texture Info Data Section
   ---- Palette Data Section

}; </syntaxhighlight>


3. NSBCA Format

The NSBCA file format stores character skeletal animation data.

3.1 'JNT0' Block

The 'JNT0' Block can be found in NSBCA files, it stores bone/joint animation data.

<syntaxhighlight lang="c"> NSBCA


struct Nitro_Header;// File identifier is 'BCA0' (Basic Character Animation)

typedef struct Block_JNT0 {

   0x00    4   u32 ;// Block identifier: 'JNT0' (Joint Block)
   0x04    4   u32 ;// Block size
   struct Header;// Joint Header: one Header object for each joint
   {// The 'Data' for this Header is like so:
       0x00    4   u32 ;// The offset of Joint_1, relative to the start of Block_JNT0
   }
   ---- Joint Section (repeats * Amount of Objects)
       0x00    4   u32 ;// Magic Stamp 'J.AC' (Joint Animation Content ?)
       0x04    2   u16 ;// Amount of Frames        
       0x06    2   u16 ;// Amount of Objects being animated. Should equal to the number of Objects in a model.
       0x08    4   u32 ;// Unknown  
       0x0C    4   u32 ;// Offset to Offset1 chunk. Relative to start of this block.
       0x10    4   u32 ;// Offset to Offset2 chunk. Relative to start of this block.
       0x14    4   u32 ;// Object Info Offset (repeats * Amount of Objects), relative to start of this Joint Section.
       ---- Object Info - Repeats * Number of Objects
           0x00    2   u16 ;// Flag - Indicates what sort of Transformations are applied.
           // The format is:
           // bit:  15..............0
           //    0 b --zyx-Sr-RZYX-T-
           // T is Translation
           // R is Rotation
           // S is Scale
           // If these bits are cleared, transformation data follows.
           //  X, Y, Z, r, x, y, z are flags that identify how the data is stored.
           0x02    1   u32 ;// Unknown
           0x03    1   u32 ;// ID Number
       ---- Transformation Info (Translation XYZ, Rotation, Scale XYZ) when set
           0x00    4   u32 ;// Actual value.
       ---- Transformation Info (Translation XYZ, Rotation, Scale XYZ) when cleared
           0x00    2   u16 ;// Unknown - typically 0.
           0x02    2   u16 ;// Unknown 
           0x04    4   u32 ;// Offset to data. Relative to end Object Info Header (Object Info Offset + 4).
   ---- Offset1 Chunk - Repeats until Offset2
       0x00    2   u16 ;// I've seen 36, 32 & 0.
       0x02    2   s16 ;// Unknown
       0x04    2   s16 ;// Unknown
   ---- Offset2 Chunk - Repeats until end of file
       // All transformation offsets point somewhere in this section.
       // It's clearly broken up into parts (Translation, Rotation & Scale) however I'm not totally sure how data is store in here yet.

}; </syntaxhighlight>


4. NSBTP Format

The NSBTP file format stores texture pattern animation data.

4.1 'PAT0' Block

The 'PAT0' Block can be found in NSBTP files, it stores pattern animation data.

<syntaxhighlight lang="c"> NSBTP


struct Nitro_Header;// File identifier is 'BTP0' (Basic Texture Pattern animation)

typedef struct Block_PAT0 {

   0x00    4   u32 ;// Block identifier: 'PAT0' (Pattern Block)
   0x04    4   u32 ;// Block size
   // Unknown beyond this point

}; </syntaxhighlight>


5. NSBTA Format

The NSBTA file format stores texture animation data.

5.1 'SRT0' Block

The 'SRT0' Block can be found in NSBTA files, texture animation data.

<syntaxhighlight lang="c"> NSBTA


struct Nitro_Header;// File identifier is 'BTA0' (Basic Texture Animation)

typedef struct Block_SRT0 {

   0x00    4   u32 ;// Block identifier: 'SRT0' (??? Block)
   0x04    4   u32 ;// Block size
   // Unknown beyond this point

}; </syntaxhighlight>


6. NSBMA Format

The NSBMA file format stores material animation data.

6.1 'MAT0' Block

The 'MAT0' Block can be found in NSBMA files, it stores material animation data.

<syntaxhighlight lang="c"> NSBMA


struct Nitro_Header;// File identifier is 'BMA0' (Basic Material Animation)

typedef struct Block_MAT0 {

   0x00    4   u32 ;// Block identifier: 'MAT0' (Material Block)
   0x04    4   u32 ;// Block size
   // Unknown beyond this point

}; </syntaxhighlight>


7. NSBVA Format

The NSBVA file format stores general-purpose value animation data perhaps ..?

7.1 'VIS0' Block

The 'VIS0' Block can be found in NSBVA files, it stores value animation data perhaps ..?

<syntaxhighlight lang="c"> NSBVA


struct Nitro_Header;// File identifier is 'BVA0' (Basic ??? Animation)

typedef struct Block_VIS0 {

   0x00    4   u32 ;// Block identifier: 'VIS0' (??? Block)
   0x04    4   u32 ;// Block size
   // Unknown beyond this point

}; </syntaxhighlight>