PTCL
PTCL
(a.k.a EFTB
/VFXB
) files define certain graphical effects of objects such as emissions, particles, and shaders. They use the .esetlist
extension, but differ between platforms in what structures it uses for different types of data, aside for ESTA
and PRMA
, which are the same[check] on both.
PTCL File Layout
PTCL files are made up of a header and four structures that are aligned to 16 bytes.
- Emitter Set Array
- Texture Array / Cafe Resource
- PRM[check] Array
- Shader Array / Binary Shader[check]
Each array serves as a root node in a tree structure.
PTCL Header
The EFTB
and VFXB
headers both contain different data, and as such have different size (0x30 and 0x40 respectively).
EFTB Header Structure
Offset (h) | Size | Data Type | Description |
---|---|---|---|
0x00 | 4 | String | file signature (magic) (45 46 54 42 or "EFTB" in ASCII)
|
0x04 | 4 | Unsigned Int | VFX API Version |
0x08 | 4 | String | Unknown (47 61 6d 65 or "Game")
|
... |
VFXB Header Structure
Offset (h) | Size | Data Type | Description |
---|---|---|---|
0x00 | 4 | String | File signature (magic) (56 46 58 42 or "VFXB" in ASCII)
|
0x04 | 4 | Unsigned Int | Unknown (20 20 20 20 )
|
0x08 | 2 | Unsigned Short | Graphics API version |
0x0A | 2 | Unsigned Short | VFX API version |
0x0C | 2 | Unsigned Short | Byte-Order Mark |
0x0E | 1 | Byte | Alignment |
0x0F | 1 | Byte | Target offset |
0x10 | 4 | Unsigned Int | Header size |
0x14 | 2 | Unsigned Short | Flag |
0x16 | 2 | Unsigned Short | First node offset |
0x18 | 4 | Padding | |
0x1C | 4 | Unsigned Int | File size |
0x20 | 4 | String | Game |
0x24 | 28 | Byte[28] | Unknown |
... |
Nodes
Each node in an array's tree structure is made up of a header and three optional sections.
- Binary data
- Attribute nodes[check]
- Child nodes
Node Header Structure
Node headers typically have the same 32-byte structure, though some are longer and some calculate certain values differently.
Offset (h) | Size | Data Type | Description |
---|---|---|---|
0x00 | 4 | Unsigned Int | Signature (magic) |
0x04 | 4 | Unsigned Int | Node size. Different node types calculate this differently. |
0x08 | 4 | Unsigned Int | Offset to the first child node, or FF FF FF FF if there are no children
|
0x0c | 4 | Unsigned Int | Offset to the next sibling node, or FF FF FF FF if there are no more siblings
|
0x10 | 4 | Unsigned Int | Offset to the first attribute[check], or FF FF FF FF if there are no attributes
|
0x14 | 4 | Unsigned Int | Offset to the binary data, or the size of the header |
0x18 | 4 | Padding | |
0x1c | 2 | Unsigned Short | Number of child nodes. Shaders' use of this value is unknown. |
0x1e | 2 | Unsigned Short | Unknown (00 01 )
|
Emitter Sets (ESTA)
The Emitter Set Array (ESTA) contains any number of Emitter Sets (ESET) as child nodes.
Emitter Set (ESET)
Emitter sets (ESET) contain 0x60 bytes of data after the header:
Offset (h) | Size (h) | Data Type | Description |
---|---|---|---|
0x10 | 0x40 | String | 0-terminated string representing the name of the emitter set |
0x50 | 0x04 | Unsigned Int | Total number of emitters in the set, including all descendant nodes |
0x5a | 0x02 | Unsigned Short | Unknown |
0x5f | 0x01 | Byte | Unknown. Can be 0x00 or 0xff
|
The rest of the data block is padding.
Emitter sets also contain any number of Emitters (EMTR) as child nodes.
Emitter (EMTR)
An Emitter's (EMTR) data section is aligned to 0x20 bytes and contains the following data after the header:
Offset (h) | Size (h) | Data Type | Description |
---|---|---|---|
0x00 | 0x60 | String | Name block, like in ESET |
0x60 | 0x18 | Six Unsigned Ints specifying the sizes of the color arrays
| |
0x38 | Byte[56] | Padding | |
0xB0 | 0x30 | UInt32[check] * 12 | Unknown |
0xE0 | 0x4 | Float | Blink Intensity 1 |
0xE4 | 0x4 | Float | Blink Intensity 2 |
0xE8 | 0x4 | Float | Blink Duration 1 |
0xEC | 0x4 | Float | Blink Duration 2 |
0xF0 | 0x2C0 | UInt32[check] * 176 | Unknown |
0x3B0 | 0x4 | Float | Radius |
0x3B4 | 0x4 | Float | Unknown |
0x3B8 | 0x8 | Byte[8] | Padding |
0x3C0 | 0x80 | Float[4] * 8 | Color 0 array (eight sets of four 32-bit floats describing Red, Green, Blue, and Time) |
0x440 | 0x80 | Float[4] * 8 | Alpha 0 array (eight sets of four 32-bit floats describing Red, Green, Blue, and Time) |
0x4C0 | 0x80 | Float[4] * 8 | Color 1 array (eight sets of four 32-bit floats describing Red, Green, Blue, and Time) |
0x540 | 0x80 | Float[4] * 8 | Alpha 1 array (eight sets of four 32-bit floats describing Red, Green, Blue, and Time) |
0x5C0 | 0x40 | UInt32[check] * 16 | Unknown array |
0x600 | 0x80 | Float[4] * 8 | Scale[check] array (eight sets of four 32-bit floats) |
0x680 | 0xD0 | UInt32[check] * 52 | Unknown |
0x750 | 0x10 | Byte[16] | Unknown |
0x760 | 0x90 | UInt32[check] * 36 | Unknown |
0x7F0 | 0x8 | Byte[8] | Unknown |
0x7F8 | 0x40 | UInt32[check] * 16 | Unknown |
0x838 | 0x8 | Byte[8] | Unknown |
0x840 | 0x58 | UInt32[check] * 22 | Unknown |
0x898 | 0x8 | Byte[8] | Unknown |
0x8A0 | 0x8 | Float[check] * 2 | Unknown |
0x8A8 | 0x10 | Byte[16] | Unknown |
0x8B8 | 0x18 | UInt32[check] * 6 | Unknown |
0x8D0 | 0x10 | Byte[16] | Unknown |
0x8E0 | 0x18 | UInt32[check] * 6 | Unknown |
0x8F8 | 0x18 | Byte[24] | Unknown |
0x910 | 0x8 | UInt32[check] * 2 | Unknown |
0x918 | 0x4 | Byte[4] | Padding? Sometimes FF FF FF FF
|
0x91C | 0x8 | UInt64 | Unknown. Sometimes FF FF FF FF FF FF FF FF
|
0x924 | 0x4 | Byte[4] | Padding? Sometimes FF FF FF FF
|
0x928 | 0x8 | UInt32[check] * 2 | Unknown |
0x930 | 0x8 | UInt64 | Unknown |
0x938 | 0x10 | UInt32[check] * 4 | Unknown |
0x948 | 0xA | String | Usually is ATEST_ONLY when used. Can be null.
|
0x952 | 0x2 | Byte[2] | Padding |
0x954 | 0x48 | UInt32[check] * 48 | Unknown |
0x99C | 0xC | Byte[12] | Unknown |
0x9A8 | 0x10 | Float[4] | Constant Color 0 if Color 0 array is empty |
0x9B8 | 0x10 | Float[4] | Constant Color 1 if Color 1 array is empty |
0x9C8 | 0x30 | UInt32[check] * 12 | Unknown |
0x9F8 | 0x60 | Three Sample Info blocks, consisting of the following structure:
| |
0xA58 | 0x30 | Byte[48] | Unknown |
Emitters can also have any number of attribute nodes (e.g. CADP, CSDP, FCSF), the purpose of which is currently unknown, as well as child emitter nodes.
Attributes
CADP causes an emitter to cast light on surrounding surfaces. It contains the following data:
Offset (h) | Size | Data Type | Description |
---|---|---|---|
0x00 | 0x04 | Bitmask | Flag determining the light's shape |
0x04 | (variable) | Float | A variable number of floats whose purpose is unknown |
Shape flag:
Flag | Description |
---|---|
0x00 | Sphere |
0x01 | Rod (e.g. swords) |
0x02 | Changes the orientation of Rod |
0x04 | Adds a dead zone to the center of Rod |
0x08 | Wide cone |
0x10 | Square |
0x20 | Point |
0x40 | Widens the Point |
Textures (TEXA)
The Texture Array (TEXA) contains any number of Textures (TEXR), with each texture containing a single GX2 Texture Block (GX2B). The TEXA tree is flattened such that all TEXR nodes appear first, followed by all of their child GX2B nodes.
(PRMA)
The PRMA[check] contains any number of PRIM[check] nodes.
Shaders (SHDA)
The Shader Array (SHDA) contains a single[check] GX2 Shader Block (SHDB).