Posted: Fri Sep 14, 2007 7:19 pm
no program
Code: Select all
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
struct GELHeader
{
int i1;
int i2;
int numberOfElements;
int i4;
int i5;
int i6;
void print()
{
//printf( "i1 = %d\n", i1 );
//printf( "i2 = %d\n", i2 );
printf( "numberOfElements = %d\n", numberOfElements );
//printf( "i4 = %d\n", i4 );
//printf( "i5 = %d\n", i5 );
//printf( "i6 = %d\n", i6 );
printf( "\n" );
}
};
struct GELEntry
{
int i1;
int i2;
char filename[128];
int i3;
int startOffset;
int dataSize;
int i6;
void print()
{
//printf( "i1 = %d\n", i1 );
//printf( "i2 = %d\n", i2 );
printf( "filename = %s\n", filename );
//printf( "i3 = %d\n", i3 );
printf( "startOffset = %d\n", startOffset );
printf( "dataSize = %d\n", dataSize );
//printf( "i6 = %d\n", i6 );
printf( "\n" );
}
};
// Set this to the .GEL file that you want to extract
std::string srcGel = "C:\\Rohan\\res\\model\\Building\\skeleton.gel";
// Set this to the .GEM file that matches the .GEL file you want to extract
std::string srcGem = "C:\\Rohan\\res\\model\\Building\\skeleton.gem";
// This is the path where all the files will be extracted to
std::string destPath = "C:\\RohanData\\model\\Building";
int main()
{
FILE* gelFP = 0;
fopen_s( &gelFP, srcGel.c_str(), "rb" );
if( gelFP )
{
FILE* gemFP = 0;
fopen_s( &gemFP, srcGem.c_str(), "rb" );
if( gemFP )
{
GELHeader gelHeader;
fread( &gelHeader, sizeof( GELHeader ), 1, gelFP );
//gelHeader.print();
for( int i=0; i<gelHeader.numberOfElements; i++ )
{
GELEntry gelEntry;
fread( &gelEntry, sizeof( GELEntry ), 1, gelFP );
//gelEntry.print();
printf( "\b\b\b\b\b\b\b%d", i + 1 );
if( gelEntry.dataSize > 0 )
{
// Create the file
std::string sFilename = gelEntry.filename;
size_t pos = sFilename.find_last_of( "\\" );
std::string path = sFilename.substr( 0, pos + 1 );
std::string filename = sFilename.substr( pos + 1, sFilename.length() - pos );
//printf( "Path = %s\nFile = %s\n", path.c_str(), filename.c_str() );
std::string newPath = destPath;
newPath.append( path );
CreateDirectory( newPath.c_str(), NULL );
// Detect GTX files (DDS files with the header changed and the extension changed
pos = filename.find_last_of( "." );
//printf( "pos = %d\n", pos );
std::string ext = filename.substr( pos + 1, filename.length() - pos - 1 );
//printf( "ext = %s\n", ext.c_str() );
if( ext.find( "gtx" ) != std::string::npos )
{
//printf( "Found GTX file!\n" );
char* data = (char*)malloc( gelEntry.dataSize );
fseek( gemFP, gelEntry.startOffset, 0 );
fread( data, gelEntry.dataSize, 1, gemFP );
if( data[0] == 'G' && data[1] == 'E' && data[2] == 'O' )
{
// Most gtx files are DDS files with the "Magic Word" changed to GEO. We change that here, before
// writing the file
filename.replace( pos + 1, 3, "dds" );
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
data[0] = 'D';
data[1] = 'D';
data[2] = 'S';
FILE* outFP = 0;
fopen_s( &outFP, fullPath.c_str(), "wb" );
if( outFP )
{
fwrite( data, gelEntry.dataSize, 1, outFP );
fclose( outFP );
}
}
else if( data[0] == 'D' && data[1] == 'D' && data[2] == 'S' )
{
// Sometimes, DDS files have the proper header in them
filename.replace( pos + 1, 3, "dds" );
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
FILE* outFP = 0;
fopen_s( &outFP, fullPath.c_str(), "wb" );
if( outFP )
{
fwrite( data, gelEntry.dataSize, 1, outFP );
fclose( outFP );
}
}
else
{
// Haven't come across this yet, but just in case, we'll know.
printf( "\n" );
printf( "Encountered UNKNOWN GTX file!\n" );
printf( "%c %c %c\n", data[0], data[1], data[2] );
printf( "\n" );
}
free( data );
}
else
{
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
FILE* outFP = 0;
fopen_s( &outFP, fullPath.c_str(), "wb" );
if( outFP )
{
void* data = malloc( gelEntry.dataSize );
fseek( gemFP, gelEntry.startOffset, 0 );
fread( data, gelEntry.dataSize, 1, gemFP );
fwrite( data, gelEntry.dataSize, 1, outFP );
free( data );
fclose( outFP );
}
}
}
}
printf( "\n\n" );
fclose( gemFP );
}
fclose( gelFP );
}
return 0;
}
Code: Select all
/* ROHAN ONLINE .IEF FORMAT
* BY PRINCEWADII
* 01/27/08 4:50 AM
* Description: .ief files group all meshes that
* belong together and store their .gmf file names
* and material names.
*/
//=============
// HEADER
//=============
dword header //always 0x00 00 00 00
dword typeCount
//============
// DATA
//============
struct Type[typeCount] //normal armor, event armor, head deco, etc..
{
dword typeID
dword setCount
struct Set[setCount] //combination of parts that form a full armor for example
{
dword setID
struct Part[4]
/*Parts always come in sets of 4 (ex: upper body,
lower body, glove, boot)*/
{
dword partLen
char[partLen] bodyPart //Example: Upper Body
dword meshCount //Number of meshes per part
struct Mesh [meshCount]
{
dword meshLen
char[meshLen] meshName //example: c_am_body01.gmf
dword matCount //Number of materials per mesh
struct Materials [matCount]
{
dword matLen
char[matLen] material //Example: Material #01001
}
}
}
}
}