Anonymous

Changes

From Final Fantasy Inside

FF7/P

10,903 bytes added, 02:56, 24 March 2018
Created page with "This page describes format of P files. 'P file' is a binary file containing data which form 3D model. File specifies model's vertices, polygons, colors, texture coordinates a..."
This page describes format of P files.
'P file' is a binary file containing data which form 3D model. File specifies model's vertices, polygons, colors, texture coordinates and model sub-groups. File does not specify references to the texture files, animations, model skeleton or anything else.
 
P-files are used as parts of field models, battle models, battle locations on PC version of FF7.
 
''Feel free to add more information.''
 
[[File:Ff7field3dfiles.png|[[Image:Ff7field3dfiles.png|Ff7field3dfiles.png]]]]
 
----
 
== "P" Polygon File Format ==
 
This is a short diagram of the file structure
 
.p-File
|
+- Header
|
+- Vertices[]
|
+- Normals[]
|
+- Unknown1[]
|
+- Texture Coords[]
|
+- Vertice Colors[]
|
+- Polygon Colors[]
|
+- Edges[]
|
+- Polygons[]
|
+- Unknown2[]
|
+- Unknown3[]
|
+- Hundreds[]
|
+- Groups[]
|
+- BoundingBoxes[]
|
+- Normal Index Table[]
[] = a variable-sized array
 
<br />
 
----
 
=== .P File Header ===
 
The .p files have a 128-Byte-long Header. The following is the known structure of the header.
 
{| style="border: 2px solid black; border-collapse: collapse" border="2" cellspacing="1" cellpadding="3" align="center"
|+ '''Table 1: P File header'''
! Off
! 00
! 01
! 02
! 03
! 04
! 05
! 06
! 07
! 08
! 09
! 0A
! 0B
! 0C
! 0D
! 0E
! 0F
|-
! 00
| colspan="4" align="center" | Version
| 01
| 00
| 00
| 00
| colspan="4" align="center" | VertexType
| colspan="4" align="center" | NumVertices
|-
! 10
| colspan="4" align="center" | NumNormals
| colspan="4" align="center" | NumUnknown1
| colspan="4" align="center" | NumTexCoords
| colspan="4" align="center" | NumVertexColors
|-
! 20
| colspan="4" align="center" | NumEdges
| colspan="4" align="center" | NumUnknown2
| colspan="4" align="center" | NumUnknown3
| colspan="4" align="center" | NumPolygons
|-
! 30
| colspan="4" align="center" | NumHundreds
| colspan="4" align="center" | NumGroups
| colspan="4" align="center" | NumBoundingBoxes
| colspan="4" align="center" | NormIndexTableFlag
|}
 
All Values, that can be read out in this part of the header are 4-Byte-Integers
 
This 64 bytes long header is followed by 64 bytes of runtime data which are to be skipped.
 
typedef struct
{
long Version;
long off04;
long VertexType;
long NumVertices;
long NumNormals;
long NumUnknown1;
long NumTexCs;
long NumVertexColors;
long NumEdges;
long NumPolys;
long NumUnknown2;
long NumUnknown3;
long NumHundreds;
long NumGroups;
long NumBoundingBoxes;
long NormIndexTableFlag;
long runtime_data[16];
}
t_p_header;
 
Here are the meanings of values from header:
 
{| style="margin-bottom: 0px"
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 26px" | VertexType
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 26px" |
Specifies the type of vertices this file contains, should always be 1 (which translates into LVERTEX in the D3D driver) 0 translates into VERTEX, which looks the same as LVERTEX but is never used in the original FF7 data. 2 translates into TLVERTEX, you don't want this unless you know exactly what it does.
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumVerts
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Vertices
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumNormals
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Normals (always 0 in Battle files)
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumTexCs
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Texture Coords
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumVertexColors
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Vertex Colors
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumEdges
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Edges
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumPolys
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Polygons
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumHundreds
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Hundreds (Someone should really come up with a better name for this)
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumGroups
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Groups
|-
| style="border: 1px solid rgb(0, 0, 0); width: 106px; height: 25px" | NumBoundingBoxes
| style="border: 1px solid rgb(0, 0, 0); width: 394px; height: 25px" | Number of Bounding Boxes
|}
 
<br />
 
=== Vertices ===
 
Vertices are stored as array of structure ‘vertex’ below, which is triplet of float numbers. Numbers specify point in 3D space. Size of this array is specified in header. Size of vertex section is ( 12 * NumVertices ). Section is allways present in the file.
 
struct s_vertex {
float x, y, z;
} vertex;
 
// structure size = 12 bytes
 
<br />
 
=== Vertex normals ===
 
Same format as vertices. Though, each of coordinate means vertex normal orientation instead of position. Size of this section is ( 12 * NumNormals ).
 
<br />
 
=== Unknown1 ===
 
Same format as vertices. No idea what this is used for. Size of this section is ( 12 * NumUnknown1 ).
 
<br />
 
=== Texture coordinates ===
 
Array of vertex texture coordinates. Size of this section is ( 8 * NumTexCoords ). Texture coord references are to be read through group information.
 
<br />
 
=== Vertex colors ===
 
