Paper Mario 2 Character and Object Model File Format Specification Generated by Retriever II Updated: May 30, 2005 If you can contribute to this documentation, please tell me what you find. You can shoot me an email at jaquadro@penguinia.net. I'll keep this document updated and credit all contributors. While I've made every effort to keep this document accurate, there may be errors, which I correct as I find them or as they are reported. The file format is broken down into 26 distinct data structures, or blocks. A 27th block is identified as an extention to block 26, and contains a set of 9 distinct sub-blocks, making it a format within a format. In this document, the global structure of the file format is outlined, then each block is examined in detail. --------------------------------------------------------------------------------- BLOCK INDEX HIERARCHY Based on references to indeces of other blocks. Currently blocks 19 and 26 don't fit into the model. This model is also only a best guess, but for what I've been able to test, it works. BLOCK 25 BLOCK 26 | +----------+----------+ | | | BLOCK 2 BLOCK 23 BLOCK 24 | +----------+----------+ | | | BLOCK 4 BLOCK 18 BLOCK 22 | +----------+----------+----------+-----------+----------+ | | | | | | BLOCK 3 BLOCK 5 BLOCK 9 BLOCK 7 BLOCK 20 BLOCK 10 | | | | | | | | | BLOCK 8 BLOCK 6 BLOCK 21 --------------------------------------------------------------------------------- Global Structure Arrangement Block Name SIZE Description Block 1 432 File Header Block 2 168 Planes Block 3 8 Polygons Block 4 12 Verteces Block 5 4 Polygon Point/Vertex Order Block 6 12 Normals Block 7 4 Normal Order Block 8 4 Colors [RGBA8] Block 9 4 Color Order Block 10 4 Texture Point/Vertex Order .. (Blocks 11-17 never observed) Block 18 8 Texture Vertex Block 19 24 Unknown Block 20 8 Texture Map Block 21 64 Texture Path Block (what purpose does this serve?) Block 22 108 Polygon / Texture Map Block 23 1 Plane Display Block 24 4 Transformation Block 25 88 Scene Graph Block 26 64 Animation Sequence Identifer Block 27 VAR Animation Sequence - data extention of block 26 --------------------------------------------------------------------------------- Block 1 (Header) (432 bytes) Mainly serves to list address offsets for block sets 2-27, and the number of blocks contained within each set. Still, contains some values whose purpose I don't yet know. Rel Addr SIZE Description 0x0000 4 Data offset Block 27, size of Blocks 1 - 26 0x0004 64 Filename 0x0044 64 Texture Filename (Minus dash) 0x0084 64 Date String 0x00C4 4 Unknown 0x00C8 4 Unknown 0x00CC 4 Unknown 0x00D0 4f Point1-x 'Main Plane'? 0x00D4 4f Point1-y 'Main Plane'? 0x00D8 4f Point1-z 'Main Plane'? 0x00DC 4f Point4-x 'Main Plane'? 0x00E0 4f Point4-y 'Main Plane'? 0x00E4 4f Point4-z 'Main Plane'? 0x00E8 4 Number blocks in Block 2 0x00EC 4 Number blocks in Block 3 0x00F0 4 Number blocks in Block 4 0x00F4 4 Number blocks in Block 5 0x00F8 4 Number blocks in Block 6 0x00FC 4 Number blocks in Block 7 0x0100 4 Number blocks in Block 8 0x0104 4 Number blocks in Block 9 0x0108 4 Number blocks in Block 10 0x010C 4 Number blocks in Block 11 (*) 0x0110 4 Number blocks in Block 12 (*) 0x0114 4 Number blocks in Block 13 (*) 0x0118 4 Number blocks in Block 14 (*) 0x011C 4 Number blocks in Block 15 (*) 0x0120 4 Number blocks in Block 16 (*) 0x0124 4 Number blocks in Block 17 (*) 0x0128 4 Number blocks in Block 18 0x012C 4 Number blocks in Block 19 0x0130 4 Number blocks in Block 20 0x0134 4 Number blocks in Block 21 0x0138 4 Number blocks in Block 22 0x013C 4 Number blocks in Block 23 0x0140 4 Number blocks in Block 24 0x0144 4 Number blocks in Block 25 0x0148 4 Number blocks in Block 26 0x014C 4 Data offset Block 2 (always 1B0) 0x0150 4 Data offset Block 3 0x0154 4 Data offset Block 4 0x0158 4 Data offset Block 5 0x015C 4 Data offset Block 6 0x0160 4 Data offset Block 7 0x0164 4 Data offset Block 8 0x0168 4 Data offset Block 9 0x016C 4 Data offset Block 10 0x0170 4 Data offset Block 11 0x0174 4 Data offset Block 12 0x0178 4 Data offset Block 13 0x017C 4 Data offset Block 14 0x0180 4 Data offset Block 15 0x0184 4 Data offset Block 16 0x0188 4 Data offset Block 17 0x018C 4 Data offset Block 18 0x0190 4 Data offset Block 19 0x0194 4 Data offset Block 20 0x0198 4 Data offset Block 21 0x019C 4 Data offset Block 22 0x01A0 4 Data offset Block 23 0x01A4 4 Data offset Block 24 0x01A8 4 Data offset Block 25 0x01AC 4 Data offset Block 26 * Always observed as 0. No Blocks. --------------------------------------------------------------------------------- Block 2 (Plane) (168 bytes) Defines a "plane". Named because Paper Mario characters are composed mostly of single quadrilateral planes, I'm defining a plane to be a collection of polygons, which are grouped by 1 or more Block 22 blocks. For most planar characters, a plane will contain only one polygon in one Block 22, but for 3D characters or 3D objects, a plane will almost always contain many polygons, which might be split accross more than one Block 22. Rel Addr SIZE Description 0x0000 64? Name String 0x0040 4 Index Block 4 (Starting Vertex) 0x0044 4 Number Block 4 (Vertices in plane) 0x0048 4 Unknown 0x004C 4 Unknown 0x0050 4 Unknown 0x0054 4 Unknown 0x0058 4 Index Block 18 (Starting Texture Vertex) 0x005C 4 Number Block 18 (Texture vertices in plane) 0x0060 4 Index of Ending Vertex + 1? What purpose? 0x0064 4 Unknown 0x0068 4 Unknown (Same as 0x0060?) 0x006C 4 Unknown 0x0070 4 Unknown (Same as 0x0060?) 0x0074 4 Unknown 0x0078 4 Unknown (Same as 0x0060?) 0x007C 4 Unknown 0x0080 4 Unknown (Same as 0x0060?) 0x0084 4 Unknown 0x0088 4 Unknown (Same as 0x0060?) 0x008C 4 Unknown 0x0090 4 Unknown (Same as 0x0060?) 0x0094 4 Unknown 0x0098 4 Index Block 22 0x009C 4 Num Block 22 0x00A0 4 Unknown (Observed values: 0*, 1, 2, 3) 0x00A4 4 Unknown (Cull Options?) (Observed values: 1[=CullBack?], 3*[=No Cull?]) * Most common values --------------------------------------------------------------------------------- Block 3 (Polygon) (8 bytes) Defines a single polygon and the number of vertices that compose that polyon. Also shows the relative index offset for Polygon Vertex Order Points (Block 5) from the Polygon Vertex Order Point Index provided by the parent Block 22. Rel Addr SIZE Description 0x0000 4 Relative Polygon Point Index Offset (Also means number points Previously defined by polygons in the current Block22) 0x0004 4 Number Points in polygon --------------------------------------------------------------------------------- Block 4 (Vertex) (12 bytes) Defines a single polygon within the model. A vertex might be shared by many polygons. Verteces appear to represent a local assembly of sorts, and many of the models will display as scattered sub-models until appropriate transformations are applied (presumably by a combination of Block25 and Block24). Some models however display perfectly assembled by the possitioning of the verteces alone, even where other transformations are defined. Rel Addr SIZE Description 0x0000 4f X Coordinate 0x0004 4f Y Coordinate 0x0008 4f Z Coordinate --------------------------------------------------------------------------------- Block 5 (Polygon Vertex Order) (4 bytes) Defines the collection of verteces used for each polygon. Because any polygon within a given Plane can potentially share the same verteces, the verteces listed are from the same pool starting at the plane's vertexIndex, and ending at vertexIndex + the highest offset listed in a Block 5 in the given Plane. Duplicate vertices listed indicates that the vertex is shared by more than one polygon. Rel Addr SIZE Description 0x0000 4 Index of vertex from base vertex of plane --------------------------------------------------------------------------------- Block 6 (Normals) (12 bytes) Best guess is this defines normals for X, Y, and Z for each vertex in each polygon. Lately I've had fairly possitive results where lighting affected the model. Rel Addr SIZE Description 0x0000 4f X Normal 0x0004 4f Y Normal 0x0008 4f Z Normal --------------------------------------------------------------------------------- Block 7 (Normal Order) (4 bytes) Most of these values increment by 1 from start to finish, but this is not always true. They define the order in which normals are applied, which is accessed by Block 22. Rel Addr SIZE Description 0x0000 4 Index Block 6 (Normal) --------------------------------------------------------------------------------- Block 8 (Color Values) (4 bytes) Best guess is this defines color for each vertex in each polygon. The color value is represnted in RGBA8 format. Most models are white for brightest possible textures under given lighting conditions, but some of the 3D models have color defined. I'm still having difficulty properly displaying this data in a model. Rel Addr SIZE Description 0x0000 4u Color value in RGBA8 format --------------------------------------------------------------------------------- Block 9 (Color Order) (4 bytes) Same as Block 7, but for colors. Why is this levle of indirection needed anyway? Rel Addr SIZE Description 0x0000 4 Index Block 8 (Color) --------------------------------------------------------------------------------- Block 10 (Texture Point/Vertex Order) (4 bytes) Similar to Block 5, but this defines the order of vertices used in polygons for applying textures. In many models, this block will be identical to Block 5. In cases where no texture is defined for a Block22, verteces for polygons within that Block22 will not be listed. In a model with no textures, this block will be empty. Rel Addr SIZE Description 0x0000 4 Index of vertex from base vertex of plane --------------------------------------------------------------------------------- Block 18 (Texture Vertex) (8 bytes) Defines X Y coordinates for mapping a texture. Rel Addr SIZE Description 0x0000 4 s 0x0004 4 t --------------------------------------------------------------------------------- Block 19 (Unknown) (24 bytes) I do not know what this block does. In every model I've checked, the first 3 floats are 0, the next 2 are 1, and the last float is 0. This block may be texture related as it has the same number of blocks as Block 20 (Texture Map), and is located among other texture-related blocks. I also have not seen a reference to indeces in this block, but there could be an implied relationship between these blocks and Texture Map Blocks. Rel Addr SIZE Description 0x0000 4f Unknown 0x0004 4f Unknown 0x0008 4f Unknown 0x000C 4f Unknown 0x0010 4f Unknown 0x0014 4f Unknown --------------------------------------------------------------------------------- Block 20 (Texture Map) (8 bytes) The first value in this block points to one of the textures defined in the Texture path Block (Block 21). The second value is usually, but not always, 0. This block is referenced by and used for mapping textures defined in Block 21 to a given Block 22. Rel Addr SIZE Description 0x0000 4 Texture index 0x0004 4 Unknown --------------------------------------------------------------------------------- Block 21 (Texture Path Block) (64 bytes) This block has a nice text representation of a texture defined in an associated TPL file. The index at the second value doesn't point to any other block, and no block lists indeces of itself, so it probably points to a texture index within the TPL file. Rel Addr SIZE Description 0x0000 4 Unknown 0x0004 4 Index? (index of a texture in the associated TPL) 0x0008 4 Unknown 0x000C ? Name String ... --------------------------------------------------------------------------------- Block 22 (Polygon / Texture Map) (108 bytes) This block actually maps more than just textures, but is more like a sub-plane. This block defines the number of polygons within it and their index offsets, as well as maps textures. This block also gives a base index for color and normal blocks. The values between 0x14 and 0x34 are usually set to all FF, so if the value is signed, they're set to -1. I don't know their purpose, nor the purpose of the last 7 values which always appear to be 0. Rel Addr SIZE Description 0x0000 4 Unknown 0x0004 4 Unknown 0x0008 4 Unknown 0x000C 4 Unknown 0x0010 4 Texture Map Index (Index Block 20) 0x0014 4 Unknown 0x0018 4 Unknown 0x001C 4 Unknown 0x0020 4 Unknown 0x0024 4 Unknown 0x0028 4 Unknown 0x002C 4 Unknown 0x0030 4 Unknown 0x0034 4 Unknown 0x0038 4 Polygon Index (Index Block 3) 0x003C 4 Number Polygons 0x0040 4 Index Block 5 0x0044 4 Index Block 7 0x0048 4 Index Block 9 0x004C 4 Index Block 10 0x0050 4 Unknown 0x0054 4 Unknown 0x0058 4 Unknown 0x005C 4 Unknown 0x0060 4 Unknown 0x0064 4 Unknown 0x0068 4 Unknown --------------------------------------------------------------------------------- Block 23 (Block25 Plane Control) (1 byte) I've only seen this value set to 0 and 1. It's referenced by Block 25, and when used to hide the display of Block25 objects that reference a 0 here, objects which you would expect to be triggered by actions or events, such as lasers, projectiles, and odd accessories, are hidden from view. Note not all Block 25 objects have an attached Plane. This might also disable transformations associated with that Block 25. Rel Addr SIZE Description 0x0000 1 (0=Hide Block22, 1=Display Block22)? --------------------------------------------------------------------------------- Block 24 (Transformations) (4 bytes) Referenced by Block 25, these come in sets of 24 and are broken down into 8 sets of three, which are used for translating, scaling, and rotating the objects from Block 25. Transformations for a parent are applied to children. I think the implementation of this is mostly correct. I've only found 1 case so far where objects don't assemble correctly, and the order that causes them to assemble properly breaks many other more complex models. Assembly could also be dependent on what is and isn't considered a joint, but I also don't know that. If anyone can help me properly identify, order, and implement these transformations, please send me an email. Rel Addr SIZE Description 0x0000 4f Float value for various XYZ Translation,Scaling,Rotation Best Guess (Works 99% of the time) of order and application of transformations Order appled: 1, 7, 2, 8, 4, 5, 3, 6 subset 1: 0-2: Translation subset 2: 3-5: Scale subset 3: 6-8: Rotation (half-angle, ZYX) subset 4: 9-11: Rotation (full-angle, ZYX) subset 5: 12-14: Rotation Translation subset 6: 15-17: Rotation Counter-Translation subset 7: 18-20: Scale Translation subset 8: 21-23: Scale Counter-Translation --------------------------------------------------------------------------------- Block 25 (Scene Graph) (88 bytes) This block is like the superset of all others. After the description, the first 2 values I believe define a hierarchy of Planes. The first value references a sibling of the current Block25, and the second value references a child. Because only one child can be pointed at per block, the siblings create a way to put several children under a single parent. It's assumed that the children inherit all transformations from their parents before they are drawn. The last value appears to be assoicated with joints. The name string references planes, locators, groups, joints, and a few other things. I don't know what the real difference is between these (planes are obvious), but those designated as a joint have their last value set to 1 instead of 0. Rel Addr SIZE Description 0x0000 64 Name String 0x0040 4 Additional Child Block25 of parent Block25 0x0044 4 Child Block25 0x0048 4 Index Block 2 0x004C 4 Index Block 23 0x0050 4 Index Block 24 0x0054 4 Joint Related? --------------------------------------------------------------------------------- Block 26 (Animation Sequence Identifier) (64 bytes) This block acts as a pointer to an animation sequence. It doesn't appear to be tied to any other block, and is used to track animation sequences which can't be tracked in the main header because of their variable size. Rel Addr SIZE Description 0x0000 42? Name String 0x003C 4 Data offset to associated Block 27 (Animation Sequence) ################################################################################# --------------------------------------------------------------------------------- Block 27 (Variable Size, block substructure) ANIMATION SEQUENCE Each Block 27 contains an animation sequence. So far texture animation (as in changing of textures) is the only identified form of animation, but it appears 5 different types of animation can be used within a sequence. Each sequence has a time length (in milliseconds?) defined in Block 27.2, and Block 27.3 is an index of animation 'frames' that will be triggered at the right time. Each frame can contain any number of the different animation types to evaluate. It appears some of the animation sequences are designed to repeat, while others are designed to play through once. I can't yet tell them apart definitively. Block 27.1 (Header) (92 bytes) Rel Addr SIZE Description 0x0000 4 Size of block 0x0004 4 Number Block 27.2 0x0008 4 Number Block 27.3 0x000C 4 Number Block 27.4 0x0010 4 Number Block 27.5 0x0014 4 Number Block 27.6 0x0018 4 Number Block 27.7 0x001C 4 Number Block 27.8 0x0020 4 Number Block 27.9 0x0024 4 Relative Data Offset Block 27.2 0x0028 4 Relative Data Offset Block 27.3 0x002C 4 Relative Data Offset Block 27.4 0x0030 4 Relative Data Offset Block 27.5 0x0034 4 Relative Data Offset Block 27.6 0x0038 4 Relative Data Offset Block 27.7 0x003C 4 Relative Data Offset Block 27.8 0x0040 4 Relative Data Offset Block 27.9 0x0044 4f Unknown 0x0048 4f Unknown 0x004C 4f Unknown 0x0050 4f Unknown 0x0054 4f Unknown 0x0058 4f Unknown --------------------------------------------------------------------------------- Block 27.2 (12 bytes) Rel Addr SIZE Description 0x0000 4 Unknown (0=Single Pass? / 1=Loop?) 0x0004 4 Unknown 0x0008 4f Length of time in (milliseconds?) animation sequence lasts --------------------------------------------------------------------------------- Block 27.3 (Frame List) (44 bytes) Rel Addr SIZE Description 0x0000 4f Time value in (milliseconds?) associated lines are evaluated 0x0004 4 Index Block 27.4 0x0008 4 Num Associated Block 27.4 0x000C 4 Index Block 27.5 0x0010 4 Num Associated Block 27.5 0x0014 4 Index Block 27.6 0x0018 4 Num Associated Block 27.6 0x001C 4 Index Block 27.7 0x0020 4 Num Associated Block 27.7 0x0024 4 Index Block 27.8 0x0028 4 Num Associated Block 27.8 --------------------------------------------------------------------------------- Block 27.4 (4 bytes) Rel Addr SIZE Description 0x0000 4* Unknown --------------------------------------------------------------------------------- Block 27.5 (4 bytes) Rel Addr SIZE Description 0x0000 4* Unknown (4 signed bytes?) --------------------------------------------------------------------------------- Block 27.6 (12 bytes) I don't know why this block has 12 bytes. The first 2 bytes are used in changing or animating textures. The first byte identifies the texture Map affected, and the second byte determines how much its texture index is incremented or decremented. See Block 27.7 for how the indexing works, I think the indexing is the same for them both (bias), but it might not be for this block. This doesn't work for a lot of the models, and it may or may not depend on the other two unknown bytes. I don't know. Rel Addr SIZE Description 0x0000 1 Index Block 20 (Texture Map) (See Block 27.7 for indexing) 0x0001 1 Number to add to Texture Index of Block 20. 0x0002 1 Unknown (0 or -1?) 0x0003 1 Unknown (0 or -1?) 0x0004 4* Unknown 0x0008 4* Unknown --------------------------------------------------------------------------------- Block 27.7 (Plane Control) (4 bytes) This block seems responsible for revealing and hiding the different planes. It also appears that the format is broken down into 4*n bytes where n is the number of block 27.7's listed in the associated block 27.3, with the first n byte pairs actually used for settings the visibility of the planes, the first byte identifying the index of the block25 or block23, and the second being set to 1 or -1, which reveal and hide the planes respectively. The index byte is only the true index for the first pair in the set. Any indeces after that are calculated by adding the index value to all the previous index values. This still leaves the second n byte pairs, which may not be paired at all. Either way, I don't know their purpose. Rel Addr SIZE Description 2x+0x0000 1 Index Block25 or Block23 2x+0x0001 1 Reveal (1) or Hide (-1) 2n+2x+0x0? 1 Unknown 2n+2x+0x1? 1 Unknown for a set of n blocks with x as the current index --------------------------------------------------------------------------------- Block 27.8 (4 bytes) Possible Purpose: Pivot animation, IE general animation Rel Addr SIZE Description 0x0000 4* Unknown --------------------------------------------------------------------------------- Block 27.9 (8 bytes) Rel Addr SIZE Description 0x0000 4 Unknown 0x0004 4 Unknown * Unknown representation