rendered paste body#include <iostream>// Windows only probably#include <direct.h>#include "DAT1.h"using namespace std;DAT1::DAT1(){ directoryCount = 0; unknown1 = 0; unknown2 = 0; unknown3 = 0; directoryBlockSize = 0; directories = NULL;}DAT1::~DAT1(){ if (directories != NULL) { for (unsigned int i = 0; i < directoryCount; i++) { delete[] directories[i].files; } } DAT1Stream.close();}void DAT1::loadDAT1File(string filename){ DAT1Stream.open(filename.c_str(),ios::in | ios::binary); // Read the unknown values out of the header DAT1Stream.read((char *)&directoryCount,sizeof(directoryCount)); DAT1Stream.read((char *)&unknown1,sizeof(unknown1)); DAT1Stream.read((char *)&unknown2,sizeof(unknown2)); // Should be 0, not putting in a die check unless usefulness is shown DAT1Stream.read((char *)&unknown3,sizeof(unknown3)); // Swap out endian order (should check endian order perhaps) directoryCount = (directoryCount>>24) | ((directoryCount<<8) & 0x00FF0000) | ((directoryCount>>8) & 0x0000FF00) | (directoryCount<<24); unknown1 = (unknown1>>24) | ((unknown1<<8) & 0x00FF0000) | ((unknown1>>8) & 0x0000FF00) | (unknown1<<24);;; unknown2 = (unknown2>>24) | ((unknown2<<8) & 0x00FF0000) | ((unknown2>>8) & 0x0000FF00) | (unknown2<<24); unknown3 = (unknown3>>24) | ((unknown3<<8) & 0x00FF0000) | ((unknown3>>8) & 0x0000FF00) | (unknown3<<24); // Allocate an array of Directories directories = new DAT1Directory[directoryCount]; // Now we're at the directory name blocks // There is a single byte containing each // Directory name length char ctmpstr[256]; // Max possible chars per directory for (unsigned int i=0; i < directoryCount;i++) { // Don't need to manually NULL terminate C string memset(ctmpstr,0,sizeof(ctmpstr)); DAT1Stream.read((char *)&directories[i].size,sizeof(directories[i].size)); DAT1Stream.read((char *)&ctmpstr,directories[i].size); directories[i].name = ctmpstr; } for (unsigned int i=0; i < directoryCount; i++) { // Get the directory header DAT1Stream.read((char *)&directories[i].numFiles,sizeof(directories[i].numFiles)); DAT1Stream.read((char *)&directories[i].unknown1,sizeof(directories[i].unknown1)); DAT1Stream.read((char *)&directories[i].unknown2,sizeof(directories[i].unknown2)); DAT1Stream.read((char *)&directories[i].unknown3,sizeof(directories[i].unknown3)); // Fix endianness (should be conditional for big endian systems) directories[i].numFiles = (directories[i].numFiles>>24) | ((directories[i].numFiles<<8) & 0x00FF0000) | ((directories[i].numFiles>>8) & 0x0000FF00) | (directories[i].numFiles<<24); directories[i].unknown1 = (directories[i].unknown1>>24) | ((directories[i].unknown1<<8) & 0x00FF0000) | ((directories[i].unknown1>>8) & 0x0000FF00) | (directories[i].unknown1<<24); directories[i].unknown2 = (directories[i].unknown2>>24) | ((directories[i].unknown2<<8) & 0x00FF0000) | ((directories[i].unknown2>>8) & 0x0000FF00) | (directories[i].unknown2<<24); directories[i].unknown3 = (directories[i].unknown3>>24) | ((directories[i].unknown3<<8) & 0x00FF0000) | ((directories[i].unknown3>>8) & 0x0000FF00) | (directories[i].unknown3<<24); // Allocate enough file classes for each file directories[i].files = new DAT1File[directories[i].numFiles]; // Now enumerate the files in the directory for (unsigned int j = 0; j < directories[i].numFiles; j++) { // Don't need to manually NULL terminate C string memset(ctmpstr,0,sizeof(ctmpstr)); // Get filename length and filename, store it in tmp str DAT1Stream.read((char *)&directories[i].files[j].size,sizeof(directories[i].files[j].size)); DAT1Stream.read((char *)&ctmpstr,directories[i].files[j].size); // Strick it in the class directories[i].files[j].filename = ctmpstr; // Get the integers DAT1Stream.read((char *)&directories[i].files[j].attributes,sizeof(directories[i].files[j].attributes)); DAT1Stream.read((char *)&directories[i].files[j].offset,sizeof(directories[i].files[j].offset)); DAT1Stream.read((char *)&directories[i].files[j].uncompressedSize,sizeof(directories[i].files[j].uncompressedSize)); DAT1Stream.read((char *)&directories[i].files[j].compressedSize,sizeof(directories[i].files[j].compressedSize)); // Swap endian order directories[i].files[j].attributes = (directories[i].files[j].attributes>>24) | ((directories[i].files[j].attributes<<8) & 0x00FF0000) | ((directories[i].files[j].attributes>>8) & 0x0000FF00) | (directories[i].files[j].attributes<<24); directories[i].files[j].offset = (directories[i].files[j].offset>>24) | ((directories[i].files[j].offset<<8) & 0x00FF0000) | ((directories[i].files[j].offset>>8) & 0x0000FF00) | (directories[i].files[j].offset<<24); directories[i].files[j].uncompressedSize = (directories[i].files[j].uncompressedSize>>24) | ((directories[i].files[j].uncompressedSize<<8) & 0x00FF0000) | ((directories[i].files[j].uncompressedSize>>8) & 0x0000FF00) | (directories[i].files[j].uncompressedSize<<24);; directories[i].files[j].compressedSize = (directories[i].files[j].compressedSize>>24) | ((directories[i].files[j].compressedSize<<8) & 0x00FF0000) | ((directories[i].files[j].compressedSize>>8) & 0x0000FF00) | (directories[i].files[j].compressedSize<<24);; } } return;}void DAT1::decompressFile(string inFile, string outFile){ ofstream fout(outFile.c_str(),ios::out | ios::binary); DAT1File *datFile = NULL; int windowSize = 4096; for (unsigned int i=0; i < directoryCount; i++) { for (unsigned int j=0; j < directories[i].numFiles; j++) { if (directories[i].files[j].filename == inFile) //if (directories[i].files[j].compressedSize == 0) { //cout << directories[i].files[j].filename << endl; datFile = &directories[i].files[j]; break; } } } if (datFile == NULL) { cout << "Could not find file " << inFile << endl; return; } else { printf("Offset: 0x%0x\n",datFile->offset); } DAT1Stream.seekg(datFile->offset); cout << "Compressed size: " << datFile->compressedSize << endl; int filesize = (datFile->compressedSize) ? datFile->compressedSize : datFile->uncompressedSize; char *buf = new char[filesize]; DAT1Stream.read((char *)buf,filesize); fout.write((char *)buf, filesize); fout.close();}void DAT1::decompress(){ ofstream fout; int filesize = 0; for (unsigned int i=0; i < directoryCount; i++) { if (directories[i].name != ".") { cout << "Creating: " << directories[i].name << endl; _mkdir(directories[i].name.c_str()); } for (unsigned int j=0; j < directories[i].numFiles; j++) { /*fout.open((directories[i].name + directories[i].files[j].filename).c_str(),ios::out | ios::binary); DAT1Stream.seekg(directories[i].files[j].offset); if (directories[i].files[j].compressedSize > 0) { filesize = directories[i].files[j].compressedSize; } else { filesize = directories[i].files[j].uncompressedSize; } cout << "Extracting " << directories[i].name + "\\" + directories[i].files[j].filename; cout << " Size (" << filesize << ") bytes" << endl; char *buf = new char[filesize]; DAT1Stream.read((char *)buf,filesize); fout.write((char *)buf, filesize); fout.close(); delete[] buf;*/ } }}void DAT1::printDAT1Info(string inFilename){ ofstream Boo(inFilename.c_str(),ios::out); Boo << "[Header Information]" << endl; Boo << "Directory Count: " << directoryCount << endl; Boo << "Unknown #1: " << unknown1 << endl; Boo << "Unknown #2: " << unknown2 << endl; Boo << "Unknown #3: " << unknown3 << endl; Boo << "Directory Block Size: " << directoryBlockSize << endl; Boo << endl; Boo << "[Directories]" << endl; for (unsigned int i=0; i < directoryCount; i++) { Boo << "Directory Name: " << directories[i].name << endl; //Boo << "Number of files: " << directories[i].numFiles << endl; //for (unsigned int j=0; j < directories[i].numFiles; j++) //{ // Boo << "File Name: " << directories[i].files[j].filename << endl; //} } Boo.close();}