All pastes #781457 Raw Edit

Something

public text v1 · immutable
·published 2007-11-18 21:37 UTC
rendered paste body
	//|=============================================|
	//|			  G3d Extractor "g3dEx.exe"			|
	//|			  (C) Matthew Leonard 2003		    |
	//|												|
	//|					 [g3dEx.cpp]				|
	//|=============================================|

/*
If you modify this source code and distribute the binary the source code also must be included as well as all original copyright notices.

CONTACT INFO

To mail me please use lenny@bwgarage.co.uk
I can also be found on these message boards: http://boards.bwgame.com as lenny_la9
*/

#include <iostream.h>
#include <fstream.h>
#include <direct.h>
#include <string.h>
#include <stdlib.h>

void createDirectory(char *dirName);

int main (void)
{
	//make directorys to save textures and meshes too 
	createDirectory("\\textures");
	createDirectory("\\meshes");

	//file variables
	long currentTexture;
	long textureTotal = 0;
	long fileSize;
	char *fileData;
	char ddsHeader []= {'D', 'D', 'S', ' '}; //in the g3d file these 4 bytes indicate the filesize, however in a DDS file the first 4 bytes need to be "DDS ".

	fstream fileIn;
	fstream fileOut;
	fstream fileHeader;

	fileIn.open("AllMeshes.g3d", ios::in | ios::binary);
	if(fileIn.is_open ())
	{
		//===============
		// High-res textures are first so we extract them
		//===============
		fileIn.seekg (48, ios::cur); //skip past all the file header info
		cout << "Extracting high resolution textures.." << endl;
		
		do
		{
			fileIn.read((char *) &currentTexture, 4); // find out the current texture number
			
			if (textureTotal < currentTexture)
				textureTotal = currentTexture;

			fileIn.seekg (4, ios::cur);
			fileIn.read((char *) &fileSize, 4); //read in the texture size
//			fileSize -=4;

			fileData = new char [fileSize+1]; //dimension memory to hold the texture data
			fileIn.read((char *) &fileData[0], sizeof(char) * fileSize);
			fileData[fileSize] = '\0';
			
			// ===== Find output dir/ name =====
			char chrTex[4]; //hold the texture number as char
			itoa(currentTexture, chrTex, 10);
			char textureFile[256] = "textures\\";
			strcat(textureFile, chrTex);
			strcat(textureFile, ".dds");

			fileOut.open (textureFile, ios::out | ios::binary);
			if (fileOut.is_open ())
			{
				fileOut.write ((char *) &ddsHeader[0], sizeof(char) * 4);
				fileOut.write ((char *) &fileData[0], sizeof(char) * (fileSize-4));

			}
			delete [] fileData;

			fileIn.seekg (36, ios::cur);
			fileOut.close ();

		} while (currentTexture != 1);
		
		cout << "Completed\n\nExtracting l3d meshes" << endl;
		
		//===============
		// Mesh offsets come now, then the actual l3d data.
		//===============
		
		//Before doing anything else we read the AllMeshes.h into memory and sort through it to get the names of all meshes.

		fileIn.seekg (4136, ios::cur);
		
		long numMeshes;
		long *meshOffset;
		long currentOffset=0;
		long meshInfoOffset;
		char l3dHeader[3];
		int l3dLength;

		fileIn.read((char *) &numMeshes, 4); //read in the texture size
		meshInfoOffset = fileIn.tellg();
		meshInfoOffset -=8;

		meshOffset = new long [numMeshes]; //dimension memory to hold mesh offsets
		
		for (int meshRun = 0; meshRun < numMeshes; meshRun++)
		{
			fileIn.read((char *) &meshOffset[meshRun], 4); //read in the texture size
		}

		fileHeader.open("standardmesh.txt", ios::in);
		if (fileHeader.is_open ())
		{
			
			char meshName[255];
			int mshCount = 0;
			char meshNumber[255];
			
			fileHeader.getline (meshNumber ,100);

			//now read in the actual l3d data
			for (meshRun = 0; (meshRun) < numMeshes; meshRun++)
			{
				
				//dps tuff for file header name
				mshCount ++;
				fileHeader.getline (meshName ,100);
				//fileHeader >> meshName;
				//cout << "mesh" << mshCount << ": " << meshName << "\n";

				currentOffset = meshInfoOffset + meshOffset[meshRun];
				
				fileIn.read((char *) &l3dHeader[0], sizeof(char) * 4);
				
				if (l3dHeader[0] != 'L')
					if (l3dHeader[1] != '3')
						if (l3dHeader[2] != 'D')
							if (l3dHeader[3] != '0')
							{
								cout << "ERROR! Could not find l3d header information.\n";
								return 0;
							}

				//fileIn.seekg(currentOffset, ios::beg);
				fileIn.seekg(4, ios::cur); //move forward 4 bytes to get l3d size.
				fileIn.read((char *) &l3dLength, 4);
				fileData = new char [l3dLength+1]; //dimension memory to hold the l3d data
				fileIn.seekg(currentOffset, ios::beg); //now we return to the beginning of the l3d file (move back 8 bytes).
				fileIn.read((char *) &fileData[0], sizeof(char) * l3dLength);

				// ===== Find output dir/ name =====
				char l3dFile[256] = "meshes\\";
				strcat(l3dFile, meshName);
				strcat(l3dFile, ".l3d");

				fileOut.open (l3dFile, ios::out | ios::binary);
				if (fileOut.is_open ())
					fileOut.write ((char *) &fileData[0], sizeof(char) * l3dLength);
				
				delete [] fileData;
				fileOut.close ();

			}
		}
		fileHeader.close ();
//		currentOffset += (l3dLength + l3dLength);
//		fileIn.seekg(currentOffset, ios::beg);
		
		//===============
		// Before finishing, extract the low res textures
		//===============
		
		cout << "Completed\n\nExtracting low resolution ('-low') textures.." << endl;

		//fileIn.seekg (3, ios::cur);
		char lowTexTag[3];
		currentTexture = textureTotal;
		do
		{
			
			fileIn.read((char *) &lowTexTag, 4); // find out the current texture number
			if (lowTexTag[0] != 'L')
				if (lowTexTag[1] != 'O')
					if (lowTexTag[2] != 'W')
					{
						cout << "invalid low textures\n";
						break;
					}

									
			fileIn.seekg (44, ios::cur);
			fileIn.read((char *) &fileSize, 4); //read in the texture size
						
			fileData = new char [fileSize+1]; //dimension memory to hold the texture data
			fileIn.read((char *) &fileData[0], sizeof(char) * fileSize);
			fileData[fileSize] = '\0';
			
			// ===== Find output dir/ name =====
			char chrTex[4]; //hold the texture number as char
			itoa(currentTexture, chrTex, 10);
			char textureFile[256] = "textures\\";
			strcat(chrTex, "-low");
			strcat(textureFile, chrTex);
			strcat(textureFile, ".dds");

			fileOut.open (textureFile, ios::out | ios::binary);
			if (fileOut.is_open ())
			{
				fileOut.write ((char *) &ddsHeader[0], sizeof(char) * 4);
				fileOut.write ((char *) &fileData[0], sizeof(char) * (fileSize-4));

			}
			delete [] fileData;

			//fileIn.seekg (44, ios::cur);
			fileOut.close ();
			currentTexture --;
			//currentOffset -= 4;
			currentOffset = fileIn.tellg();
			currentOffset -=4;
			fileIn.seekg(currentOffset, ios::beg);

		} while (currentTexture != 0);
		
		cout << "Completed.\n\n";
		

	}
	else
	{
		cout << "could not open G3D file"; //if we cant open the file, give the user an error message.
		return 0;
	}
	cout << "The contents of the G3D file have been successfulyl extracted to the \\meshes and \\textures folders.\n\n";

	// clean up
	fileIn.close ();
	return 0;
}

void createDirectory(char *dirName)
{
	char curDir[255];
	char finalDir[255];

	getcwd(curDir, 255); //get working directory
	strcpy(finalDir, curDir);
	strcat(finalDir, dirName);
	mkdir(finalDir); //make the new directory

}