// seg 55 #include "common.h" #ifdef WIN32 #include #endif extern "C" { extern char homePath[512]; } typedef struct pakInfoStruct // warning: alignment unsafe { s32 discSize; s32 uncompressedSize; char compressionFlag; char info5; s16 offset; }; typedef struct pakInfoStruct pakInfoStruct; //#define USE_UNPACKED_DATA void readPakInfo(pakInfoStruct* pPakInfo, FILE* fileHandle) { fread(&pPakInfo->discSize,4,1,fileHandle); fread(&pPakInfo->uncompressedSize,4,1,fileHandle); fread(&pPakInfo->compressionFlag,1,1,fileHandle); fread(&pPakInfo->info5,1,1,fileHandle); fread(&pPakInfo->offset,2,1,fileHandle); pPakInfo->discSize = READ_LE_U32(&pPakInfo->discSize); pPakInfo->uncompressedSize = READ_LE_U32(&pPakInfo->uncompressedSize); pPakInfo->offset = READ_LE_U16(&pPakInfo->offset); } unsigned int PAK_getNumFiles(const char* name) { char bufferName[512]; FILE* fileHandle; u32 fileOffset; strcpy(bufferName, homePath); strcat(bufferName, name); // temporary until makeExtention is coded strcat(bufferName,".PAK"); fileHandle = fopen(bufferName,"rb"); if (!fileHandle) return 0; ASSERT(fileHandle); fseek(fileHandle,4,SEEK_CUR); fread(&fileOffset,4,1,fileHandle); #ifdef MACOSX fileOffset = READ_LE_U32(&fileOffset); #endif fclose(fileHandle); return((fileOffset/4)-2); } int LoadPak(const char* name, int index, char* ptr) { #ifdef USE_UNPACKED_DATA char buffer[256]; FILE* fHandle; int size; sprintf(buffer,"%s/%04X.OUT",name,index); fHandle = fopen(buffer,"rb"); if(!fHandle) return(0); fseek(fHandle,0L,SEEK_END); size = ftell(fHandle); fseek(fHandle,0L,SEEK_SET); fread(ptr,size,1,fHandle); fclose(fHandle); return(1); #else char* lptr; lptr = loadPak(name,index); memcpy(ptr,lptr,getPakSize(name,index)); free(lptr); return(1); #endif } int getPakSize(const char* name, int index) { #ifdef USE_UNPACKED_DATA char buffer[256]; FILE* fHandle; int size; sprintf(buffer,"%s/%04X.OUT",name,index); fHandle = fopen(buffer,"rb"); if(!fHandle) return(0); fseek(fHandle,0L,SEEK_END); size = ftell(fHandle); fseek(fHandle,0L,SEEK_SET); fclose(fHandle); return (size); #else char bufferName[512]; FILE* fileHandle; s32 fileOffset; s32 additionalDescriptorSize; pakInfoStruct pakInfo; s32 size=0; strcpy(bufferName, homePath); strcat(bufferName, name); // temporary until makeExtention is coded strcat(bufferName,".PAK"); fileHandle = fopen(bufferName,"rb"); if(fileHandle) // a bit stupid, should return NULL right away { fseek(fileHandle,(index+1)*4,SEEK_SET); fread(&fileOffset,4,1,fileHandle); fileOffset = READ_LE_U32(&fileOffset); fseek(fileHandle,fileOffset,SEEK_SET); fread(&additionalDescriptorSize,4,1,fileHandle); additionalDescriptorSize = READ_LE_U32(&additionalDescriptorSize); readPakInfo(&pakInfo,fileHandle); fseek(fileHandle,pakInfo.offset,SEEK_CUR); if(pakInfo.compressionFlag == 0) // uncompressed { size = pakInfo.discSize; } else if(pakInfo.compressionFlag == 1) // compressed { size = pakInfo.uncompressedSize; } else if(pakInfo.compressionFlag == 4) { size = pakInfo.uncompressedSize; } fclose(fileHandle); } return size; #endif } char* loadPak(const char* name, int index) { if(PAK_getNumFiles(name) < index) return NULL; //dumpPak(name); #ifdef USE_UNPACKED_DATA char buffer[256]; FILE* fHandle; int size; char* ptr; sprintf(buffer,"%s/%04X.OUT",name,index); fHandle = fopen(buffer,"rb"); if(!fHandle) return NULL; fseek(fHandle,0L,SEEK_END); size = ftell(fHandle); fseek(fHandle,0L,SEEK_SET); ptr = (char*)malloc(size); fread(ptr,size,1,fHandle); fclose(fHandle); return ptr; #else char bufferName[512]; FILE* fileHandle; u32 fileOffset; u32 additionalDescriptorSize; pakInfoStruct pakInfo; char* ptr=0; //makeExtention(bufferName, name, ".PAK"); strcpy(bufferName, homePath); strcat(bufferName, name); // temporary until makeExtention is coded strcat(bufferName,".PAK"); fileHandle = fopen(bufferName,"rb"); if(fileHandle) // a bit stupid, should return NULL right away { char nameBuffer[256] = ""; fseek(fileHandle,(index+1)*4,SEEK_SET); fread(&fileOffset,4,1,fileHandle); fileOffset = READ_LE_U32(&fileOffset); fseek(fileHandle,fileOffset,SEEK_SET); fread(&additionalDescriptorSize,4,1,fileHandle); additionalDescriptorSize = READ_LE_U32(&additionalDescriptorSize); if(additionalDescriptorSize) { fseek(fileHandle, additionalDescriptorSize-4, SEEK_CUR); } readPakInfo(&pakInfo,fileHandle); if(pakInfo.offset) { ASSERT(pakInfo.offset<256); fread(nameBuffer,pakInfo.offset,1,fileHandle); #ifdef FITD_DEBUGGER printf("Loading %s/%s\n", name,nameBuffer+2); #endif } else { fseek(fileHandle,pakInfo.offset,SEEK_CUR); } switch(pakInfo.compressionFlag) { case 0: { ptr = (char*)malloc(pakInfo.discSize); fread(ptr,pakInfo.discSize,1,fileHandle); break; } case 1: { char * compressedDataPtr = (char *) malloc(pakInfo.discSize); fread(compressedDataPtr, pakInfo.discSize, 1, fileHandle); ptr = (char *) malloc(pakInfo.uncompressedSize); PAK_explode((unsigned char*)compressedDataPtr, (unsigned char*)ptr, pakInfo.discSize, pakInfo.uncompressedSize, pakInfo.info5); free(compressedDataPtr); break; } case 4: { char * compressedDataPtr = (char *) malloc(pakInfo.discSize); fread(compressedDataPtr, pakInfo.discSize, 1, fileHandle); ptr = (char *) malloc(pakInfo.uncompressedSize); PAK_deflate((unsigned char*)compressedDataPtr, (unsigned char*)ptr, pakInfo.discSize, pakInfo.uncompressedSize); free(compressedDataPtr); break; } default: assert(false); break; } fclose(fileHandle); } return ptr; #endif } void dumpPak(const char* name) { #ifdef WIN32 unsigned int numEntries = PAK_getNumFiles(name); for (unsigned int index = 0; index < numEntries; index++) { char bufferName[512]; FILE* fileHandle; u32 fileOffset; u32 additionalDescriptorSize; pakInfoStruct pakInfo; char* ptr = 0; //makeExtention(bufferName, name, ".PAK"); strcpy(bufferName, homePath); strcat(bufferName, name); // temporary until makeExtention is coded strcat(bufferName, ".PAK"); fileHandle = fopen(bufferName, "rb"); if (fileHandle) // a bit stupid, should return NULL right away { char nameBuffer[256] = ""; fseek(fileHandle, (index + 1) * 4, SEEK_SET); fread(&fileOffset, 4, 1, fileHandle); fileOffset = READ_LE_U32(&fileOffset); fseek(fileHandle, fileOffset, SEEK_SET); fread(&additionalDescriptorSize, 4, 1, fileHandle); additionalDescriptorSize = READ_LE_U32(&additionalDescriptorSize); if (additionalDescriptorSize) { fseek(fileHandle, additionalDescriptorSize - 4, SEEK_CUR); } readPakInfo(&pakInfo, fileHandle); if (pakInfo.offset) { ASSERT(pakInfo.offset < 256); fread(nameBuffer, pakInfo.offset, 1, fileHandle); #ifdef FITD_DEBUGGER printf("Loading %s/%s\n", name, nameBuffer + 2); #endif } else { fseek(fileHandle, pakInfo.offset, SEEK_CUR); } switch (pakInfo.compressionFlag) { case 0: { ptr = (char*)malloc(pakInfo.discSize); fread(ptr, pakInfo.discSize, 1, fileHandle); break; } case 1: { char * compressedDataPtr = (char *)malloc(pakInfo.discSize); fread(compressedDataPtr, pakInfo.discSize, 1, fileHandle); ptr = (char *)malloc(pakInfo.uncompressedSize); PAK_explode((unsigned char*)compressedDataPtr, (unsigned char*)ptr, pakInfo.discSize, pakInfo.uncompressedSize, pakInfo.info5); free(compressedDataPtr); break; } case 4: { char * compressedDataPtr = (char *)malloc(pakInfo.discSize); fread(compressedDataPtr, pakInfo.discSize, 1, fileHandle); ptr = (char *)malloc(pakInfo.uncompressedSize); PAK_deflate((unsigned char*)compressedDataPtr, (unsigned char*)ptr, pakInfo.discSize, pakInfo.uncompressedSize); free(compressedDataPtr); break; } default: assert(false); break; } fclose(fileHandle); { mkdir(name); char outputName[256]; sprintf(outputName, "%s/%02d_%s", name, index, nameBuffer + 2); FILE* foutputHandle = fopen(outputName, "wb+"); if (foutputHandle) { fwrite(ptr, pakInfo.uncompressedSize, 1, foutputHandle); fclose(foutputHandle); } } } } #endif }