The G3D Binary File format is the basic structure that all NNS G3D binary files follow.
Header#
The header of all NNS G3D binary files takes on the same structure. That is as follows:
Offset | Type | Meaning |
---|---|---|
0x00 | char[4] | File signature. This is a 4-character tag that identifies the file type. |
0x04 | u16 | Byte order mark. This is 0xFEFF in the endianness used. In practice only little endian byte order is used. |
0x06 | u16 | File version. The most significant 8 bits are the major version, and least significant 8 bits are the minor version. For most G3D files this will be 1.0. |
0x08 | u32 | File size. |
0x0C | u16 | Header size, not including the offset table. This is usually 0x10. |
0x0E | u16 | Number of blocks. |
0x10 | u32[...] | Offset array to blocks. |
Block Structure#
G3D files are composed of multiple binary blocks. They are structured in such a way that a decoder only needs to be aware of the structure of blocks relevant to it and can skip over other blocks. These are structured as follows:
Offset | Type | Meaning |
---|---|---|
0x00 | char[4] | Block signature. This is a 4-character tag identifying the type of block. |
0x04 | u32 | Block size. This is the size of the whole block, including this header. |
G3D is less permissive than G2D with what blocks are allowed to be in a file. Where G2D makes no assumptions about the order and presence of certain blocks, G3D only allows particular blocks to be present in binary files.
Dictionaries#
A feature common to G3D files is their use of dictionaries to name resources. These map names (of up to 16 characters long) to a resource in the file. The structure of a dictionary is shown here:
Offset | Type | Meaning |
---|---|---|
0x00 | u8 | Revision (should be 0) |
0x01 | u8 | Number of entries |
0x02 | u16 | Size of the dictionary |
0x04 | u16 | |
0x06 | u16 | Offset to dictionary entries, relative to the start of this structure. |
0x08 | ... | Patricia tree nodes |
To speed up the resource lookup process, dictionaries include a Patricia tree. These are used when there are more than 16 resources present in a dictionary, and allows for lookup in O(log n) time. The structure of these nodes is as follows:
Offset | Type | Meaning |
---|---|---|
0x00 | u8 | Reference bit. |
0x01 | u8 | Left node index. |
0x02 | u8 | Right node index. |
0x03 | u8 | Entry index. |
The reference bit of the tree node refers to the particular bit index in the resource name. This is extracted like:
int bit = (((const u32 *) resName)[refBit % 32] >> (refBit % 32)) & 1;
The dictionary entries immediately follow the Patricia tree. The format of these depends on the file format. The dictionary entry starts with the following header:
Offset | Type | Meaning |
---|---|---|
0x00 | u16 | Size of each dictionary entry |
0x02 | u16 | Offset to names, relative to the start of this structure. |
0x04 | ... | Dictionary entries |
... | char[...][16] | Resource name table (names 0-padded to 16 bytes). |