.P FILE FORMAT ============== OK, this is a brief file format description for the .P files Final Fantasy VII PC uses. It's based mainly on Qhimm's rather useful 3DS plugin, so kudos to him, but if you have questions post 'em on Qhimm's message board where a lot of us FF7 hackers visit. I'm stating all the offsets in hex, it's pretty standard. So when I say: offset $C3 I mean, skip C3 hex (=195 decimal) bytes from the start of the file. Lengths I'll probably state in decimal. Anyway, a $ sign means I'm using hex. Also, you'll need to understand the following basic concepts: 3d models are made up of polygons, usually triangles. A polygon is made up of a number of points, usually called vertices (or verts for short). Each vert has the following 'properties' (usually, anyway): -X,Y and Z co-ordinates; it's position in 3d space. -R,G and B values: Red/Green/Blue colours. When in nontextured, that's the colour at that point. In textured mode, you could use this to 'light up' the texture with a red light, or whatever. I don't think FF7 does this though. To simplify things, most 3d files use vertex 'pools'. In other words, they have a list of vertices; than to specify a polygon (say a triangle) they just say "connect vertices 1, 3 and 6." You go off and look up those vertices, then you've got your triangle. The advantage of this is, lots of triangles 'share' vertices. You want one triangle to press right up against the one next to it so there aren't any gaps in your 3d model. To do that, you want some of their vertices to have the same coordinates. By having a 'pool', you guarantee they'll use the same point. A--------C--------D \ | / \ | / \ | / \ | / \ | / \ | / \ | / \|/ B (That probably looks *really* crap unless you're using a fixed-size font, like in Notepad). You have 2 triangles, and four points (vertices). Say you decide to move point C in your model to change how the model looks. If each triangle had its own separate coordinates, there'd be a gap between the triangles. If you have a pool, though, you just change the coords of that vertex in the central pool (list), and both triangles move to show that - and they still fit up against each other! One other point is that, often, the colour of a vertex isn't necessarily fixed. For example, in the triangles above, vertex C could have a red colour for the first triangle, and a blue colour for the second. That isn't used too often - because it gives a very sharp change between colours, which can look strange - but sometimes it's exactly what you want. Usually, when the three vertices have different colours, the triangle is 'blended' to give a smooth colour shift over the surface. That's what FF7 does. Right: onto the file format. FILE HEADER ----------- Offset Size Type Name $0C 4 integer additional $10 4 integer numverts $18 4 integer value3 $20 4 integer numlines $24 4 integer numpolys (A nearly exact translation from Qhimm's source). There are three sections in the .P file we know how to decode at the moment: Vertex pool Colour pool Polygon list The number of vertices in the vertex pool is equal to numverts+additional. The number of colour entries in the colour pool is equal to numpolys+additional. The number of polygons in the polygon list is equal to numpolys. 1: VERTEX POOL -------------- This section starts at offset $80. It contains 1 entry for each vertex (see above for number of vertices). Each vertex consists of 12 bytes: 4 each for the X,Y and Z co-ordinates. They are stored as single-precision floating point numbers (usually called Single's or Float's). So, the offset for the N'th vertex is $80 + N*12 (assuming N starts at 0). 2: COLOUR POOL -------------- This section starts at offset $80 + (Number of vertices * 12) + (Value3 * 8) In other words, once you've finished reading the vertex pool, skip (Value3 * 8) bytes and you reach the colour pool. (Incidentally, if you're wondering what's in the bytes skipped over, I'm not sure. Actually, value3 was 0 in the few files I checked, so you didn't skip any bytes.) Each colour entry consists of 4 bytes; a standard RGB quad. The order is: Blue byte Green byte Red byte Reserved byte The reserved byte seems to be $FF (maximum value, 255) every time. Possibly it indicates transparency/brightness, but it's probably just ignored. 3: POLYGON POOL --------------- This section starts at offset $80 + (Number of vertices * 12) + (Value3 * 8) + (Number of colours * 4) + (Numlines * 4) So, once you've finished with the colours, skip (Numlines*4) bytes and you get to polygons. (The bytes skipped over here are probably something to do with drawing lines, rather than polygons ... as you might guess from the name Numlines) Each polygon consists of 24 bytes, in the following format: Type Size Name Word 2 Tag array[3] of Word 6 Verts array[3] of Word 6 CVerts array[3] of Word 6 Lines Integer 4 Unknown (Word = 16 bit unsigned integer; Integer = 32 bit integer). Tag, I don't know the meaning. Seems to be the same for every polygon in the file. Verts are the important part of the polygon. It's the index into the vertex pool for the 3 vertices that make up this polygon (so yes, you only get triangles). Also, they're the index into the colour pool for the colour of that vertex (so yes, each vertex has a fixed colour; vertex 3 always uses colour 3). CVerts: Not sure. First of all, I thought it was the index of the 3 colours to use at each point ... but it isn't. Lines: Not sure. Unknown: Well, it's unknown :-p OK! That's all you need to know to read in and display a .P file. Incidentally, I've already got Delphi code to do just that anybody's welcome to see. (Since it's just based off Qhimm's anyway). Texture information is stored in the RSD file which points to a .P file. HRC files list a 'skeleton' of different .P parts and how they link together. Not fully understood by me yet (OK: I understand everything but how to get the different parts in the right position.) Oh, I think it's obvious, but when I'm talking about 'size' above, it's in bytes. A word is 2 bytes, an Integer 4 bytes, etc. Written rather quickly by Ficedula ficedula@lycos.co.uk http://ficedula.cjb.net/ Qhimm's site at www.qhimm.com