From 26ee630756ebdd7c96bccede0881a8c8b98e8f2b Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 11 Feb 2006 22:45:04 +0000 Subject: Moved engines to the new engines/ directory svn-id: r20582 --- engines/queen/resource.cpp | 287 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 engines/queen/resource.cpp (limited to 'engines/queen/resource.cpp') diff --git a/engines/queen/resource.cpp b/engines/queen/resource.cpp new file mode 100644 index 0000000000..51fa47b687 --- /dev/null +++ b/engines/queen/resource.cpp @@ -0,0 +1,287 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003-2006 The ScummVM project + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "queen/resource.h" + +namespace Queen { + +#ifdef PALMOS_68K +static ResourceEntry *_resourceTablePEM10; +#endif + +const char *Resource::_tableFilename = "queen.tbl"; + +const GameVersion Resource::_gameVersions[] = { + { "PEM10", 0x00000008, 22677657 }, + { "CEM10", 0x0000584E, 190787021 }, + { "PFM10", 0x0002CD93, 22157304 }, + { "CFM10", 0x00032585, 186689095 }, + { "PGM10", 0x00059ACA, 22240013 }, + { "CGM10", 0x0005F2A7, 217648975 }, + { "PIM10", 0x000866B1, 22461366 }, + { "CIM10", 0x0008BEE2, 190795582 }, + { "CSM10", 0x000B343C, 190730602 }, + { "CHM10", 0x000DA981, 190705558 }, + { "PE100", 0x00101EC6, 3724538 }, + { "PE100", 0x00102B7F, 3732177 }, + { "PEint", 0x00103838, 1915913 } +}; + +static int compareResourceEntry(const void *a, const void *b) { + const char *filename = (const char *)a; + const ResourceEntry *entry = (const ResourceEntry *)b; + return strcmp(filename, entry->filename); +} + +Resource::Resource() + : _resourceEntries(0), _resourceTable(NULL) { + _resourceFile = new Common::File(); + if (!findCompressedVersion() && !findNormalVersion()) + error("Could not open resource file '%s'", "queen.1"); + checkJASVersion(); + debug(5, "Detected game version: %s, which has %d resource entries", _versionString, _resourceEntries); +} + +Resource::~Resource() { + _resourceFile->close(); + delete _resourceFile; + + if (_resourceTable != _resourceTablePEM10) + delete[] _resourceTable; +} + +ResourceEntry *Resource::resourceEntry(const char *filename) const { + assert(filename[0] && strlen(filename) < 14); + + char entryName[14]; + char *ptr = entryName; + + strcpy(entryName, filename); + do + *ptr = toupper(*ptr); + while (*ptr++); + + ResourceEntry *re = NULL; +#ifndef PALMOS_MODE + re = (ResourceEntry *)bsearch(entryName, _resourceTable, _resourceEntries, sizeof(ResourceEntry), compareResourceEntry); +#else + // PALMOS FIXME (?) : still doesn't work for me (????) use this instead + uint32 cur = 0; + do { + if (!strcmp(entryName, _resourceTable[cur].filename)) { + re = &_resourceTable[cur]; + break; + } + } while (cur++ < _resourceEntries); +#endif + return re; +} + +uint8 *Resource::loadFile(const char *filename, uint32 skipBytes, uint32 *size, bool useMalloc) { + ResourceEntry *re = resourceEntry(filename); + assert(re != NULL); + uint32 sz = re->size - skipBytes; + if (size != NULL) { + *size = sz; + } + + byte *dstBuf; + if (useMalloc) { + dstBuf = (byte *)malloc(sz); + } else { + dstBuf = new byte[sz]; + } + + _resourceFile->seek(re->offset + skipBytes); + _resourceFile->read(dstBuf, sz); + return dstBuf; +} + +bool Resource::findNormalVersion() { + _resourceFile->open("queen.1"); + if (!_resourceFile->isOpen()) { + return false; + } + + _compression = COMPRESSION_NONE; + + // detect game version based on resource file size ; we try to + // verify that it is indeed the version we think it is later on + const GameVersion *gameVersion = detectGameVersion(_resourceFile->size()); + if (gameVersion == NULL) + error("Unknown/unsupported FOTAQ version"); + + strcpy(_versionString, gameVersion->versionString); + if (!readTableFile(gameVersion)) { + // check if it is the english floppy version, for which we have a hardcoded version of the table + if (!strcmp(gameVersion->versionString, _gameVersions[VER_ENG_FLOPPY].versionString)) { + _resourceEntries = 1076; + _resourceTable = _resourceTablePEM10; + } else { + error("Could not find tablefile '%s'", _tableFilename); + } + } + return true; +} + +bool Resource::findCompressedVersion() { + _resourceFile->open("queen.1c"); + if (!_resourceFile->isOpen()) { + return false; + } + readTableCompResource(); + return true; +} + +void Resource::checkJASVersion() { + ResourceEntry *re = resourceEntry("QUEEN.JAS"); + assert(re != NULL); + uint32 offset = re->offset; + if (isDemo()) + offset += JAS_VERSION_OFFSET_DEMO; + else if (isInterview()) + offset += JAS_VERSION_OFFSET_INTV; + else + offset += JAS_VERSION_OFFSET_PC; + _resourceFile->seek(offset); + + char versionStr[6]; + _resourceFile->read(versionStr, 6); + if (strcmp(_versionString, versionStr)) + error("Verifying game version failed! (expected: '%s', found: '%s')", _versionString, versionStr); +} + +Language Resource::getLanguage() const { + switch (_versionString[1]) { + case 'E': + return ENGLISH; + case 'G': + return GERMAN; + case 'F': + return FRENCH; + case 'I': + return ITALIAN; + case 'S': + return SPANISH; + case 'H': + return HEBREW; + default: + return ENGLISH; + } +} + +bool Resource::readTableFile(const GameVersion *gameVersion) { + Common::File tableFile; + tableFile.open(_tableFilename); + if (tableFile.isOpen() && tableFile.readUint32BE() == 'QTBL') { + if (tableFile.readUint32BE() != CURRENT_TBL_VERSION) + warning("Incorrect version of queen.tbl, please update it"); + tableFile.seek(gameVersion->tableOffset); + readTableEntries(&tableFile); + return true; + } + return false; +} + +void Resource::readTableCompResource() { + if (_resourceFile->readUint32BE() != 'QTBL') + error("Invalid table header"); + + _resourceFile->read(_versionString, 6); + _resourceFile->readByte(); // obsolete + _resourceFile->readByte(); // obsolete + _compression = _resourceFile->readByte(); + + readTableEntries(_resourceFile); +} + +void Resource::readTableEntries(Common::File *file) { + _resourceEntries = file->readUint16BE(); + _resourceTable = new ResourceEntry[_resourceEntries]; + for (uint16 i = 0; i < _resourceEntries; ++i) { + ResourceEntry *re = &_resourceTable[i]; + file->read(re->filename, 12); + re->filename[12] = '\0'; + re->bundle = file->readByte(); + re->offset = file->readUint32BE(); + re->size = file->readUint32BE(); + } +} + +const GameVersion *Resource::detectGameVersion(uint32 size) const { + const GameVersion *pgv = _gameVersions; + for (int i = 0; i < VER_COUNT; ++i, ++pgv) { + if (pgv->dataFileSize == size) { + return pgv; + } + } + return NULL; +} + +Common::File *Resource::giveCompressedSound(const char *filename, uint32 *size) { + assert(strstr(filename, ".SB")); + Common::File *f = NULL; + ResourceEntry *re = resourceEntry(filename); + if (re) { + if (size != NULL) { + *size = re->size; + } + _resourceFile->seek(re->offset); + f = _resourceFile; + } + return f; +} + +LineReader::LineReader(char *buffer, uint32 bufsize) : _buffer(buffer), _bufSize(bufsize), _current(0) { +} + +LineReader::~LineReader() { + delete[] _buffer; +} + +char *LineReader::nextLine() { + char *startOfLine = _buffer + _current; + char *curPos = startOfLine; + while (curPos < _buffer + _bufSize && *curPos++ != 0xd) ; + *(curPos - 1) = '\0'; // '\r' + if (curPos < _buffer + _bufSize) { + *curPos = '\0'; // '\n' + _current = (curPos - _buffer) + 1; + } + return startOfLine; +} + +} // End of namespace Queen + +#ifdef PALMOS_68K +#include "scumm_globals.h" + +_GINIT(Queen_Restables) +_GSETPTR(Queen::_resourceTablePEM10, GBVARS_RESOURCETABLEPM10_INDEX, Queen::ResourceEntry, GBVARS_QUEEN) +_GEND + +_GRELEASE(Queen_Restables) +_GRELEASEPTR(GBVARS_RESOURCETABLEPM10_INDEX, GBVARS_QUEEN) +_GEND + +#endif -- cgit v1.2.3