CGFX

CGFX

CGFX is a container format used to store graphics resources. It can contain 3D models, textures and animation data.

CGFX #

CGFX header :

OffsetLengthDescription
0x00x4Magic “CGFX”
0x40x2Byte order mark: FFFE (little endian) or FEFF (big endian)
0x60x2CGFX header size
0x80x4Revision
0xC0x4File size (bytes)
0x100x4Number of entries

A typical CGFX file contains two main entries, beginning directly after the CGFX header: DATA and IMAG.

DATA #

DATA contains a list of DICT references.

DATA header (for N = 0..15) :

OffsetLengthDescription
0x00x4Magic “DATA”
0x40x4DATA Size (in bytes)
0x8 +(N*8)0x4Number of entries in DICT N
0xC +(N*8)0x4Offset (self-relative) to DICT N

The DATA header contains the entry counts and offsets for each DICT entry. The number of entries can vary (probably based on the version?), but are always in the following order. Any unused entries are zeroed.

Typical entries:

NType
0Models
1Textures
2LUTS (Material/Color/Shader look-up tables?)
3Materials
4Shaders
5Cameras
6Lights
7Fog
8Environments
9Skeleton animations
10Texture animations
11Visibility animations
12Camera animations
13Light animations
14Emitters
15Unknown

DICT #

DICTs are generic structures used to store values (and associate them to a key ?). A DICT header is 0x1C bytes long.

DICT header :

OffsetLengthDescription
0x00x4Magic “DICT”
0x40x4DICT size (in bytes)
0x80x4Number of entries
0xC0x4?
0x100x2Unknown. Seems to be shifted left by 4 bits in the source.
0x120xA?

DICT entry:

OffsetLengthDescription
0x00x4?
0x40x2?
0x60x2?
0x80x4Offset (self-relative) to symbol
0xC0x4Offset (self-relative) to object

CMDL #

CMDL is used to describe a 3D model.

CMDL Header :

OffsetLengthDescription
0x00x4Flags (bit 7: hasSkeletonSobj)
0x40x4Magic “CMDL”
0x80x4?
0xC0x4Offset (self-relative) to model name
0x100x18?
0x280x4Number of entries in Animation Types DICT
0x2C0x4Offset (self-relative) to Animation Types DICT
0x300xCGlobal scale vector (3 floats : x, y, z)
0x3C0x18?
0x540x30Matrix 1
0x840x30Matrix 2
0xB40x4Number of Vertex Info SOBJ entries
0xB80x4Offset (self-relative) to Vertex Info SOBJ list
0xBC0x4Number of MTOB DICT entries
0xC00x4Offset (self-relative) to MTOB DICT
0xC40x4Number of Vertex Info SOBJ entries
0xC80x4Offset (self-relative) to Vertex Info SOBJ list
0xCC0x4Number of Unknown DICT entries
0xD00x4Offset (self-relative) to Unknown DICT
0xD40xC?
0xE00x4Skeleton Info SOBJ offset (self-relative) [only present if flag bit 7 is set]
0xB8+[0xB8]0x4*NVertex Info SOBJ self-relative offset list

A CMDL section refers to outside data; it can not be considered separately from the rest of the CGFX file. The second DICT in the CMDL section contains offsets to MTOB objects.

SOBJ #

SOBJ structures can be used to describe 3D objects that are part of the model. If such is the case then they will follow this structure :

OffsetLengthDescription
0x00x4Flags (bit 4: model; bit 1: skeleton)
0x40x4Magic “SOBJ”
0x80x4?
0xC0x4Unknown symbol offset (self-relative)
0x100xC?
0x1C0x4Offset (self-relative) to Unknown1 (appears to hold array of floats) ?
0x200xCMesh position offset (X/Y/Z floats)
0x2C0x4Face groups count
0x300x4Offset (self-relative) to face groups offset array
0x340x4?
0x380x4Vertex groups count
0x3C0x4Offset (self-relative) to vertex groups offset array
0x400x4Unknown offset (self-relative) ?

Face groups:

OffsetLengthDescription
0x00x4Bone groups count
0x40x4Offset (self-relative) to UInt32 bone group IDs array
0x80x4?
0xC0x4Unknown2 count
0x100x4Offset (self-relative) to Unknown2 offset array

Unknown2:

OffsetLengthDescription
0x00x4Face group descriptor count
0x40x4Offset (self-relative) to face array descriptors offset array
0x80x4Unknown3 count
0xC0x4Offset (self-relative) to UInt32 Unknown3 array
0x100x8?

Face array descriptor:

OffsetLengthDescription
0x00x4Flags (bit 1: vertex index format: 0=byte, 1=short)
0x40x4?
0x80x4Vertex index array size (in bytes)
0xC0x4Offset (self-relative) to vertex index array

