/* * * file.cpp * * 3rd February 2009: Created file.cpp from parts of util.cpp * * Part of the OpenJazz project * * * Copyright (c) 2005-2009 Alister Thomson * * OpenJazz is distributed under the terms of * the GNU General Public License, version 2.0 * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "file.h" #include "io/gfx/video.h" File::File (char * fileName, bool write) { // Open the file from the current directory f = fopen(fileName, write ? "wb": "rb"); // If that succeeded, done if (f) { //log("Opened file", fileName); filePath = createString(fileName); return; } // Create the file path filePath = createString(path, fileName); // Open the file from the path f = fopen(filePath, write ? "wb": "rb"); if (f == NULL) { log("Could not open file", fileName); delete[] filePath; throw E_FILE; } //log("Opened file", filePath); return; } File::~File () { fclose(f); //log("Closed file", filePath); delete[] filePath; return; } int File::getSize () { int pos, size; pos = ftell(f); fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, pos, SEEK_SET); return size; } int File::tell () { return ftell(f); } void File::seek (int offset, bool reset) { fseek(f, offset, reset ? SEEK_SET: SEEK_CUR); return; } unsigned char File::loadChar () { return fgetc(f); } void File::storeChar (unsigned char val) { fputc(val, f); return; } unsigned short int File::loadShort () { unsigned short int val; val = fgetc(f); val += fgetc(f) << 8; return val; } void File::storeShort (unsigned short int val) { fputc(val & 255, f); fputc(val >> 8, f); return; } signed long int File::loadInt () { unsigned long int val; val = fgetc(f); val += fgetc(f) << 8; val += fgetc(f) << 16; val += fgetc(f) << 24; return *((signed long int *)&val); } void File::storeInt (signed long int val) { unsigned long int uval; uval = *((unsigned long int *)&val); fputc(uval & 255, f); fputc((uval >> 8) & 255, f); fputc((uval >> 16) & 255, f); fputc(uval >> 24, f); return; } unsigned char * File::loadBlock (int length) { unsigned char *buffer; buffer = new unsigned char[length]; fread(buffer, 1, length, f); return buffer; } unsigned char * File::loadRLE (int length) { unsigned char *buffer; int rle, pos, byte, count, next; // Determine the offset that follows the block next = fgetc(f); next += fgetc(f) << 8; next += ftell(f); buffer = new unsigned char[length]; pos = 0; while (pos < length) { rle = fgetc(f); if (rle > 127) { byte = fgetc(f); for (count = 0; count < (rle & 127); count++) { buffer[pos++] = byte; if (pos >= length) break; } } else if (rle > 0) { for (count = 0; count < rle; count++) { buffer[pos++] = fgetc(f); if (pos >= length) break; } } else buffer[pos++] = fgetc(f); } fseek(f, next, SEEK_SET); return buffer; } void File::skipRLE () { int next; next = fgetc(f); next += fgetc(f) << 8; fseek(f, next, SEEK_CUR); return; } char * File::loadString () { char *string; int length, count; length = fgetc(f); count = 0; if (length) { string = new char[length + 1]; for (; count < length; count++) string[count] = fgetc(f); } else { // If the length is not given, assume it is an 8.3 file name string = new char[13]; for (; count < 9; count++) { string[count] = fgetc(f); if (string[count] == '.') { string[++count] = fgetc(f); string[++count] = fgetc(f); string[++count] = fgetc(f); count++; break; } } } string[count] = 0; return string; } SDL_Surface * File::loadSurface (int width, int height) { return createSurface(loadRLE(width * height), width, height); } void File::loadPalette (SDL_Color *palette) { unsigned char *buffer; int count; buffer = loadRLE(768); for (count = 0; count < 256; count++) { // Palette entries are 6-bit // Shift them upwards to 8-bit, and fill in the lower 2 bits palette[count].r = (buffer[count * 3] << 2) + (buffer[count * 3] >> 4); palette[count].g = (buffer[(count * 3) + 1] << 2) + (buffer[(count * 3) + 1] >> 4); palette[count].b = (buffer[(count * 3) + 2] << 2) + (buffer[(count * 3) + 2] >> 4); } delete[] buffer; return; }