serthy
3rd January 2014, 20:11
Happy New Year!
Here are all file formats i've done so far.
All formats are little endian and use the same basic types.
These are templates of a hex editor, basically C-style so everyone should be able to understand this.
With them i was able to decompile some simple models and textures, but the code is rly poor atm, if its worth, ill release it in the near future.
Here you go:
[CoD2 iwi]
LittleEndian();
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
local int DXTVERSION = 0;
typedef struct
{
u8 start_I;
u8 start_W;
u8 start_i;
u8 version;
u8 DXTformat; //0x0b -> DXT1? | 0x0d -> DXT5?
u8 flag;
u16 width;
u16 height;
u16 u3;
u32 lol[4];
if( start_I != 73 || start_W != 87 || start_i != 105 )
return 0;
else if( version != 0x05 )
return -2;
if( DXTformat == 0x0b )
DXTVERSION = 1;
else if( DXTformat == 0x0d )
DXTVERSION = 5;
else
return -3;
if( u3 != 1 )
return -4;
else if( flag != 1 && flag != 0 )
return -5;
} HEADER;
typedef struct
{
u16 color0;
u16 color1;
u8 index[4];
} COLORBLOCK;
typedef struct
{
COLORBLOCK cb;
} DXT1;
typedef struct
{
u8 alpha[8];
COLORBLOCK cb;
} DXT3;
typedef struct
{
u8 alpha1;
u8 alpha2;
u8 alpha_indices[6];
COLORBLOCK cb;
} DXT5;
local int getSize( local int width , local int height , local int depth )
{
return ( ( width + 3 ) / 4 ) * ( ( height + 3 ) / 4 );// * ( DXTVERSION == 0 ? 8 : 16 );
}
local int getMipmapCount( local int width , local int height )
{
local int max = width > height ? width : height;
local int count = 0;
local int i = 0;
for( i = 0 ; max >> i > 0 ; i++ )
{
count++;
}
return count;
}
void readMipmap( local int count )
{
if( DXTVERSION == 1 )
DXT1 blocks[count] <optimize=false>;
else if( DXTVERSION == 3 )
DXT3 blocks[count] <optimize=false>;
else if( DXTVERSION == 5 )
DXT5 blocks[count] <optimize=false>;
}
typedef struct
{
HEADER header;
local int numMipmaps = getMipmapCount( header.width , header.height );
Printf( "numMipmaps: %d\n" , numMipmaps );
while( numMipmaps > 0 )
{
numMipmaps--;
readMipmap( getSize( header.width >> numMipmaps , header.height >> numMipmaps , 4 ) );
}
} IWI;
IWI x;
Okay, the iwi structure is kind of simple, it is DXT compressed and seems to have always all possible mipmaps.
There are still some unknown bits, but i am able to convert alot of textures to dds and tga yet.
[CoD2 xModel]
//SetBackColor( cLtPurple );
//BigEndian();
LittleEndian();
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
//SetBackColor( cLtGreen );
//SetBackColor( cNone );
typedef struct
{
u16 start;
} HEADER;
typedef struct
{
f32 x;
f32 y;
f32 z;
} VEC3;
typedef struct
{
SetBackColor( cLtGreen );
string name;
} MATERIALNAME;
typedef struct
{
VEC3 min;
VEC3 max;
} MINMAX;
typedef struct
{
VEC3 min;
VEC3 max;
} BOUNDS;
typedef struct
{
f32 LODdistance;
string LODxmodelsurfs;
} LOD;
typedef struct
{
VEC3 normal;
VEC3 xVec; //
VEC3 yVec; //
VEC3 zVec; //
} COLLFACE;
typedef struct
{
u16 numMaterials;
MATERIALNAME materials[numMaterials] <optimize=false>;
} LODMATERIAL;
typedef struct
{
SetBackColor( cLtGreen );
HEADER header;
u8 groundLit; // 00
BOUNDS bounds;
local int numLOD = 1;
LOD lod[numLOD] <optimize=false>;
f32 ukn;
u32 endLOD_null;
SetBackColor( cLtRed );
u8 u4[3];
//u32 unknown0;
u32 unknown1;
i32 unknown2;
i32 hasColl;
if( hasColl > 0 )
{
u32 numCollData;
COLLFACE c[numCollData];
MINMAX mm1;
u8 unknown3[12];
}
SetBackColor( cLtGreen );
LODMATERIAL LODMat[numLOD] <optimize=false>;
SetBackColor( cLtYellow );
local int count = 1;
MINMAX mm2[count];
} XMODEL;
XMODEL x;
Okay, the xModel format seems to be more troublesome when i did this first look some weeks ago, seems that all collision data (if any, LOD to HIGH) is in this file.
[CoD2 xModelSurf]
LittleEndian();
// modelType 0 -> rigid
// modelType 1 -> animated
// modelType 2 -> viewmodel
// modelType 3 -> playerbody
// modelType 4 -> viewhands
local int fileType = 2;
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
typedef struct
{
f32 x;
f32 y;
f32 z;
} VEC3;
typedef struct
{
SetBackColor( cLtGreen );
u8 color_b; //OK!
u8 color_g; //OK!
u8 color_r; //OK!
u8 color_a; //OK!
SetBackColor( cNone );
} COLOR;
typedef struct
{
f32 u;
f32 v;
} UV;
local int modus = 1; //different possibilities to read this chunk
typedef struct
{
if( modus == 0 )
{
u16 boneID;
VEC3 v1;
u16 unkn;
}
else
{
u8 unkn1;
u16 boneID;
VEC3 v1;
u8 unkn2;
}
} CHUNK;
typedef struct
{
VEC3 normal;
COLOR color;
UV uv;
if( fileType == 0 )
{
u8 lol1[4];
f32 unknownFloats[4];
u8 lol2[4];
VEC3 position;
}
else if( fileType == 1 )
{
f32 unknownFloats[6];
u8 chunkCount;
u16 u7;
VEC3 position;
if( chunkCount != 0 )
{
if( modus == 0 )
i8 y;
Printf( "%d\n" , chunkCount );
CHUNK chunk[chunkCount] <optimize=false>;
if( modus != 0 )
u8 lol;
}
}
} VERTEX;
typedef struct
{
u16 start; //14 00
} HEADER;
typedef struct
{
u16 ID[3];
} VERTORDER;
typedef struct
{
u8 u1;
u16 numVerts;
u16 numTris;
if( u1 == 0 && ReadUShort( FTell() ) != 0 )
{
u8 u2 , u3;
Printf( "u2 = %d | u3 = %d\n" , u2 , u3 );
}
u16 u4;
VERTEX v[numVerts] <optimize=false>;
VERTORDER vertOrder[numTris] <optimize=false>;
} MATCHUNK;
typedef struct
{
HEADER header;
u16 numMatChunks;
MATCHUNK mc[numMatChunks] <optimize=false>;
} XMODELSURF;
XMODELSURF x;
I didnt get the mesh weight part to the vertices, and also some coords (Z-coord) is kind of distorted, but cant remember correctly for now.
[CoD2 xModelPart]
LittleEndian();
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
local int modelType = 1;
// modelType 0 -> rigid
// modelType 1 -> animated
// modelType 2 -> viewmodel
// modelType 3 -> playerbody
// modelType 4 -> viewhands
typedef struct
{
u16 start;
} HEADER;
typedef struct
{
string name;
} BONENAME;
typedef struct
{
u8 parentBoneID;
if( modelType == 0 || modelType == 1 ) //rigid|animated
{
f32 x; // offset relative to its
f32 y; // parent bone position
f32 z; // they seem distorted/wrong im 50% of all cases
i16 unkn[3];
}
else if( modelType == 3 ) // playerbody
{
u8 unknown[18]; // differs from the same model as modelType = 2
}
else if( modelType == 2 || modelType == 4 ) // viewmodel & viewhands
{
f32 zero[3];
u8 unknown[6];
}
} RELATIVE;
typedef struct
{
HEADER header;
u16 numBonesRelative; // position relative to parent bone
u16 numBonesAbsolute; // position absolute to world/origin
RELATIVE rel[numBonesRelative] <optimize=false>;
BONENAME bones[numBonesRelative + numBonesAbsolute] <optimize=false>;
u8 unknown[numBonesRelative + numBonesAbsolute]; // hit location ID? depends on jointnames
} XMODELPARTS;
XMODELPARTS x;
The xModelPart is known to 99% if i remember correctly. So there shouldnt be any problems here.
I've done them some weeks ago, so i dont remember correctly if theyre the latest ones and when they apply.
Would apprecciate it if some1 want to help me to unreveal the complete formats, also for other ones.
If you improved them, please share them to the remaining community and make them public!
Cheers, Serthy
Here are all file formats i've done so far.
All formats are little endian and use the same basic types.
These are templates of a hex editor, basically C-style so everyone should be able to understand this.
With them i was able to decompile some simple models and textures, but the code is rly poor atm, if its worth, ill release it in the near future.
Here you go:
[CoD2 iwi]
LittleEndian();
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
local int DXTVERSION = 0;
typedef struct
{
u8 start_I;
u8 start_W;
u8 start_i;
u8 version;
u8 DXTformat; //0x0b -> DXT1? | 0x0d -> DXT5?
u8 flag;
u16 width;
u16 height;
u16 u3;
u32 lol[4];
if( start_I != 73 || start_W != 87 || start_i != 105 )
return 0;
else if( version != 0x05 )
return -2;
if( DXTformat == 0x0b )
DXTVERSION = 1;
else if( DXTformat == 0x0d )
DXTVERSION = 5;
else
return -3;
if( u3 != 1 )
return -4;
else if( flag != 1 && flag != 0 )
return -5;
} HEADER;
typedef struct
{
u16 color0;
u16 color1;
u8 index[4];
} COLORBLOCK;
typedef struct
{
COLORBLOCK cb;
} DXT1;
typedef struct
{
u8 alpha[8];
COLORBLOCK cb;
} DXT3;
typedef struct
{
u8 alpha1;
u8 alpha2;
u8 alpha_indices[6];
COLORBLOCK cb;
} DXT5;
local int getSize( local int width , local int height , local int depth )
{
return ( ( width + 3 ) / 4 ) * ( ( height + 3 ) / 4 );// * ( DXTVERSION == 0 ? 8 : 16 );
}
local int getMipmapCount( local int width , local int height )
{
local int max = width > height ? width : height;
local int count = 0;
local int i = 0;
for( i = 0 ; max >> i > 0 ; i++ )
{
count++;
}
return count;
}
void readMipmap( local int count )
{
if( DXTVERSION == 1 )
DXT1 blocks[count] <optimize=false>;
else if( DXTVERSION == 3 )
DXT3 blocks[count] <optimize=false>;
else if( DXTVERSION == 5 )
DXT5 blocks[count] <optimize=false>;
}
typedef struct
{
HEADER header;
local int numMipmaps = getMipmapCount( header.width , header.height );
Printf( "numMipmaps: %d\n" , numMipmaps );
while( numMipmaps > 0 )
{
numMipmaps--;
readMipmap( getSize( header.width >> numMipmaps , header.height >> numMipmaps , 4 ) );
}
} IWI;
IWI x;
Okay, the iwi structure is kind of simple, it is DXT compressed and seems to have always all possible mipmaps.
There are still some unknown bits, but i am able to convert alot of textures to dds and tga yet.
[CoD2 xModel]
//SetBackColor( cLtPurple );
//BigEndian();
LittleEndian();
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
//SetBackColor( cLtGreen );
//SetBackColor( cNone );
typedef struct
{
u16 start;
} HEADER;
typedef struct
{
f32 x;
f32 y;
f32 z;
} VEC3;
typedef struct
{
SetBackColor( cLtGreen );
string name;
} MATERIALNAME;
typedef struct
{
VEC3 min;
VEC3 max;
} MINMAX;
typedef struct
{
VEC3 min;
VEC3 max;
} BOUNDS;
typedef struct
{
f32 LODdistance;
string LODxmodelsurfs;
} LOD;
typedef struct
{
VEC3 normal;
VEC3 xVec; //
VEC3 yVec; //
VEC3 zVec; //
} COLLFACE;
typedef struct
{
u16 numMaterials;
MATERIALNAME materials[numMaterials] <optimize=false>;
} LODMATERIAL;
typedef struct
{
SetBackColor( cLtGreen );
HEADER header;
u8 groundLit; // 00
BOUNDS bounds;
local int numLOD = 1;
LOD lod[numLOD] <optimize=false>;
f32 ukn;
u32 endLOD_null;
SetBackColor( cLtRed );
u8 u4[3];
//u32 unknown0;
u32 unknown1;
i32 unknown2;
i32 hasColl;
if( hasColl > 0 )
{
u32 numCollData;
COLLFACE c[numCollData];
MINMAX mm1;
u8 unknown3[12];
}
SetBackColor( cLtGreen );
LODMATERIAL LODMat[numLOD] <optimize=false>;
SetBackColor( cLtYellow );
local int count = 1;
MINMAX mm2[count];
} XMODEL;
XMODEL x;
Okay, the xModel format seems to be more troublesome when i did this first look some weeks ago, seems that all collision data (if any, LOD to HIGH) is in this file.
[CoD2 xModelSurf]
LittleEndian();
// modelType 0 -> rigid
// modelType 1 -> animated
// modelType 2 -> viewmodel
// modelType 3 -> playerbody
// modelType 4 -> viewhands
local int fileType = 2;
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
typedef struct
{
f32 x;
f32 y;
f32 z;
} VEC3;
typedef struct
{
SetBackColor( cLtGreen );
u8 color_b; //OK!
u8 color_g; //OK!
u8 color_r; //OK!
u8 color_a; //OK!
SetBackColor( cNone );
} COLOR;
typedef struct
{
f32 u;
f32 v;
} UV;
local int modus = 1; //different possibilities to read this chunk
typedef struct
{
if( modus == 0 )
{
u16 boneID;
VEC3 v1;
u16 unkn;
}
else
{
u8 unkn1;
u16 boneID;
VEC3 v1;
u8 unkn2;
}
} CHUNK;
typedef struct
{
VEC3 normal;
COLOR color;
UV uv;
if( fileType == 0 )
{
u8 lol1[4];
f32 unknownFloats[4];
u8 lol2[4];
VEC3 position;
}
else if( fileType == 1 )
{
f32 unknownFloats[6];
u8 chunkCount;
u16 u7;
VEC3 position;
if( chunkCount != 0 )
{
if( modus == 0 )
i8 y;
Printf( "%d\n" , chunkCount );
CHUNK chunk[chunkCount] <optimize=false>;
if( modus != 0 )
u8 lol;
}
}
} VERTEX;
typedef struct
{
u16 start; //14 00
} HEADER;
typedef struct
{
u16 ID[3];
} VERTORDER;
typedef struct
{
u8 u1;
u16 numVerts;
u16 numTris;
if( u1 == 0 && ReadUShort( FTell() ) != 0 )
{
u8 u2 , u3;
Printf( "u2 = %d | u3 = %d\n" , u2 , u3 );
}
u16 u4;
VERTEX v[numVerts] <optimize=false>;
VERTORDER vertOrder[numTris] <optimize=false>;
} MATCHUNK;
typedef struct
{
HEADER header;
u16 numMatChunks;
MATCHUNK mc[numMatChunks] <optimize=false>;
} XMODELSURF;
XMODELSURF x;
I didnt get the mesh weight part to the vertices, and also some coords (Z-coord) is kind of distorted, but cant remember correctly for now.
[CoD2 xModelPart]
LittleEndian();
typedef float f32;
typedef double f64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef char i8;
typedef short i16;
typedef int i32;
local int modelType = 1;
// modelType 0 -> rigid
// modelType 1 -> animated
// modelType 2 -> viewmodel
// modelType 3 -> playerbody
// modelType 4 -> viewhands
typedef struct
{
u16 start;
} HEADER;
typedef struct
{
string name;
} BONENAME;
typedef struct
{
u8 parentBoneID;
if( modelType == 0 || modelType == 1 ) //rigid|animated
{
f32 x; // offset relative to its
f32 y; // parent bone position
f32 z; // they seem distorted/wrong im 50% of all cases
i16 unkn[3];
}
else if( modelType == 3 ) // playerbody
{
u8 unknown[18]; // differs from the same model as modelType = 2
}
else if( modelType == 2 || modelType == 4 ) // viewmodel & viewhands
{
f32 zero[3];
u8 unknown[6];
}
} RELATIVE;
typedef struct
{
HEADER header;
u16 numBonesRelative; // position relative to parent bone
u16 numBonesAbsolute; // position absolute to world/origin
RELATIVE rel[numBonesRelative] <optimize=false>;
BONENAME bones[numBonesRelative + numBonesAbsolute] <optimize=false>;
u8 unknown[numBonesRelative + numBonesAbsolute]; // hit location ID? depends on jointnames
} XMODELPARTS;
XMODELPARTS x;
The xModelPart is known to 99% if i remember correctly. So there shouldnt be any problems here.
I've done them some weeks ago, so i dont remember correctly if theyre the latest ones and when they apply.
Would apprecciate it if some1 want to help me to unreveal the complete formats, also for other ones.
If you improved them, please share them to the remaining community and make them public!
Cheers, Serthy