MM2 Reference

Midnight Club

Introduction Format Vehicles Hud map Sky Dome Midnight Club

Midnight Club

The game Midnight Club, MC, uses a similar game engine as MM2. However there are some significant differences in the PKG-format of Midnight Club. These differences are not yet fully understood, but this section gives a suggestion for interpretation.

Geometry sections

Some objects in MC use a new graphics construct. Several separate strips can be described in the same geometry structure. This is controlled by bit 8 in the flags of the PKGSection. This flag also controls the data type of several attributes of the strips, presenting a more compact way of representing the geometry.

As a part of this more compact representation, normals are not represented by vectors. Instead Euler angles are used to give the direction of the normal. The angles are given in three unsigned bytes as a value between 0 and 255, yielding a full revolution in 256 steps. (This range is not yet verified)

union PKGSection { STDPKGSection stdSection; // If flags indicate standard sections CompactPKGSection compactSection; // If flags indicate compact sections } // Standard section - A single actual strip per strip, this is the only // format used in MM2. // // STDPKGSection { ushort nStrips; // Number of geometry strips in this section ushort flags; // Unknown flags, bit 8 clear long shaderOffset; // Offset into the shader list of the requested // paintjob PKGStrip[nStrips] strips; } // Compact section - Each strip can contain several separate strips and data // types are smaller than in the standard section. // // CompactPKGSection { ushort nStrips; // Number of geometry strips in this section ushort flags; // Unknown flags, bit 8 set ushort shaderOffset; // Offset into the shader list of the requested // paintjob PKGCompactStrip[nStrips] strips; } PKGCompactStrip { ushort verticesPerFace; // Indicates triangles or quads ushort nVertices; // Number of vertices in this section PKGCompactVertex[nVertices] vertices; ushort nIndices; // Number of indices making up the geometry strip PKGCompactIndex[nIndices] indices; } PKGCompactIndex { ushort index; // Index in vertex list, bit 14 and 15 are special: // bit 14: Vertex order is reversed for this strip // bit 15: Indicates the end of a strip } struct PKGOrientation { unsigned char xAngle; // Integer angle of unknown range, assumed 0-255 unsigned char yAngle; // Integer angle of unknown range, assumed 0-255 unsigned char zAngle; // Integer angle of unknown range, assumed 0-255 } PKGCompactTex2D { ushort x; // Fixed point value s = (x / 128f) ushort y; // Fixed point value t = (y / 128f) } PKGCompactVertex { Vertex3D coordinate; // If PKGFileData.flags indicate // coordinates PKGOrientation normal; // If PKGFileData.flags indicate normals ulong unknown; // If PKGFileData.flags indicate unknown PKGCompactTex2D textureCoordinate; // If PKGFileData.flags indicate texture // coordinates }

Description of the bits for the PKGFILEData.flags field:

Bit 1
Texture coordinates or coordinates
Bit 4
Normals
Bit 6
Unknown value, 32 bits
Bit 8
Coordinates or texture coordinates

All other bits are unknown at this time.