Nitro Files: Difference between revisions

From wiki.vg
Jump to navigation Jump to search
imported>Lexou Duck
No edit summary
imported>Cruiseliu
No edit summary
 
(15 intermediate revisions by 3 users not shown)
Line 18: Line 18:


Most 3D models found in Nintendo DS games use the following set of Nitro files:
Most 3D models found in Nintendo DS games use the following set of Nitro files:
- `NSBMD` (Nitro Model), which stores polygon models.
* `NSBMD` (Nitro Model), which stores polygon models.
- `NSBTX` (Nitro Texture), which stores texture image and palette data.
* `NSBTX` (Nitro Texture), which stores texture image and palette data.
- `NSBCA` (Nitro Character Animation), which stores skeletal animation data.
* `NSBCA` (Nitro Character Animation), which stores skeletal animation data.
- `NSBTP` (Nitro Texture Pattern anim), which stores texture-swap animations.
* `NSBTP` (Nitro Texture Pattern anim), which stores texture-swap animations.
- `NSBTA` (Nitro Texture Animation), which stores UV-change animations.
* `NSBTA` (Nitro Texture Animation), which stores UV-change animations.
- `NSBMA` (Nitro Material Animation), which stores material-swap animations.
* `NSBMA` (Nitro Material Animation), which stores material-swap animations.
- `NSBVA` (Unknown)
* `NSBVA` (Unknown)
----
----


Line 99: Line 99:
     ---- Data Info Section
     ---- Data Info Section
         ---- Sub-Header
         ---- Sub-Header
             0x00    2  u16 ;// Size of each Data entry, always = 4
             0x00    2  u16 ;// Size of each Data entry, usually = 4
             0x02    2  u16 ;// Size of this Data Info Section
             0x02    2  u16 ;// Size of this Data Info Section
         ---- Data (repeats * Amount of objects)
         ---- Data (repeats * Amount of objects)
Line 155: Line 155:
         0x18    1  u8  ;// Amount of Materials
         0x18    1  u8  ;// Amount of Materials
         0x19    1  u8  ;// Amount of Polygons
         0x19    1  u8  ;// Amount of Polygons
         0x20    4  u32 ;// Unknown
 
        0x1A    2  u16 ;// Unknown
        0x1C    4  u32 ;// Model scale?
         0x20    4  u32 ;// Bound scale?
 
         0x24    2  u8  ;// Amount of Vertices
         0x24    2  u8  ;// Amount of Vertices
         0x26    2  u8  ;// Amount of Surfaces
         0x26    2  u8  ;// Amount of Surfaces
Line 282: Line 286:


             ---- Material Definition (repeats * Amount of Materials)
             ---- Material Definition (repeats * Amount of Materials)
                 ;// Usually 48 bytes for each material
                 ;// Usually 44 (or 48?) bytes for each material
                0x00    2  u16 ;// Zero
                0x02    2  u16 ;// Size of this material
                0x04    28      ;// Unknown
                0x20    2  u16 ;// Width
                0x22    2  u16 ;// Height
                0x24    8      ;// Unknown
               


         ---- Polygon Section
         ---- Polygon Section
Line 366: Line 377:
             // The format is:
             // The format is:
             // bit:  15..............0
             // bit:  15..............0
             //    0 b --CFFFHHHWWW-----
             //    0 b --CFFFHHHWWW----
             // where:
             // where:
             // C = Palette ID
             // C = Palette ID
Line 584: Line 595:
};
};
</syntaxhighlight>
</syntaxhighlight>
[[Category:File Formats]]
[[Category:Model Formats]]

Latest revision as of 22:17, 21 September 2024

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 44 (or 48?) bytes for each material
               0x00    2   u16 ;// Zero
               0x02    2   u16 ;// Size of this material
               0x04    28      ;// Unknown
               0x20    2   u16 ;// Width
               0x22    2   u16 ;// Height
               0x24    8       ;// Unknown
               
       ---- 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>