FF7/Battle model format (PSX)
Contents
Playstation battle model format
The entire file is compressed using LZS format and is decompressed into the playstation user memory for a battle. The file consists of several section blocks, a header, compiled HRC and model information, battle animations, a texture image in TIM format, and optional weapon models. All integers short or long are little endian based. This includes some of the animation data as well.
Battle model header
The header section is a sequence of little endian 32 bit unsigned integers. The first integer (entitled SectionCount) contains the number of pointers offset from the begining of the file. The remaining integers are SectionCount number of pointers.
Offset |
Size |
Description |
000000 |
4 bytes long |
Number of Sections |
N*4 |
4 bytes long |
Pointer to each section of data. |
(N+1)*4 |
Varies |
First section of data, this is
the actual 3d data for the model. |
(N+2)*4 |
Varies |
First animation for the model. |
unknown |
Varies |
Tim image information often 4bpp
sometimes 8bpp # of cluts varies |
unknown |
Varies |
Battle weapon models for
characters go here they have the indentical format as the first
section, save they do not have textured polygons |
Battle model HRC/model information
This is the first section and consists of real model data and bone structure. Without the animation information the model CANNOT be displayed properly.
HRC data
This data resembles Hierarchy files (.HRC), from the PsyQ library. To be correct the HRC files were used to generate this information hence it's called HRC data. The HRC data begins with an unsigned 32 bit integer (BoneCount) indicating the number of bones. Following this is the root bone, which is allays zero'd. After the root bone is BoneCount number of bones. The bone information is stored in a structure like the thus (using C conventions):
typedef struct { uint16 Parent; int16 Length; uint32 Offset; } FF7_bone;
Where offset is relative to the begining of the section. If Offset is 0 then the object is a Joint otherwise it's a bone. All FF7 bone lengths are negative.
HRC Table structure
Offset |
Size |
Description |
000000 |
4 bytes long |
Number of Bones |
000004 |
8 bytes |
root bone (always 0 values) |
000008 |
8*N bytes |
Bones and joints of model |
Bone Structure
Offset |
Size |
Description |
000000 |
2 bytes (word) |
Parent Bone |
000002 |
2 bytes (signed) |
Bone Length |
000004 |
4 bytes |
Offset to bone data object is a joint if 0 |
Model information
Following the HRC Data is the model information, these are referenced by offsets in the Bone structure. Each bone has it's own model section specific too it. Each bone section has the following information uint32 VertexCount (int bytes), Vertices, Textured Triangle Count (Poly Count Structure), Textured Triangles, Textured Quadric Count (PCS), Textured Quadrics, Triangle Count (PCS), Triangles, Quadric Count (PCS), Quadrics. If the count of any of these is zero then the follow data is a Poly Count Structure.
All structure information is 32 bit aligned for the PSX GPU.
typedef struct { uint16 Count; uint16 TexPage; } PolyCount;
typedef struct { int16 X; int16 Y; int16 Z; int16 Unused; } Vertex;
typedef struct { uint8 Red; uint8 Green; uint8 Blue; uint8 Unused; } Color;
typedef struct { uint16 A; uint16 B; uint16 C; uint16 D; } PolyIndices;
typedef struct { PolyIndices Vertexs; Color Colors[3]; } ColorTriangle;
typedef struct { PolyIndices Vertexs; Color Colors[4]; } ColorQuadric;
typedef struct { PolyIndices Vertex; uint8 U0, V0; unint16 Flags; uint8 U1, V1; uint8 U2, V2; } TexTriangle;
typedef struct { PolyIndices Vertex; uint8 U0, V0; unint16 Flags; uint8 U1, V1; uint8 U2, V2; uint8 U3, V3; uint16 Unused; } TexQuadric;
The Flags field on the Textured polygons contains the texture palette offset for the TIM texture file associated with the model. The TexPage is not used in any of the battle models however battle scenes do use this to refer another page of texture data (for 8bpp TIM's used in them).
Bone structure data
Offset |
Size |
Description |
000000 |
4 bytes (long) |
Vertex pool size (in bytes) |
000004 |
Vertex Pool Size bytes |
Vertex pool for bone structure |
... |
2 bytes (word) |
Number of polygons
<textured triangles> |
... |
2 bytes (word) |
Polygon flags (Palette) |
... |
N * 16 bytes |
Textured Triangles if N polygons
= 0 these ocupy no space |
... |
2 bytes (word) |
Number of polygons <textured
quadrics> |
... |
2 bytes (word) |
Polygon flags (Palette) |
... |
N * 20 bytes |
Textured Quadrics if N polygons
= 0 these ocupy no space |
... |
2 bytes (word) |
Number of polygons
<triangles> |
... |
2 bytes (word) |
<always zero> |
... |
N * 20 bytes |
Colored vertex triangles if N
polygons = 0 these ocupy no space |
... |
2 bytes (word) |
Number of polygons
<quadrics> |
... |
2 bytes (word) |
<always zero> |
... |
N * 24 bytes |
Colored vertex quadrics if N polygons = 0 these ocupy no space |
Battle animations
This is identical to the PC version of FF7.
Texture information
see TIM format
Weapon models
These are identical to the bone model structures, as the weapon models are treated as bones in character animation. They have NO texture data period.