/* Copyright (C) 2006 Parallel Realities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../headers.h" Pak::Pak() { input = NULL; numberOfFiles = 0; uncompressedSize = 0; fileDataTable.name = "PAK File"; setPakFile(PAKNAME); } Pak::~Pak() { clear(); } Pak *Pak::getInstance() { return &instance; } void Pak::clear() { if (input != NULL) { delete[] input; } fileDataTable.clear(); input = NULL; } void Pak::showPakErrorAndExit() { printf("\nFatal Error: The Blob and Conquer PAK file was either not found or was not accessable.\n"); printf("The file was expected to be found within,\n\n"); printf(PAKFULLPATH"\n\n"); printf("Please try running the game again. If problems persist either reinstall the game or check,\n\n"); printf("http://www.parallelrealities.co.uk/blobAndConquer.php\n\n"); printf("for updates.\n\n"); exit(1); } void Pak::setPakFile(char *pakFilename) { uLongf listPos; strcpy(this->pakFilename, pakFilename); debug(("Pak : Filename set to %s\n", pakFilename)); FILE *pak = fopen(pakFilename, "rb"); if (!pak) { return; } fseek(pak, (-sizeof(Uint32)) * 2, SEEK_END); fread(&listPos, sizeof(Uint32), 1, pak); fread(&numberOfFiles, sizeof(Uint32), 1, pak); listPos = SDL_SwapLE32(listPos); numberOfFiles = SDL_SwapLE32(numberOfFiles); debug(("Pak : File list resides at %d\n", (int)listPos)); debug(("Pak : Number of files are %d\n", (int)numberOfFiles)); fseek(pak, listPos, SEEK_SET); FileData *fileData; for (unsigned int i = 0 ; i < numberOfFiles ; i++) { fileData = new FileData(); if (!fread(fileData, sizeof(FileData), 1, pak)) { printf("WARNING: Pak::setPakFile - UNEXPECTED END OF FILE DATA ENCOUNTERED!\n"); break; } fileDataTable.put(fileData->filename, fileData); } fclose(pak); } bool Pak::unpack(char *filename, unsigned char **buffer) { debug(("Pak : Unpacking %s...\n", filename)); bool found = false; FileData *fileData = (FileData*)fileDataTable.get(filename); if (fileData == NULL) { return false; } debug(("Found %s. Uncompressing...\n", fileData->filename)); FILE *pak = fopen(pakFilename, "rb"); if (!pak) { showPakErrorAndExit(); } fseek(pak, fileData->location, SEEK_SET); if (input != NULL) { delete[] input; } input = NULL; input = new unsigned char[(int)(fileData->cSize * 1.01) + 12]; *buffer = new unsigned char[fileData->fSize]; fread(input, 1, fileData->cSize, pak); fclose(pak); uncompress(*buffer, &fileData->fSize, input, fileData->cSize); uncompressedSize = fileData->fSize; found = true; if (input != NULL) { delete[] input; } input = NULL; debug(("Pak : Unpack %s...Done\n", filename)); return found; } bool Pak::fileExistsInFS(char *filename) { FILE *fp = fopen(filename, "rb"); if (fp != NULL) { fclose(fp); return true; } return false; } bool Pak::fileExistsInPak(char *filename) { if (fileDataTable.getSize() == 0) { return false; } if (fileDataTable.get(filename) != NULL) { return true; } return false; } int Pak::getFileLocation(char *filename) { char installedFileName[1024]; sprintf(installedFileName, "%s/%s", PAKLOCATION, filename); if (fileExistsInFS(filename)) { strcpy(validFileName, filename); return FILE_IN_FS; } else if (fileExistsInFS(installedFileName)) { strcpy(validFileName, installedFileName); return FILE_IN_FS; } else if (fileExistsInPak(filename)) { return FILE_IN_PAK; } return FILE_NOT_FOUND; } char *Pak::getFileName() { return validFileName; } unsigned int Pak::getUncompressedSize() { return uncompressedSize; } Pak Pak::instance;