Vertex groups come in a number of different formats. Typically the first vertex group entry is of format 0x40000002 and contains the actual vertex array.

Vertex group format 0x40000002:

OffsetLengthDescription
0x00x4Flags (0x40000002)
0x40x4?
0x80x4?
0xC0x4?
0x100x4?
0x140x4Vertex array size (in bytes)
0x180x4Offset (self-relative) to vertex array
0x1C0x4?
0x200x4?
0x240x4Vertex stride/size in bytes (see below)
0x280x4Unknown3 count
0x2C0x4Offset (self-relative) to component declaration offset array

Each mesh’s primary vertex group contains an array of vertex component declaration objects, defining the order and parameters for each of a vertex’s components.

Vertex component declaration:

OffsetLengthDescription
0x00x4Flags (0x40000001)
0x40x4Vertex component type (see below)
0x80x4?
0xC0x4?
0x100x4?
0x140x4?
0x180x4?
0x1C0x4?
0x200x4?
0x240x1Component data type (see below)
0x250x1?
0x260x1?
0x270x1?
0x280x4Number of values in this component (e.g. XYZ->3, UV->2)
0x2C0x4Multiplier for this component’s values (float)
0x300x4Position of this component within vertex stride

Vertex formats with bone data support multiple bone assignment. In this case, the sum of all bone weights is 0x64.

Vertex component types:

ValueType
0x00Position
0x01Normal
0x02? (unobserved)
0x03Color
0x04UV0
0x05UV1
0x06? (unobserved, possibly UV2)
0x07Weight
0x08Index

Vertex component data types:

ValueType
0x00sbyte
0x01byte
0x02short
0x03? (unobserved, possibly ushort)
0x04? (unobserved, possibly int)
0x05? (unobserved, possibly uint)
0x06float

Vertex components are stored as one of the above data types, and the vertex component declaration contains a multiplier that adapts the values to the float version which the game will use. For example, color RGBA values are stored as bytes, and the multiplier converts them from 0-255 to 0-1.0, and position components using short values are normalized via the multiplier to take advantage of the entire short value range.

TXOB #

TXOBs are contained within MTOBs. They can describe textures; if such is the case, then their structure is as follows :

OffsetLengthDescription
0x00x4Flags
0x40x4Magic “TXOB”
0x80x8?
0xC0x4Offset (self-relative) to symbol
0x180x4Texture height
0x1C0x4Texture width
0x280x4Mipmap levels
0x340x4Texture format ID (see table below)
0x3C0x4Texture height (?)
0x400x4Texture width (?)
0x440x4Texture data size
0x480x4Texture data offset (self-relative)
Texture format IDDescription
0x0RGBA8
0x1RGB8
0x2RGBA5551
0x3RGB565
0x4RGBA4
0x5LA8
0x6HILO8
0x7L8
0x8A8
0x9LA4
0xAL4
0xBA4 ?
0xCETC1 (see notes below)
0xDETC1A4 ?

Every texture format has its texture data divided into 8x8 tiles. See SMDH for more information. ETC1 is a compressed texture format which compresses blocks of 4x4 pixels into u64s. These u64 are traditionally stored in big endian; however, nintendo’s implementation stores them in little endian. ETC1 textures are stored in 8x8 tiles; decompressed 4x4 therefore have to be organized accordingly. See 🔗 1 for implementation example.

LUTS #

Appears to contain color lookup tables possibly for use with shaders.

LUTS Header:

OffsetLengthDescription
0x00x4Magic “LUTS”
0x40x2Seems to adhere to powers of 2 (width/height/flags?)
0x60x2Seems to adhere to powers of 2 (width/height/flags?)
0x80x4?
0xC0x8all zeroes ?
0x140x4?
0x180x4Offset to DICT (self-relative) ?

All observed instances have an otherwise unreferenced DICT section immediately afterward (the last LUTS value being a 0x4, which may describe the relative position of that DICT), which appears to describe material specularity.

Skeleton data #

Skeleton data is stored in an array. Each entry is 0xE0 bytes in length and organized this way :

OffsetLengthDescription
0x00x4Offset (self relative) to name symbol
0x40x4?
0x80x4Joint ID
0xC0x4Parent joint ID
0x100x4Signed offset (self-relative) to parent joint
0x2C0xCAngle vector (floats, x, y, z)
0x380xCPosition vector (floats, x, y, z)
0x440x30Transformation matrix (4x3)
0x740x30Identity matrix ? (4x3)

Each entry stores the joint transformation data twice; once as angle/position vectors and once as a transformation matrix. Each entry also stores a second matrix which appears to always be identity. (?)

CANM #

CANMs are used to store skeletal animation data.

Tools #

  • Every File Explorer
  • Ohana3DS and its forks
  • SPICA

Category:File formats