Vertex colors are stored as array of colors, each color is specified by four bytes. Color is in B8G8R8A8 format, that means that first byte specifies Blue, second specifies Green, third specifies Red and fourth specifies Alpha. Alpha byte has usually value ‘255’, so its at full opacity. Size of this section is ( 4 * NumVertexColors ).
 
<br />
 
=== Polygon colors ===
 
Polygon colors are stored in the same manner as vertex colors. Size of this section is ( 4 * NumPolygons ).
 
<br />
 
=== Edges ===
 
Specifies edges, not really useful. Each index has value in range 0 .. NumVertices. Size of this section is ( 4 * NumEdges ).
 
<br />
 
=== Polygons ===
 
Array of polygon definitions. I know only meaning of values which specify vertex indexes. Vertex indexes can’t be used directly to select vertices, you have first to read group information, there you will find information on which polygons and vertices you should be used to form a model part. Polygons have group-relative indexes to vertices (that means that in each group these indexes start from 0 ). Size of this section is ( 24 * NumPolygons ).
 
struct {
unsigned short zero, VertexIndex[3], NormalIndex[3], EdgeIndex[3], u[2];
} Ppolygon;
 
{| class="wikitable"
|+ '''Table 1: Structure of single polygon data'''
! Off
! 00
! 01
! 02
! 03
! 04
! 05
! 06
! 07
! 08
! 09
! 0A
! 0B
! 0C
! 0D
! 0E
! 0F
|-
! 00
| colspan="2" align="center" | 00 00
| colspan="2" align="center" | VertexIndex1
| colspan="2" align="center" | VertexIndex2
| colspan="2" align="center" | VertexIndex3
| colspan="2" align="center" | NormalIndex1
| colspan="2" align="center" | NormalIndex2
| colspan="2" align="center" | NormalIndex3
| colspan="2" align="center" | EdgeIndex1
|-
! 10
| colspan="2" align="center" | EdgeIndex2
| colspan="2" align="center" | EdgeIndex3
| colspan="2" align="center" | u1
| colspan="2" align="center" | u2
| colspan="8" align="center" |
|}
 
<br />
 
=== Unknown2 ===
 
(Probably)Same format as polygons. No idea what this is used for. Size of this section is ( 24 * NumUnknown2 ).
 
<br />
 
=== Unknown3 ===
 
No idea what this is used for. Size of this section is ( 3 * NumUnknown3 ).
 
<br />
 
=== Hundreds ===
 
Complex structure that specifies render state (texturing, blend modes, culling, filtering, depth testing, depth masking, shademode etc) Contact me (Aali) for more information.
 
<br />
 
=== Groups ===
 
{| class="wikitable"
|+ '''Table 1: Structure of single 'groups' record'''
! Off
! 00
! 01
! 02
! 03
! 04
! 05
! 06
! 07
! 08
! 09
! 0A
! 0B
! 0C
! 0D
! 0E
! 0F
|-
! 00
| colspan="4" align="center" | PrimitiveType
| colspan="4" align="center" | PolygonStartIndex
| colspan="4" align="center" | NumPolygons
| colspan="4" align="center" | VerticesStartIndex
|-
! 10
| colspan="4" align="center" | NumVertices
| colspan="4" align="center" | EdgeStartIndex
| colspan="4" align="center" | NumEdges
| colspan="4" align="center" | ?
|-
! 20
| colspan="4" align="center" | ?
| colspan="4" align="center" | ?
| colspan="4" align="center" | ?
| colspan="4" align="center" | TexCoordStartIndex
|-
! 30
| colspan="4" align="center" | AreTexturesUsed
| colspan="4" align="center" | TextureNumber
| colspan="8" align="center" |
|}
 
<br />
 
struct {
unsigned long PrimitiveType;
unsigned long PolygonStartIndex;
unsigned long NumPolygons;
unsigned long VerticesStartIndex;
unsigned long NumVertices;
unsigned long EdgeStartIndex;
unsigned long NumEdges;
unsigned long u1;
unsigned long u2;
unsigned long u3;
unsigned long u4;
unsigned long TexCoordStartIndex;
unsigned long AreTexturesUsed;
unsigned long TextureNumber;
} group;
// also called pool56, size is 56 bytes
 
Section contains array of group information. Each group specifies group of polygons. To read this group’s geometry you have to read polygons from polygon segment. First polygon is one with index ''group.PolygonStartIndex'', number of polygons is defined by ''group.NumPolygons''. Polygon has indexes of vertices. These indexes are group-relative and that means that you have to add ''group.VerticesStartIndex'' to each vertex index. It’s the same with vertex texture coords. Their indexes are group-relative too, to each index you have to add ''group.TexCoordStartIndex''.
 
If ''group.textures_used'' is equal 1 then texture is applied on all polygons of current group. If its 0 there is no texture. If its 1 then ''group.TextureNumber'' defines which texture to use on polygons. Though, texture name is not specified inside the P-file, it is specified in HRC or DA file, which loads model as a whole ( it points to texture files, P-files, animation files etc.) Size of this section is ( 56 * NumGroups ).
 
=== Bounding box ===
 
Six 4-byte floats in order max( x, y, z ), min( x, y, z ). Sometimes just zeroes. Size of this section is 24 bytes * NumBoundingBoxes.
 
<br />
 
=== Normal index table ===
 
Not used anywhere. Size of this section is ( 4 * NumVertices ).
Anonymous user