#include #include #include char *sections[] = { "None", "Struct", "String", "Extension", "Unknown", "Camera", "Texture", "Material", "Material List", "Atomic Section", "Plane Section", "World", "Spline", "Matrix", "Frame List", "Geometry", "Clump", "Unknown", "Light", "Unicode String", "Atomic", "Texture Native", "Texture Dictionary", "Animation Database", "Image", "Skin Animation", "Geometry List", "Anim Animation", "Team", "Crowd", "Delta Morph Animation", "Right To Render", "MultiTexture Effect Native", "MultiTexture Effect Dictionary", "Team Dictionary", "Platform Independet Texture Dictionary", "Table of Contents", "Particle Standard Global Data", "AltPipe", "Platform Independet Peds", "Patch Mesh", "Chunk Group Start", "Chunk Group End", "UV Animation Dictionary", "Coll Tree" }; /* From 0x0101 through 0x0135 */ char *toolkitsections0[] = { "Metrics PLG", "Spline PLG", "Stereo PLG", "VRML PLG", "Morph PLG", "PVS PLG", "Memory Leak PLG", "Animation PLG", "Gloss PLG", "Logo PLG", "Memory Info PLG", "Random PLG", "PNG Image PLG", "Bone PLG", "VRML Anim PLG", "Sky Mipmap Val", "MRM PLG", "LOD Atomic PLG", "ME PLG", "Lightmap PLG", "Refine PLG", "Skin PLG", "Label PLG", "Particles PLG", "GeomTX PLG", "Synth Core PLG", "STQPP PLG", "Part PP PLG", "Collision PLG", "HAnim PLG", "User Data PLG", "Material Effects PLG", "Particle System PLG", "Delta Morph PLG", "Patch PLG", "Team PLG", "Crowd PP PLG", "Mip Split PLG", "Anisotrophy PLG", "Not used", "GCN Material PLG", "Geometric PVS PLG", "XBOX Material PLG", "Multi Texture PLG", "Chain PLG", "Toon PLG", "PTank PLG", "Particle Standard PLG", "PDS PLG", "PrtAdv PLG", "Normal Map PLG", "ADC PLG", "UV Animation PLG" }; /* From 0x0180 through 0x01c1 */ char *toolkitsections1[] = { "Character Set PLG", "NOHS World PLG", "Import Util PLG", "Slerp PLG", "Optim PLG", "TL World PLG", "Database PLG", "Raytrace PLG", "Ray PLG", "Library PLG", "Not used", "Not used", "Not used", "Not used", "Not used", "Not used", "2D PLG", "Tile Render PLG", "JPEG Image PLG", "TGA Image PLG", "GIF Image PLG", "Quat PLG", "Spline PVS PLG", "Mipmap PLG", "MipmapK PLG", "2D Font", "Intersection PLG", "TIFF Image PLG", "Pick PLG", "BMP Image PLG", "RAS Image PLG", "Skin FX PLG", "VCAT PLG", "2D Path", "2D Brush", "2D Object", "2D Shape", "2D Scene", "2D Pick Region", "2D Object String", "2D Animation PLG", "2D Animation", "Not used", "Not used", "Not used", "Not used", "Not used", "Not used", "2D Keyframe", "2D Maestro", "Barycentric", "Platform Independent Texture Dictionary TK", "TOC TK", "TPL TK", "AltPipe TK", "Animation TK", "Skin Split Tookit", "Compressed Key TK", "Geometry Conditioning PLG", "Wing PLG", "Generic Pipeline TK", "Lightmap Conversion TK", "Filesystem PLG", "Dictionary TK", "UV Animation Linear", "UV Animation Parameter" }; char *RSsections[] = { "Unused 1", "Unused 2", "Unused 3", "Pipeline Set", "Unused 5", "Unused 6", "Specular Material", "Unused 8", "2dfx", "Night Vertex Colors", "Collision Model", "Unused 12", "Reflection Material", "Mesh Extension", "Frame", "Unused 16" }; typedef struct rwheader { unsigned int type; unsigned int size; unsigned int version; } rwheader; rwheader readheader(FILE *rw) { rwheader rwh; fread(&rwh, 4, 3, rw); return rwh; } int isheader(rwheader rwh, int vers) { if (rwh.version == vers) return 1; return 0; } void getsectname(char *name, int type) { if (type <= 45) strcpy(name, sections[type]); else if (type <= 0x0253F2FF && type >= 0x0253F2F0) { strcpy(name, RSsections[type-0x0253F2F0]); } else if (type <= 0x0135 && type >= 0x0101) { strcpy(name, toolkitsections0[type-0x0101]); } else if (type <= 0x0180 && type >= 0x01c1) { strcpy(name, toolkitsections1[type-0x0180]); } else { strcpy(name, "Unknown"); } switch (type) { case 0x50E: strcpy(name, "Bin Mesh PLG"); break; case 0x510: strcpy(name, "Native Data PLG"); break; case 0xF21E: strcpy(name, "ZModeler Lock"); break; default: break; } } void readsection(rwheader *rwh, int pos, int vers, int level, FILE *rw) { rwheader newheader; unsigned int end; int i; char name[64]; for (i = 0; i < level; i++) printf(" "); getsectname(name, rwh->type); printf("%s (%d bytes @ 0x%lX/0x%lX) - [0x%X]\n", name, rwh->size, ftell(rw)-12, ftell(rw), rwh->type); end = ftell(rw) + rwh->size; loop: if (ftell(rw) >= end) return; newheader = readheader(rw); if (isheader(newheader, vers)) { readsection(&newheader, ftell(rw), vers, level+1, rw); if (rwh->type == 0x510) { fseek(rw, end, 0); } goto loop; } else fseek(rw, rwh->size-12, SEEK_CUR); } int main(int argc, char *argv[]) { FILE *rw; rwheader rwh; int vers, end; if (argc < 2) { printf("Usage: %s rw\n", argv[0]); exit(1); } if ((rw = fopen(argv[1], "rb")) == NULL) { printf("Could not open file: %s\n", argv[1]); exit(1); } fseek(rw, 0, SEEK_END); end = ftell(rw); fseek(rw, 0, SEEK_SET); while (ftell(rw) < end) { rwh = readheader(rw); vers = rwh.version; readsection(&rwh, ftell(rw), vers, 0, rw); printf("RW version: %X\n", vers); } return 0; }