mirror of https://github.com/yaz0r/FITD.git
403 lines
10 KiB
C++
403 lines
10 KiB
C++
// seg 55
|
|
|
|
#include "common.h"
|
|
|
|
#ifdef WIN32
|
|
#include <direct.h>
|
|
#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
|
|
}
|