[Scummvm-cvs-logs] SF.net SVN: scummvm:[35484] scummvm/trunk/engines/saga
thebluegr at users.sourceforge.net
thebluegr at users.sourceforge.net
Mon Dec 22 15:13:15 CET 2008
Revision: 35484
http://scummvm.svn.sourceforge.net/scummvm/?rev=35484&view=rev
Author: thebluegr
Date: 2008-12-22 14:13:15 +0000 (Mon, 22 Dec 2008)
Log Message:
-----------
- Split the SAGA resource manager in 3 different ones, depending on the resource type (RSC for ITE, RES for IHNM and HRS for DINO/FTA2). The SAGA 2 HRS resource manager is still a stub
- Added detection for the voice file of FTA2
Modified Paths:
--------------
scummvm/trunk/engines/saga/actor.cpp
scummvm/trunk/engines/saga/animation.cpp
scummvm/trunk/engines/saga/detection.cpp
scummvm/trunk/engines/saga/events.cpp
scummvm/trunk/engines/saga/font.cpp
scummvm/trunk/engines/saga/gfx.cpp
scummvm/trunk/engines/saga/interface.cpp
scummvm/trunk/engines/saga/introproc_ihnm.cpp
scummvm/trunk/engines/saga/introproc_ite.cpp
scummvm/trunk/engines/saga/module.mk
scummvm/trunk/engines/saga/music.cpp
scummvm/trunk/engines/saga/saga.cpp
scummvm/trunk/engines/saga/scene.cpp
scummvm/trunk/engines/saga/script.cpp
scummvm/trunk/engines/saga/sfuncs.cpp
scummvm/trunk/engines/saga/sndres.cpp
scummvm/trunk/engines/saga/sprite.cpp
Added Paths:
-----------
scummvm/trunk/engines/saga/resource.cpp
scummvm/trunk/engines/saga/resource.h
scummvm/trunk/engines/saga/resource_hrs.cpp
scummvm/trunk/engines/saga/resource_res.cpp
scummvm/trunk/engines/saga/resource_rsc.cpp
Removed Paths:
-------------
scummvm/trunk/engines/saga/rscfile.cpp
scummvm/trunk/engines/saga/rscfile.h
Modified: scummvm/trunk/engines/saga/actor.cpp
===================================================================
--- scummvm/trunk/engines/saga/actor.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/actor.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -31,7 +31,7 @@
#include "saga/events.h"
#include "saga/isomap.h"
#include "saga/objectmap.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/script.h"
#include "saga/sndres.h"
#include "saga/sound.h"
Modified: scummvm/trunk/engines/saga/animation.cpp
===================================================================
--- scummvm/trunk/engines/saga/animation.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/animation.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -32,7 +32,7 @@
#include "saga/events.h"
#include "saga/interface.h"
#include "saga/render.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/scene.h"
#include "saga/animation.h"
Modified: scummvm/trunk/engines/saga/detection.cpp
===================================================================
--- scummvm/trunk/engines/saga/detection.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/detection.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -37,7 +37,7 @@
#include "saga/animation.h"
#include "saga/displayinfo.h"
#include "saga/events.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/interface.h"
#include "saga/scene.h"
Modified: scummvm/trunk/engines/saga/events.cpp
===================================================================
--- scummvm/trunk/engines/saga/events.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/events.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -35,7 +35,7 @@
#include "saga/palanim.h"
#include "saga/render.h"
#include "saga/sndres.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/music.h"
#include "saga/actor.h"
Modified: scummvm/trunk/engines/saga/font.cpp
===================================================================
--- scummvm/trunk/engines/saga/font.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/font.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -27,7 +27,7 @@
#include "saga/saga.h"
#include "saga/gfx.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/font.h"
#include "saga/render.h"
Modified: scummvm/trunk/engines/saga/gfx.cpp
===================================================================
--- scummvm/trunk/engines/saga/gfx.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/gfx.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -28,7 +28,7 @@
#include "saga/saga.h"
#include "saga/gfx.h"
#include "saga/interface.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/scene.h"
#include "saga/render.h"
Modified: scummvm/trunk/engines/saga/interface.cpp
===================================================================
--- scummvm/trunk/engines/saga/interface.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/interface.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -42,7 +42,7 @@
#include "saga/script.h"
#include "saga/sound.h"
#include "saga/sprite.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/interface.h"
Modified: scummvm/trunk/engines/saga/introproc_ihnm.cpp
===================================================================
--- scummvm/trunk/engines/saga/introproc_ihnm.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/introproc_ihnm.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -32,7 +32,7 @@
#include "saga/events.h"
#include "saga/interface.h"
#include "saga/render.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/sndres.h"
#include "saga/music.h"
Modified: scummvm/trunk/engines/saga/introproc_ite.cpp
===================================================================
--- scummvm/trunk/engines/saga/introproc_ite.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/introproc_ite.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -36,7 +36,7 @@
#include "saga/music.h"
#include "saga/scene.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
namespace Saga {
Modified: scummvm/trunk/engines/saga/module.mk
===================================================================
--- scummvm/trunk/engines/saga/module.mk 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/module.mk 2008-12-22 14:13:15 UTC (rev 35484)
@@ -24,7 +24,10 @@
palanim.o \
puzzle.o \
render.o \
- rscfile.o \
+ resource.o \
+ resource_hrs.o \
+ resource_res.o \
+ resource_rsc.o \
saga.o \
saveload.o \
scene.o \
Modified: scummvm/trunk/engines/saga/music.cpp
===================================================================
--- scummvm/trunk/engines/saga/music.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/music.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -27,7 +27,7 @@
#include "saga/saga.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/music.h"
#include "sound/audiostream.h"
Added: scummvm/trunk/engines/saga/resource.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource.cpp (rev 0)
+++ scummvm/trunk/engines/saga/resource.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -0,0 +1,521 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// RSC Resource file management module
+
+#include "saga/saga.h"
+
+#include "saga/actor.h"
+#include "saga/animation.h"
+#include "saga/interface.h"
+#include "saga/music.h"
+#include "saga/resource.h"
+#include "saga/scene.h"
+#include "saga/sndres.h"
+
+#include "common/advancedDetector.h"
+
+namespace Saga {
+
+Resource::Resource(SagaEngine *vm): _vm(vm) {
+ _contexts = NULL;
+ _contextsCount = 0;
+}
+
+Resource::~Resource() {
+ clearContexts();
+}
+
+bool Resource::loadResContext_v1(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
+ size_t i;
+ bool result;
+ byte tableInfo[RSC_TABLEINFO_SIZE];
+ byte *tableBuffer;
+ size_t tableSize;
+ uint32 resourceTableOffset;
+ ResourceData *resourceData;
+
+ if (contextSize < RSC_MIN_FILESIZE) {
+ return false;
+ }
+
+ context->file->seek(contextOffset + contextSize - RSC_TABLEINFO_SIZE);
+
+ if (context->file->read(tableInfo, RSC_TABLEINFO_SIZE) != RSC_TABLEINFO_SIZE) {
+ return false;
+ }
+
+ MemoryReadStreamEndian readS(tableInfo, RSC_TABLEINFO_SIZE, context->isBigEndian);
+
+ resourceTableOffset = readS.readUint32();
+ context->count = readS.readUint32();
+
+ // Check for sane table offset
+ if (resourceTableOffset != contextSize - RSC_TABLEINFO_SIZE - RSC_TABLEENTRY_SIZE * context->count) {
+ return false;
+ }
+
+ // Load resource table
+ tableSize = RSC_TABLEENTRY_SIZE * context->count;
+
+ tableBuffer = (byte *)malloc(tableSize);
+
+ context->file->seek(resourceTableOffset + contextOffset, SEEK_SET);
+
+ result = (context->file->read(tableBuffer, tableSize) == tableSize);
+ if (result) {
+ context->table = (ResourceData *)calloc(context->count, sizeof(*context->table));
+
+ MemoryReadStreamEndian readS1(tableBuffer, tableSize, context->isBigEndian);
+
+ for (i = 0; i < context->count; i++) {
+ resourceData = &context->table[i];
+ resourceData->offset = contextOffset + readS1.readUint32();
+ resourceData->size = readS1.readUint32();
+ //sanity check
+ if ((resourceData->offset > (uint)context->file->size()) || (resourceData->size > contextSize)) {
+ result = false;
+ break;
+ }
+ }
+ }
+
+ free(tableBuffer);
+ return result;
+}
+
+bool Resource::loadContext(ResourceContext *context) {
+ size_t i;
+ const GamePatchDescription *patchDescription;
+ ResourceData *resourceData;
+ uint16 subjectResourceType;
+ ResourceContext *subjectContext;
+ uint32 subjectResourceId;
+ uint32 patchResourceId;
+ ResourceData *subjectResourceData;
+ byte *tableBuffer;
+ size_t tableSize;
+ bool isMacBinary;
+
+ if (!context->file->open(context->fileName)) {
+ return false;
+ }
+
+ context->isBigEndian = _vm->isBigEndian();
+
+ if (context->fileType & GAME_SWAPENDIAN)
+ context->isBigEndian = !context->isBigEndian;
+
+ isMacBinary = (context->fileType & GAME_MACBINARY) > 0;
+ context->fileType &= ~GAME_MACBINARY;
+
+ if (!isMacBinary) {
+ if (!loadResContext(context, 0, context->file->size())) {
+ return false;
+ }
+ } else {
+ if (!loadMacContext(context)) {
+ return false;
+ }
+ }
+
+ //process internal patch files
+ if (context->fileType & GAME_PATCHFILE) {
+ subjectResourceType = ~GAME_PATCHFILE & context->fileType;
+ subjectContext = getContext((GameFileTypes)subjectResourceType);
+ if (subjectContext == NULL) {
+ error("Resource::loadContext() Subject context not found");
+ }
+ loadResource(context, context->count - 1, tableBuffer, tableSize);
+
+ MemoryReadStreamEndian readS2(tableBuffer, tableSize, context->isBigEndian);
+ for (i = 0; i < tableSize / 8; i++) {
+ subjectResourceId = readS2.readUint32();
+ patchResourceId = readS2.readUint32();
+ subjectResourceData = subjectContext->getResourceData(subjectResourceId);
+ resourceData = context->getResourceData(patchResourceId);
+ subjectResourceData->patchData = new PatchData(context->file);
+ subjectResourceData->offset = resourceData->offset;
+ subjectResourceData->size = resourceData->size;
+ }
+ free(tableBuffer);
+ }
+
+ //process external patch files
+ for (patchDescription = _vm->getPatchDescriptions(); patchDescription && patchDescription->fileName; ++patchDescription) {
+ if ((patchDescription->fileType & context->fileType) != 0) {
+ if (patchDescription->resourceId < context->count) {
+ resourceData = &context->table[patchDescription->resourceId];
+ resourceData->patchData = new PatchData(patchDescription);
+ if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) {
+ resourceData->offset = 0;
+ resourceData->size = resourceData->patchData->_patchFile->size();
+ // ITE uses several patch files which are loaded and then not needed
+ // anymore (as they're in memory), so close them here. IHNM uses only
+ // 1 patch file, which is reused, so don't close it
+ if (_vm->getGameId() == GID_ITE)
+ resourceData->patchData->_patchFile->close();
+ } else {
+ delete resourceData->patchData;
+ resourceData->patchData = NULL;
+ }
+ }
+ }
+ }
+
+ // Close the file if it's part of a series of files
+ // This prevents having all voice files open in IHNM for no reason, as each chapter uses
+ // a different voice file
+ if (context->serial > 0)
+ context->file->close();
+
+ return true;
+}
+
+bool Resource::createContexts() {
+ int i;
+ ResourceContext *context;
+ char musicFileName[256];
+ char soundFileName[256];
+ int soundFileIndex = 0;
+ int voicesFileIndex = 0;
+ bool digitalMusic = false;
+ bool soundFileInArray = false;
+ bool multipleVoices = false;
+ bool censoredVersion = false;
+ uint16 voiceFileType = GAME_VOICEFILE;
+ bool fileFound = false;
+ int maxFile = 0;
+
+ _vm->_voiceFilesExist = true;
+
+ struct SoundFileInfo {
+ char fileName[40];
+ bool isCompressed;
+ };
+
+ SoundFileInfo *curSoundfiles;
+
+ // If the Wyrmkeep credits file is found, set the Wyrmkeep version flag to true
+ if (Common::File::exists("graphics/credit3n.dlt")) {
+ _vm->_gf_wyrmkeep = true;
+ }
+
+ _contextsCount = 0;
+ for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) {
+ _contextsCount++;
+ if (_vm->getFilesDescriptions()[i].fileType == GAME_SOUNDFILE)
+ soundFileInArray = true;
+ }
+
+ //// Detect and add SFX files ////////////////////////////////////////////////
+ SoundFileInfo sfxFilesITE[] = {
+ { "sounds.rsc", false },
+ { "sounds.cmp", true },
+ { "soundsd.rsc", false },
+ { "soundsd.cmp", true }
+ };
+
+ SoundFileInfo sfxFilesIHNM[] = {
+ { "sfx.res", false },
+ { "sfx.cmp", true }
+ };
+
+ SoundFileInfo sfxFilesFTA2[] = {
+ { "ftasound.hrs", false }
+ };
+
+ if (!soundFileInArray) {
+ // If the sound file is not specified in the detector table, add it here
+ fileFound = false;
+
+ switch (_vm->getGameId()) {
+ case GID_ITE:
+ curSoundfiles = sfxFilesITE;
+ maxFile = 4;
+ break;
+ case GID_IHNM:
+ curSoundfiles = sfxFilesIHNM;
+ maxFile = 2;
+ break;
+ case GID_DINO:
+ // TODO
+ curSoundfiles = NULL;
+ maxFile = 0;
+ break;
+ case GID_FTA2:
+ curSoundfiles = sfxFilesFTA2;
+ maxFile = 1;
+ break;
+ }
+
+ for (i = 0; i < maxFile; i++) {
+ if (Common::File::exists(curSoundfiles[i].fileName)) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ strcpy(soundFileName, curSoundfiles[i].fileName);
+ _vm->_gf_compressed_sounds = curSoundfiles[i].isCompressed;
+ fileFound = true;
+ break;
+ }
+ }
+
+ if (!fileFound) {
+ // No sound file found, don't add any file to the array
+ soundFileInArray = true;
+ if (_vm->getGameId() == GID_ITE) {
+ // ITE floppy versions have both voices and sounds in voices.rsc
+ voiceFileType = GAME_SOUNDFILE | GAME_VOICEFILE;
+ }
+ }
+ }
+
+ //// Detect and add voice files /////////////////////////////////////////////
+ SoundFileInfo voiceFilesITE[] = {
+ { "voices.rsc", false },
+ { "voices.cmp", true },
+ { "voicesd.rsc", false },
+ { "voicesd.cmp", true },
+ { "inherit the earth voices", false },
+ { "inherit the earth voices.cmp", true },
+ { "ite voices.bin", false }
+ };
+
+ SoundFileInfo voiceFilesIHNM[] = {
+ { "voicess.res", false },
+ { "voicess.cmp", true },
+ { "voicesd.res", false },
+ { "voicesd.cmp", true },
+ };
+
+ SoundFileInfo voiceFilesFTA2[] = {
+ { "ftavoice.hrs", false },
+ };
+
+ // Detect and add voice files
+ fileFound = false;
+
+ switch (_vm->getGameId()) {
+ case GID_ITE:
+ curSoundfiles = voiceFilesITE;
+ maxFile = 7;
+ break;
+ case GID_IHNM:
+ curSoundfiles = voiceFilesIHNM;
+ maxFile = 4;
+ break;
+ case GID_DINO:
+ // TODO
+ curSoundfiles = NULL;
+ maxFile = 0;
+ break;
+ case GID_FTA2:
+ curSoundfiles = voiceFilesFTA2;
+ maxFile = 1;
+ break;
+ }
+
+ for (i = 0; i < maxFile; i++) {
+ if (Common::File::exists(curSoundfiles[i].fileName)) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ strcpy(_voicesFileName[0], curSoundfiles[i].fileName);
+ _vm->_gf_compressed_sounds = curSoundfiles[i].isCompressed;
+ fileFound = true;
+
+ // Special cases
+ if (!scumm_stricmp(curSoundfiles[i].fileName, "inherit the earth voices") ||
+ !scumm_stricmp(curSoundfiles[i].fileName, "inherit the earth voices.cmp")) {
+ // The resources in the Wyrmkeep combined Windows/Mac/Linux CD version are little endian, but
+ // the voice file is big endian. If we got such a version with mixed files, mark this voice file
+ // as big endian
+ if (!_vm->isBigEndian())
+ voiceFileType = GAME_VOICEFILE | GAME_SWAPENDIAN; // This file is big endian
+ }
+
+ if (!scumm_stricmp(curSoundfiles[i].fileName, "ite voices.bin")) {
+ voiceFileType = GAME_VOICEFILE | GAME_MACBINARY;
+ }
+
+ if (!scumm_stricmp(curSoundfiles[i].fileName, "voicess.res") ||
+ !scumm_stricmp(curSoundfiles[i].fileName, "voicess.cmp")) {
+ // IHNM has multiple voice files
+ multipleVoices = true;
+ // Note: it is assumed that the voice files are always last in the list
+ if (Common::File::exists("voices4.res") || Common::File::exists("voices4.cmp")) {
+ _contextsCount += 6; // voices1-voices6
+ } else {
+ // The German and French versions of IHNM don't have Nimdok's chapter,
+ // therefore the voices file for that chapter is missing
+ _contextsCount += 5; // voices1-voices3, voices4-voices5
+ censoredVersion = true;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (!fileFound) {
+ if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
+ // The Macintosh version of IHNM has no voices.res, and it has all
+ // its voice files in subdirectories, so don't do anything here
+ } else {
+ warning("No voice file found, voices will be disabled");
+ _vm->_voicesEnabled = false;
+ _vm->_subtitlesEnabled = true;
+ _vm->_voiceFilesExist = false;
+ }
+ }
+
+ //// Detect and add ITE music files /////////////////////////////////////////
+ // We don't set the compressed flag here
+ SoundFileInfo musicFilesITE[] = {
+ { "music.rsc", true },
+ { "music.cmp", true },
+ { "musicd.rsc", true },
+ { "musicd.cmp", true },
+ };
+
+ // Check for digital music in ITE
+ if (_vm->getGameId() == GID_ITE) {
+ fileFound = false;
+
+ for (i = 0; i < 4; i++) {
+ if (Common::File::exists(musicFilesITE[i].fileName)) {
+ _contextsCount++;
+ digitalMusic = true;
+ fileFound = true;
+ strcpy(musicFileName, musicFilesITE[i].fileName);
+ break;
+ }
+ }
+
+ if (!fileFound) {
+ // No sound file found, don't add any file to the array
+ digitalMusic = false;
+ }
+ }
+
+ _contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts));
+
+ for (i = 0; i < _contextsCount; i++) {
+ context = &_contexts[i];
+ context->file = new Common::File();
+ context->serial = 0;
+
+ // For ITE, add the digital music file and sfx file information here
+ if (_vm->getGameId() == GID_ITE && digitalMusic && i == _contextsCount - 1) {
+ context->fileName = musicFileName;
+ context->fileType = GAME_MUSICFILE;
+ } else if (!soundFileInArray && i == soundFileIndex) {
+ context->fileName = soundFileName;
+ context->fileType = GAME_SOUNDFILE;
+ } else if (_vm->_voiceFilesExist && i == voicesFileIndex) {
+ context->fileName = _voicesFileName[0];
+ // can be GAME_VOICEFILE or GAME_SOUNDFILE | GAME_VOICEFILE or GAME_VOICEFILE | GAME_SWAPENDIAN
+ context->fileType = voiceFileType;
+ } else {
+ if (!(_vm->_voiceFilesExist && multipleVoices && (i > voicesFileIndex))) {
+ context->fileName = _vm->getFilesDescriptions()[i].fileName;
+ context->fileType = _vm->getFilesDescriptions()[i].fileType;
+ } else {
+ int token = (censoredVersion && (i - voicesFileIndex >= 4)) ? 1 : 0; // censored versions don't have voice4
+
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(_voicesFileName[i - voicesFileIndex + token], "voices%i.cmp", i - voicesFileIndex + token);
+ else
+ sprintf(_voicesFileName[i - voicesFileIndex + token], "voices%i.res", i - voicesFileIndex + token);
+
+ context->fileName = _voicesFileName[i - voicesFileIndex + token];
+ context->fileType = GAME_VOICEFILE;
+
+ // IHNM has several different voice files, so we need to allow
+ // multiple resource contexts of the same type. We tell them
+ // apart by assigning each of the duplicates a unique serial
+ // number. The default behaviour when requesting a context will
+ // be to look for serial number 0.
+ context->serial = i - voicesFileIndex + token;
+ }
+ }
+
+ if (!loadContext(context)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void Resource::clearContexts() {
+ int i;
+ size_t j;
+ ResourceContext *context;
+ if (_contexts == NULL) {
+ return;
+ }
+ for (i = 0; i < _contextsCount; i++) {
+ context = &_contexts[i];
+ delete context->file;
+ if (context->table != NULL) {
+ for (j = 0; j < context->count; j++) {
+ delete context->table[j].patchData;
+ }
+ }
+ free(context->table);
+ }
+ free(_contexts);
+ _contexts = NULL;
+}
+
+void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize) {
+ Common::File *file;
+ uint32 resourceOffset;
+ ResourceData *resourceData;
+
+ debug(8, "loadResource %d", resourceId);
+
+ resourceData = context->getResourceData(resourceId);
+
+ file = context->getFile(resourceData);
+
+ resourceOffset = resourceData->offset;
+ resourceSize = resourceData->size;
+
+ resourceBuffer = (byte*)malloc(resourceSize);
+
+ file->seek((long)resourceOffset, SEEK_SET);
+
+ if (file->read(resourceBuffer, resourceSize) != resourceSize) {
+ error("Resource::loadResource() failed to read");
+ }
+
+ // ITE uses several patch files which are loaded and then not needed
+ // anymore (as they're in memory), so close them here. IHNM uses only
+ // 1 patch file, which is reused, so don't close it
+ if (resourceData->patchData != NULL && _vm->getGameId() == GID_ITE)
+ file->close();
+}
+
+} // End of namespace Saga
Property changes on: scummvm/trunk/engines/saga/resource.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/saga/resource.h
===================================================================
--- scummvm/trunk/engines/saga/resource.h (rev 0)
+++ scummvm/trunk/engines/saga/resource.h 2008-12-22 14:13:15 UTC (rev 35484)
@@ -0,0 +1,217 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// RSC Resource file management header file
+
+#ifndef SAGA_RESOURCE_H
+#define SAGA_RESOURCE_H
+
+#include "common/file.h"
+
+namespace Saga {
+
+#define MAC_BINARY_HEADER_SIZE 128
+#define RSC_TABLEINFO_SIZE 8
+#define RSC_TABLEENTRY_SIZE 8
+
+#define RSC_MIN_FILESIZE (RSC_TABLEINFO_SIZE + RSC_TABLEENTRY_SIZE + 1)
+
+struct PatchData {
+ bool _deletePatchFile;
+ Common::File *_patchFile;
+ const GamePatchDescription *_patchDescription;
+
+ PatchData(const GamePatchDescription *patchDescription): _patchDescription(patchDescription), _deletePatchFile(true) {
+ _patchFile = new Common::File();
+ }
+ PatchData(Common::File *patchFile): _patchDescription(NULL), _patchFile(patchFile), _deletePatchFile(false) {
+ }
+
+ ~PatchData() {
+ if (_deletePatchFile) {
+ delete _patchFile;
+ }
+ }
+};
+
+struct ResourceData {
+ size_t offset;
+ size_t size;
+ PatchData *patchData;
+ void fillSoundPatch(const GameSoundInfo *&soundInfo) {
+ if (patchData != NULL) {
+ if (patchData->_patchDescription != NULL) {
+ if (patchData->_patchDescription->soundInfo != NULL) {
+ soundInfo = patchData->_patchDescription->soundInfo;
+ }
+ }
+ }
+ }
+};
+
+struct ResourceContext {
+ const char *fileName;
+ uint16 fileType;
+ Common::File *file;
+ int serial;
+
+ bool isBigEndian;
+ ResourceData *table;
+ size_t count;
+
+ Common::File *getFile(ResourceData *resourceData) const {
+ if (resourceData->patchData != NULL) {
+ if (!resourceData->patchData->_patchFile->isOpen())
+ resourceData->patchData->_patchFile->open(resourceData->patchData->_patchDescription->fileName);
+ return resourceData->patchData->_patchFile;
+ } else {
+ return file;
+ }
+ }
+
+ bool validResourceId(uint32 resourceId) const {
+ return (resourceId < count);
+ }
+
+ ResourceData *getResourceData(uint32 resourceId) const {
+ if (resourceId >= count) {
+ error("ResourceContext::getResourceData() wrong resourceId %d", resourceId);
+ }
+ return &table[resourceId];
+ }
+
+};
+
+struct MetaResource {
+ int16 sceneIndex;
+ int16 objectCount;
+ int32 objectsStringsResourceID;
+ int32 inventorySpritesID;
+ int32 mainSpritesID;
+ int32 objectsResourceID;
+ int16 actorCount;
+ int32 actorsStringsResourceID;
+ int32 actorsResourceID;
+ int32 protagFaceSpritesID;
+ int32 field_22;
+ int16 field_26;
+ int16 protagStatesCount;
+ int32 protagStatesResourceID;
+ int32 cutawayListResourceID;
+ int32 songTableID;
+
+ MetaResource() {
+ memset(this, 0, sizeof(*this));
+ }
+};
+
+class Resource {
+public:
+ Resource(SagaEngine *vm);
+ ~Resource();
+ bool createContexts();
+ void clearContexts();
+ void loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize);
+
+ virtual uint32 convertResourceId(uint32 resourceId) = 0;
+ virtual void loadGlobalResources(int chapter, int actorsEntrance) = 0;
+
+ ResourceContext *getContext(uint16 fileType, int serial = 0) {
+ int i;
+ for (i = 0; i < _contextsCount; i++) {
+ if ((_contexts[i].fileType & fileType) && _contexts[i].serial == serial) {
+ return &_contexts[i];
+ }
+ }
+ return NULL;
+ }
+
+protected:
+ SagaEngine *_vm;
+ ResourceContext *_contexts;
+ int _contextsCount;
+ char _voicesFileName[8][256];
+
+ bool loadContext(ResourceContext *context);
+ virtual bool loadMacContext(ResourceContext *context) = 0;
+ virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) = 0;
+ bool loadResContext_v1(ResourceContext *context, uint32 contextOffset, uint32 contextSize);
+public:
+ virtual MetaResource* getMetaResource() = 0;
+};
+
+// ITE
+class Resource_RSC : public Resource {
+public:
+ Resource_RSC(SagaEngine *vm) : Resource(vm) {}
+ virtual uint32 convertResourceId(uint32 resourceId);
+ virtual void loadGlobalResources(int chapter, int actorsEntrance) {}
+ virtual MetaResource* getMetaResource() {
+ MetaResource *dummy = 0;
+ return dummy;
+ }
+private:
+ virtual bool loadMacContext(ResourceContext *context);
+ virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
+ return loadResContext_v1(context, contextOffset, contextSize);
+ }
+};
+
+// IHNM
+class Resource_RES : public Resource {
+public:
+ Resource_RES(SagaEngine *vm) : Resource(vm) {}
+ virtual uint32 convertResourceId(uint32 resourceId) { return resourceId; }
+ virtual void loadGlobalResources(int chapter, int actorsEntrance);
+ virtual MetaResource* getMetaResource() { return &_metaResource; };
+private:
+ virtual bool loadMacContext(ResourceContext *context) { return false; }
+ virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
+ return loadResContext_v1(context, contextOffset, contextSize);
+ }
+ MetaResource _metaResource;
+};
+
+// DINO, FTA2
+class Resource_HRS : public Resource {
+public:
+ Resource_HRS(SagaEngine *vm) : Resource(vm) {}
+ virtual uint32 convertResourceId(uint32 resourceId) { return resourceId; }
+ virtual void loadGlobalResources(int chapter, int actorsEntrance) {}
+ virtual MetaResource* getMetaResource() {
+ MetaResource *dummy = 0;
+ return dummy;
+ }
+private:
+ virtual bool loadMacContext(ResourceContext *context) { return false; }
+ virtual bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
+ return loadResContext_v2(context, contextOffset, contextSize);
+ }
+ bool loadResContext_v2(ResourceContext *context, uint32 contextOffset, uint32 contextSize);
+};
+
+} // End of namespace Saga
+
+#endif
Property changes on: scummvm/trunk/engines/saga/resource.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/saga/resource_hrs.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource_hrs.cpp (rev 0)
+++ scummvm/trunk/engines/saga/resource_hrs.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// HRS Resource file management module (SAGA 2, used in DINO and FTA2)
+
+#include "saga/saga.h"
+
+#include "saga/actor.h"
+#include "saga/animation.h"
+#include "saga/interface.h"
+#include "saga/music.h"
+#include "saga/resource.h"
+#include "saga/scene.h"
+#include "saga/sndres.h"
+
+#include "common/advancedDetector.h"
+
+namespace Saga {
+
+bool Resource_HRS::loadResContext_v2(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
+ // STUB
+ return true;
+}
+
+} // End of namespace Saga
Property changes on: scummvm/trunk/engines/saga/resource_hrs.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/saga/resource_res.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource_res.cpp (rev 0)
+++ scummvm/trunk/engines/saga/resource_res.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -0,0 +1,217 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// RSC Resource file management module (SAGA 1, used in IHNM)
+
+#include "saga/saga.h"
+
+#include "saga/actor.h"
+#include "saga/animation.h"
+#include "saga/interface.h"
+#include "saga/music.h"
+#include "saga/resource.h"
+#include "saga/scene.h"
+#include "saga/sndres.h"
+
+#include "common/advancedDetector.h"
+
+namespace Saga {
+
+static int metaResourceTable[] = { 0, 326, 517, 677, 805, 968, 1165, 0, 1271 };
+static int metaResourceTableDemo[] = { 0, 0, 0, 0, 0, 0, 0, 285, 0 };
+
+void Resource_RES::loadGlobalResources(int chapter, int actorsEntrance) {
+ if (chapter < 0)
+ chapter = (!(_vm->getFeatures() & GF_IHNM_DEMO)) ? 8 : 7;
+
+ _vm->_script->_globalVoiceLUT.freeMem();
+
+ // TODO: close chapter context, or rather reassign it in our case
+
+ ResourceContext *resourceContext;
+ ResourceContext *soundContext;
+ int i;
+
+ resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE);
+ if (resourceContext == NULL) {
+ error("Resource::loadGlobalResources() resource context not found");
+ }
+
+ soundContext = _vm->_resource->getContext(GAME_SOUNDFILE);
+ if (soundContext == NULL) {
+ error("Resource::loadGlobalResources() sound context not found");
+ }
+
+ byte *resourcePointer;
+ size_t resourceLength;
+
+ if (!(_vm->getFeatures() & GF_IHNM_DEMO)) {
+ _vm->_resource->loadResource(resourceContext, metaResourceTable[chapter],
+ resourcePointer, resourceLength);
+ } else {
+ _vm->_resource->loadResource(resourceContext, metaResourceTableDemo[chapter],
+ resourcePointer, resourceLength);
+ }
+
+ if (resourceLength == 0) {
+ error("Resource::loadGlobalResources wrong metaResource");
+ }
+
+ MemoryReadStream metaS(resourcePointer, resourceLength);
+
+ _metaResource.sceneIndex = metaS.readSint16LE();
+ _metaResource.objectCount = metaS.readSint16LE();
+ _metaResource.objectsStringsResourceID = metaS.readSint32LE();
+ _metaResource.inventorySpritesID = metaS.readSint32LE();
+ _metaResource.mainSpritesID = metaS.readSint32LE();
+ _metaResource.objectsResourceID = metaS.readSint32LE();
+ _metaResource.actorCount = metaS.readSint16LE();
+ _metaResource.actorsStringsResourceID = metaS.readSint32LE();
+ _metaResource.actorsResourceID = metaS.readSint32LE();
+ _metaResource.protagFaceSpritesID = metaS.readSint32LE();
+ _metaResource.field_22 = metaS.readSint32LE();
+ _metaResource.field_26 = metaS.readSint16LE();
+ _metaResource.protagStatesCount = metaS.readSint16LE();
+ _metaResource.protagStatesResourceID = metaS.readSint32LE();
+ _metaResource.cutawayListResourceID = metaS.readSint32LE();
+ _metaResource.songTableID = metaS.readSint32LE();
+
+ free(resourcePointer);
+
+ _vm->_actor->loadActorList(actorsEntrance, _metaResource.actorCount,
+ _metaResource.actorsResourceID, _metaResource.protagStatesCount,
+ _metaResource.protagStatesResourceID);
+
+ _vm->_actor->_protagonist->_sceneNumber = _metaResource.sceneIndex;
+
+ _vm->_actor->_objectsStrings.freeMem();
+
+ _vm->_resource->loadResource(resourceContext, _metaResource.objectsStringsResourceID, resourcePointer, resourceLength);
+ _vm->loadStrings(_vm->_actor->_objectsStrings, resourcePointer, resourceLength);
+ free(resourcePointer);
+
+ if (chapter >= _vm->_sndRes->_fxTableIDsLen) {
+ error("Chapter ID exceeds fxTableIDs length");
+ }
+
+ debug(0, "Going to read %d of %d", chapter, _vm->_sndRes->_fxTableIDs[chapter]);
+ _vm->_resource->loadResource(soundContext, _vm->_sndRes->_fxTableIDs[chapter],
+ resourcePointer, resourceLength);
+
+ if (resourceLength == 0) {
+ error("Resource::loadGlobalResources Can't load sound effects for current track");
+ }
+
+ free(_vm->_sndRes->_fxTable);
+
+ _vm->_sndRes->_fxTableLen = resourceLength / 4;
+ _vm->_sndRes->_fxTable = (FxTable *)malloc(sizeof(FxTable) * _vm->_sndRes->_fxTableLen);
+
+ MemoryReadStream fxS(resourcePointer, resourceLength);
+
+ for (i = 0; i < _vm->_sndRes->_fxTableLen; i++) {
+ _vm->_sndRes->_fxTable[i].res = fxS.readSint16LE();
+ _vm->_sndRes->_fxTable[i].vol = fxS.readSint16LE();
+ }
+ free(resourcePointer);
+
+ _vm->_interface->_defPortraits.freeMem();
+ _vm->_sprite->loadList(_metaResource.protagFaceSpritesID, _vm->_interface->_defPortraits);
+
+ _vm->_actor->_actorsStrings.freeMem();
+
+ _vm->_resource->loadResource(resourceContext, _metaResource.actorsStringsResourceID, resourcePointer, resourceLength);
+ _vm->loadStrings(_vm->_actor->_actorsStrings, resourcePointer, resourceLength);
+ free(resourcePointer);
+
+ _vm->_sprite->_inventorySprites.freeMem();
+ _vm->_sprite->loadList(_metaResource.inventorySpritesID, _vm->_sprite->_inventorySprites);
+
+ _vm->_sprite->_mainSprites.freeMem();
+ _vm->_sprite->loadList(_metaResource.mainSpritesID, _vm->_sprite->_mainSprites);
+
+ _vm->_actor->loadObjList(_metaResource.objectCount, _metaResource.objectsResourceID);
+
+ _vm->_resource->loadResource(resourceContext, _metaResource.cutawayListResourceID, resourcePointer, resourceLength);
+
+ if (resourceLength == 0) {
+ error("Resource::loadGlobalResources Can't load cutaway list");
+ }
+
+ _vm->_anim->loadCutawayList(resourcePointer, resourceLength);
+
+ if (_metaResource.songTableID > 0) {
+ _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength);
+
+ if (chapter == 6) {
+ int32 id = READ_LE_UINT32(&resourcePointer[actorsEntrance * 4]);
+ free(resourcePointer);
+ _vm->_resource->loadResource(resourceContext, id, resourcePointer, resourceLength);
+ }
+
+ if (resourceLength == 0) {
+ error("Resource::loadGlobalResources Can't load songs list for current track");
+ }
+
+ free(_vm->_music->_songTable);
+
+ _vm->_music->_songTableLen = resourceLength / 4;
+ _vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen);
+
+ MemoryReadStream songS(resourcePointer, resourceLength);
+
+ for (i = 0; i < _vm->_music->_songTableLen; i++)
+ _vm->_music->_songTable[i] = songS.readSint32LE();
+ free(resourcePointer);
+ } else {
+ // The IHNM demo has a fixed music track and doesn't load a song table
+ _vm->_music->setVolume(_vm->_musicVolume, 1);
+ _vm->_music->play(3, MUSIC_LOOP);
+ free(resourcePointer);
+ }
+
+ int voiceLUTResourceID = 0;
+
+ if (chapter != 7) {
+ int voiceBank = (chapter == 8) ? 0 : chapter;
+ _vm->_sndRes->setVoiceBank(voiceBank);
+ voiceLUTResourceID = 22 + voiceBank;
+ } else {
+ // IHNM demo
+ _vm->_sndRes->setVoiceBank(0);
+ voiceLUTResourceID = 17;
+ }
+
+ if (voiceLUTResourceID) {
+ _vm->_resource->loadResource(resourceContext, voiceLUTResourceID, resourcePointer, resourceLength);
+ _vm->_script->loadVoiceLUT(_vm->_script->_globalVoiceLUT, resourcePointer, resourceLength);
+ free(resourcePointer);
+ }
+
+ _vm->_spiritualBarometer = 0;
+ _vm->_scene->setChapterNumber(chapter);
+}
+
+} // End of namespace Saga
Property changes on: scummvm/trunk/engines/saga/resource_res.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/saga/resource_rsc.cpp
===================================================================
--- scummvm/trunk/engines/saga/resource_rsc.cpp (rev 0)
+++ scummvm/trunk/engines/saga/resource_rsc.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -0,0 +1,212 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// RSC Resource file management module (SAGA 1, used in ITE)
+
+#include "saga/saga.h"
+
+#include "saga/actor.h"
+#include "saga/animation.h"
+#include "saga/interface.h"
+#include "saga/music.h"
+#include "saga/resource.h"
+#include "saga/scene.h"
+#include "saga/sndres.h"
+
+#include "common/advancedDetector.h"
+
+namespace Saga {
+
+struct MacResMap {
+ int16 resAttr;
+ int16 typeOffset;
+ int16 nameOffset;
+ int16 numTypes;
+};
+
+struct MacResource {
+ int16 id;
+ int16 nameOffset;
+ byte attr;
+ int32 dataOffset;
+ byte name[255];
+};
+
+struct MacResType {
+ uint32 id;
+ int16 items;
+ int16 maxItemId;
+ int16 offset;
+ MacResource *resources;
+};
+
+#define ID_MIDI MKID_BE('Midi')
+
+uint32 Resource_RSC::convertResourceId(uint32 resourceId) {
+
+ if (_vm->isMacResources()) {
+ if (resourceId > 1537) {
+ return resourceId - 2;
+ } else {
+ if (resourceId == 1535 || resourceId == 1536) {
+ error("Wrong resource number %d for Mac ITE", resourceId);
+ }
+ }
+ }
+
+ return resourceId;
+}
+
+bool Resource_RSC::loadMacContext(ResourceContext *context) {
+ int32 macDataSize, macDataSizePad;
+ int32 macResSize, macResSizePad;
+ int32 macResOffset;
+
+ uint32 macMapLength;
+ uint32 macDataLength;
+ uint32 macMapOffset;
+ uint32 macDataOffset;
+
+ MacResMap macResMap;
+ MacResType *macResTypes;
+
+ MacResType *macResType;
+ MacResource *macResource;
+ int i, j;
+ byte macNameLen;
+ bool notSagaContext = false;
+
+ if (context->file->size() < RSC_MIN_FILESIZE + MAC_BINARY_HEADER_SIZE) {
+ return false;
+ }
+
+ if (context->file->readByte() != 0) {
+ return false;
+ }
+ context->file->readByte(); //MAX Name Len
+ context->file->seek(74);
+ if (context->file->readByte() != 0) {
+ return false;
+ }
+ context->file->seek(82);
+ if (context->file->readByte() != 0) {
+ return false;
+ }
+
+ macDataSize = context->file->readSint32BE();
+ macResSize = context->file->readSint32BE();
+ macDataSizePad = (((macDataSize + 127) >> 7) << 7);
+ macResSizePad = (((macResSize + 127) >> 7) << 7);
+
+ macResOffset = MAC_BINARY_HEADER_SIZE + macDataSizePad;
+ context->file->seek(macResOffset);
+
+ macDataOffset = context->file->readUint32BE() + macResOffset;
+ macMapOffset = context->file->readUint32BE() + macResOffset;
+ macDataLength = context->file->readUint32BE();
+ macMapLength = context->file->readUint32BE();
+
+ if (macDataOffset >= (uint)context->file->size() || macMapOffset >= (uint)context->file->size() ||
+ macDataLength + macMapLength > (uint)context->file->size()) {
+ return false;
+ }
+
+ context->file->seek(macMapOffset + 22);
+
+ macResMap.resAttr = context->file->readUint16BE();
+ macResMap.typeOffset = context->file->readUint16BE();
+ macResMap.nameOffset = context->file->readUint16BE();
+ macResMap.numTypes = context->file->readUint16BE();
+ macResMap.numTypes++;
+
+ context->file->seek(macMapOffset + macResMap.typeOffset + 2);
+
+ macResTypes = (MacResType *)calloc(macResMap.numTypes, sizeof(*macResTypes));
+
+ for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
+ macResType->id = context->file->readUint32BE();
+ macResType->items = context->file->readUint16BE();
+ macResType->offset = context->file->readUint16BE();
+ macResType->items++;
+ macResType->resources = (MacResource*)calloc(macResType->items, sizeof(*macResType->resources));
+ }
+
+ for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
+ context->file->seek(macResType->offset + macMapOffset + macResMap.typeOffset);
+
+ for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
+ macResource->id = context->file->readUint16BE();
+ macResource->nameOffset = context->file->readUint16BE();
+ macResource->dataOffset = context->file->readUint32BE();
+ macResSize = context->file->readUint32BE();
+
+ macResource->attr = macResource->dataOffset >> 24;
+ macResource->dataOffset &= 0xFFFFFF;
+ if (macResource->id > macResType->maxItemId) {
+ macResType->maxItemId = macResource->id;
+ }
+ }
+
+ for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
+ if (macResource->nameOffset != -1) {
+ context->file->seek(macResource->nameOffset + macMapOffset + macResMap.nameOffset);
+ macNameLen = context->file->readByte();
+ context->file->read(macResource->name, macNameLen);
+ }
+ }
+ }
+
+//
+ for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
+ //getting offsets & sizes of midi
+ if (((context->fileType & GAME_MUSICFILE_GM) > 0) && (macResType->id == ID_MIDI)) {
+
+ context->count = macResType->maxItemId + 1;
+ context->table = (ResourceData *)calloc(context->count, sizeof(*context->table));
+ for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
+ context->file->seek(macDataOffset + macResource->dataOffset);
+ context->table[macResource->id].size = context->file->readUint32BE();
+ context->table[macResource->id].offset = context->file->pos();
+ }
+ notSagaContext = true;
+ break;
+ }
+ }
+
+//free
+ for (i = 0; i < macResMap.numTypes; i++) {
+ free(macResTypes[i].resources);
+ }
+ free(macResTypes);
+
+ if ((!notSagaContext) && (!loadResContext(context, MAC_BINARY_HEADER_SIZE, macDataSize))) {
+ return false;
+ }
+
+ return true;
+}
+
+
+} // End of namespace Saga
Property changes on: scummvm/trunk/engines/saga/resource_rsc.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Deleted: scummvm/trunk/engines/saga/rscfile.cpp
===================================================================
--- scummvm/trunk/engines/saga/rscfile.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/rscfile.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -1,836 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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$
- *
- */
-
-// RSC Resource file management module
-
-#include "saga/saga.h"
-
-#include "saga/actor.h"
-#include "saga/animation.h"
-#include "saga/interface.h"
-#include "saga/music.h"
-#include "saga/rscfile.h"
-#include "saga/scene.h"
-#include "saga/sndres.h"
-
-#include "common/advancedDetector.h"
-
-namespace Saga {
-
-struct MacResMap {
- int16 resAttr;
- int16 typeOffset;
- int16 nameOffset;
- int16 numTypes;
-};
-
-struct MacResource {
- int16 id;
- int16 nameOffset;
- byte attr;
- int32 dataOffset;
- byte name[255];
-};
-
-struct MacResType {
- uint32 id;
- int16 items;
- int16 maxItemId;
- int16 offset;
- MacResource *resources;
-};
-
-
-#define ID_MIDI MKID_BE('Midi')
-
-Resource::Resource(SagaEngine *vm): _vm(vm) {
- _contexts = NULL;
- _contextsCount = 0;
-}
-
-Resource::~Resource() {
- clearContexts();
-}
-
-bool Resource::loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) {
- size_t i;
- bool result;
- byte tableInfo[RSC_TABLEINFO_SIZE];
- byte *tableBuffer;
- size_t tableSize;
- uint32 resourceTableOffset;
- ResourceData *resourceData;
-
- if (contextSize < RSC_MIN_FILESIZE) {
- return false;
- }
-
- context->file->seek(contextOffset + contextSize - RSC_TABLEINFO_SIZE);
-
- if (context->file->read(tableInfo, RSC_TABLEINFO_SIZE) != RSC_TABLEINFO_SIZE) {
- return false;
- }
-
- MemoryReadStreamEndian readS(tableInfo, RSC_TABLEINFO_SIZE, context->isBigEndian);
-
- resourceTableOffset = readS.readUint32();
- context->count = readS.readUint32();
-
- // Check for sane table offset
- if (resourceTableOffset != contextSize - RSC_TABLEINFO_SIZE - RSC_TABLEENTRY_SIZE * context->count) {
- return false;
- }
-
- // Load resource table
- tableSize = RSC_TABLEENTRY_SIZE * context->count;
-
- tableBuffer = (byte *)malloc(tableSize);
-
- context->file->seek(resourceTableOffset + contextOffset, SEEK_SET);
-
- result = (context->file->read(tableBuffer, tableSize) == tableSize);
- if (result) {
- context->table = (ResourceData *)calloc(context->count, sizeof(*context->table));
-
- MemoryReadStreamEndian readS1(tableBuffer, tableSize, context->isBigEndian);
-
- for (i = 0; i < context->count; i++) {
- resourceData = &context->table[i];
- resourceData->offset = contextOffset + readS1.readUint32();
- resourceData->size = readS1.readUint32();
- //sanity check
- if ((resourceData->offset > (uint)context->file->size()) || (resourceData->size > contextSize)) {
- result = false;
- break;
- }
- }
- }
-
- free(tableBuffer);
- return result;
-}
-
-bool Resource::loadMacContext(ResourceContext *context) {
- int32 macDataSize, macDataSizePad;
- int32 macResSize, macResSizePad;
- int32 macResOffset;
-
- uint32 macMapLength;
- uint32 macDataLength;
- uint32 macMapOffset;
- uint32 macDataOffset;
-
- MacResMap macResMap;
- MacResType *macResTypes;
-
- MacResType *macResType;
- MacResource *macResource;
- int i, j;
- byte macNameLen;
- bool notSagaContext = false;
-
- if (context->file->size() < RSC_MIN_FILESIZE + MAC_BINARY_HEADER_SIZE) {
- return false;
- }
-
- if (context->file->readByte() != 0) {
- return false;
- }
- context->file->readByte(); //MAX Name Len
- context->file->seek(74);
- if (context->file->readByte() != 0) {
- return false;
- }
- context->file->seek(82);
- if (context->file->readByte() != 0) {
- return false;
- }
-
- macDataSize = context->file->readSint32BE();
- macResSize = context->file->readSint32BE();
- macDataSizePad = (((macDataSize + 127) >> 7) << 7);
- macResSizePad = (((macResSize + 127) >> 7) << 7);
-
- macResOffset = MAC_BINARY_HEADER_SIZE + macDataSizePad;
- context->file->seek(macResOffset);
-
- macDataOffset = context->file->readUint32BE() + macResOffset;
- macMapOffset = context->file->readUint32BE() + macResOffset;
- macDataLength = context->file->readUint32BE();
- macMapLength = context->file->readUint32BE();
-
- if (macDataOffset >= (uint)context->file->size() || macMapOffset >= (uint)context->file->size() ||
- macDataLength + macMapLength > (uint)context->file->size()) {
- return false;
- }
-
- context->file->seek(macMapOffset + 22);
-
- macResMap.resAttr = context->file->readUint16BE();
- macResMap.typeOffset = context->file->readUint16BE();
- macResMap.nameOffset = context->file->readUint16BE();
- macResMap.numTypes = context->file->readUint16BE();
- macResMap.numTypes++;
-
- context->file->seek(macMapOffset + macResMap.typeOffset + 2);
-
- macResTypes = (MacResType *)calloc(macResMap.numTypes, sizeof(*macResTypes));
-
- for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
- macResType->id = context->file->readUint32BE();
- macResType->items = context->file->readUint16BE();
- macResType->offset = context->file->readUint16BE();
- macResType->items++;
- macResType->resources = (MacResource*)calloc(macResType->items, sizeof(*macResType->resources));
- }
-
- for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
- context->file->seek(macResType->offset + macMapOffset + macResMap.typeOffset);
-
- for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
- macResource->id = context->file->readUint16BE();
- macResource->nameOffset = context->file->readUint16BE();
- macResource->dataOffset = context->file->readUint32BE();
- macResSize = context->file->readUint32BE();
-
- macResource->attr = macResource->dataOffset >> 24;
- macResource->dataOffset &= 0xFFFFFF;
- if (macResource->id > macResType->maxItemId) {
- macResType->maxItemId = macResource->id;
- }
- }
-
- for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
- if (macResource->nameOffset != -1) {
- context->file->seek(macResource->nameOffset + macMapOffset + macResMap.nameOffset);
- macNameLen = context->file->readByte();
- context->file->read(macResource->name, macNameLen);
- }
- }
- }
-
-//
- for (i = macResMap.numTypes, macResType = macResTypes; i > 0; i--, macResType++) {
- //getting offsets & sizes of midi
- if (((context->fileType & GAME_MUSICFILE_GM) > 0) && (macResType->id == ID_MIDI)) {
-
- context->count = macResType->maxItemId + 1;
- context->table = (ResourceData *)calloc(context->count, sizeof(*context->table));
- for (j = macResType->items, macResource = macResType->resources; j > 0; j--, macResource++) {
- context->file->seek(macDataOffset + macResource->dataOffset);
- context->table[macResource->id].size = context->file->readUint32BE();
- context->table[macResource->id].offset = context->file->pos();
- }
- notSagaContext = true;
- break;
- }
- }
-
-//free
- for (i = 0; i < macResMap.numTypes; i++) {
- free(macResTypes[i].resources);
- }
- free(macResTypes);
-
- if ((!notSagaContext) && (!loadResContext(context, MAC_BINARY_HEADER_SIZE, macDataSize))) {
- return false;
- }
-
- return true;
-}
-
-bool Resource::loadHResContext(ResourceContext *context, uint32 contextSize) {
- // Stub for now
-
- return true;
-}
-
-bool Resource::loadContext(ResourceContext *context) {
- size_t i;
- const GamePatchDescription *patchDescription;
- ResourceData *resourceData;
- uint16 subjectResourceType;
- ResourceContext *subjectContext;
- uint32 subjectResourceId;
- uint32 patchResourceId;
- ResourceData *subjectResourceData;
- byte *tableBuffer;
- size_t tableSize;
- bool isMacBinary;
-
- if (!context->file->open(context->fileName)) {
- return false;
- }
-
- context->isBigEndian = _vm->isBigEndian();
-
- if (context->fileType & GAME_SWAPENDIAN)
- context->isBigEndian = !context->isBigEndian;
-
- isMacBinary = (context->fileType & GAME_MACBINARY) > 0;
- context->fileType &= ~GAME_MACBINARY;
-
- if (!isMacBinary) {
- if (!_vm->isSaga2()) {
- // ITE, IHNM
- if (!loadResContext(context, 0, context->file->size())) {
- return false;
- }
- } else {
- // DINO, FTA2
- if (!loadHResContext(context, context->file->size())) {
- return false;
- }
- }
- } else {
- if (!loadMacContext(context)) {
- return false;
- }
- }
-
- //process internal patch files
- if (context->fileType & GAME_PATCHFILE) {
- subjectResourceType = ~GAME_PATCHFILE & context->fileType;
- subjectContext = getContext((GameFileTypes)subjectResourceType);
- if (subjectContext == NULL) {
- error("Resource::loadContext() Subject context not found");
- }
- loadResource(context, context->count - 1, tableBuffer, tableSize);
-
- MemoryReadStreamEndian readS2(tableBuffer, tableSize, context->isBigEndian);
- for (i = 0; i < tableSize / 8; i++) {
- subjectResourceId = readS2.readUint32();
- patchResourceId = readS2.readUint32();
- subjectResourceData = subjectContext->getResourceData(subjectResourceId);
- resourceData = context->getResourceData(patchResourceId);
- subjectResourceData->patchData = new PatchData(context->file);
- subjectResourceData->offset = resourceData->offset;
- subjectResourceData->size = resourceData->size;
- }
- free(tableBuffer);
- }
-
- //process external patch files
- for (patchDescription = _vm->getPatchDescriptions(); patchDescription && patchDescription->fileName; ++patchDescription) {
- if ((patchDescription->fileType & context->fileType) != 0) {
- if (patchDescription->resourceId < context->count) {
- resourceData = &context->table[patchDescription->resourceId];
- resourceData->patchData = new PatchData(patchDescription);
- if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) {
- resourceData->offset = 0;
- resourceData->size = resourceData->patchData->_patchFile->size();
- // ITE uses several patch files which are loaded and then not needed
- // anymore (as they're in memory), so close them here. IHNM uses only
- // 1 patch file, which is reused, so don't close it
- if (_vm->getGameId() == GID_ITE)
- resourceData->patchData->_patchFile->close();
- } else {
- delete resourceData->patchData;
- resourceData->patchData = NULL;
- }
- }
- }
- }
-
- // Close the file if it's part of a series of files
- // This prevents having all voice files open in IHNM for no reason, as each chapter uses
- // a different voice file
- if (context->serial > 0)
- context->file->close();
-
- return true;
-}
-
-bool Resource::createContexts() {
- int i;
- ResourceContext *context;
- char musicFileName[256];
- char soundFileName[256];
- int soundFileIndex = 0;
- int voicesFileIndex = 0;
- bool digitalMusic = false;
- bool soundFileInArray = false;
- bool multipleVoices = false;
- bool censoredVersion = false;
- uint16 voiceFileType = GAME_VOICEFILE;
- bool fileFound = false;
- int maxFile = 0;
-
- _vm->_voiceFilesExist = true;
-
- struct SoundFileInfo {
- char fileName[40];
- bool isCompressed;
- };
-
- SoundFileInfo *curSoundfiles;
-
- // If the Wyrmkeep credits file is found, set the Wyrmkeep version flag to true
- if (Common::File::exists("graphics/credit3n.dlt")) {
- _vm->_gf_wyrmkeep = true;
- }
-
- _contextsCount = 0;
- for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) {
- _contextsCount++;
- if (_vm->getFilesDescriptions()[i].fileType == GAME_SOUNDFILE)
- soundFileInArray = true;
- }
-
- //// Detect and add SFX files ////////////////////////////////////////////////
- SoundFileInfo sfxFilesITE[] = {
- { "sounds.rsc", false },
- { "sounds.cmp", true },
- { "soundsd.rsc", false },
- { "soundsd.cmp", true }
- };
-
- SoundFileInfo sfxFilesIHNM[] = {
- { "sfx.res", false },
- { "sfx.cmp", true }
- };
-
- if (!soundFileInArray) {
- // If the sound file is not specified in the detector table, add it here
- fileFound = false;
- curSoundfiles = _vm->getGameId() == GID_ITE ? sfxFilesITE : sfxFilesIHNM;
- maxFile = _vm->getGameId() == GID_ITE ? 4 : 2;
-
- for (i = 0; i < maxFile; i++) {
- if (Common::File::exists(curSoundfiles[i].fileName)) {
- _contextsCount++;
- soundFileIndex = _contextsCount - 1;
- strcpy(soundFileName, curSoundfiles[i].fileName);
- _vm->_gf_compressed_sounds = curSoundfiles[i].isCompressed;
- fileFound = true;
- break;
- }
- }
-
- if (!fileFound) {
- // No sound file found, don't add any file to the array
- soundFileInArray = true;
- if (_vm->getGameId() == GID_ITE) {
- // ITE floppy versions have both voices and sounds in voices.rsc
- voiceFileType = GAME_SOUNDFILE | GAME_VOICEFILE;
- }
- }
- }
-
- //// Detect and add voice files /////////////////////////////////////////////
- SoundFileInfo voiceFilesITE[] = {
- { "voices.rsc", false },
- { "voices.cmp", true },
- { "voicesd.rsc", false },
- { "voicesd.cmp", true },
- { "inherit the earth voices", false },
- { "inherit the earth voices.cmp", true },
- { "ite voices.bin", false }
- };
-
- SoundFileInfo voiceFilesIHNM[] = {
- { "voicess.res", false },
- { "voicess.cmp", true },
- { "voicesd.res", false },
- { "voicesd.cmp", true },
- };
-
- // Detect and add voice files
- fileFound = false;
- curSoundfiles = _vm->getGameId() == GID_ITE ? voiceFilesITE : voiceFilesIHNM;
- maxFile = _vm->getGameId() == GID_ITE ? 7 : 4;
-
- for (i = 0; i < maxFile; i++) {
- if (Common::File::exists(curSoundfiles[i].fileName)) {
- _contextsCount++;
- voicesFileIndex = _contextsCount - 1;
- strcpy(_voicesFileName[0], curSoundfiles[i].fileName);
- _vm->_gf_compressed_sounds = curSoundfiles[i].isCompressed;
- fileFound = true;
-
- // Special cases
- if (!scumm_stricmp(curSoundfiles[i].fileName, "inherit the earth voices") ||
- !scumm_stricmp(curSoundfiles[i].fileName, "inherit the earth voices.cmp")) {
- // The resources in the Wyrmkeep combined Windows/Mac/Linux CD version are little endian, but
- // the voice file is big endian. If we got such a version with mixed files, mark this voice file
- // as big endian
- if (!_vm->isBigEndian())
- voiceFileType = GAME_VOICEFILE | GAME_SWAPENDIAN; // This file is big endian
- }
-
- if (!scumm_stricmp(curSoundfiles[i].fileName, "ite voices.bin")) {
- voiceFileType = GAME_VOICEFILE | GAME_MACBINARY;
- }
-
- if (!scumm_stricmp(curSoundfiles[i].fileName, "voicess.res") ||
- !scumm_stricmp(curSoundfiles[i].fileName, "voicess.cmp")) {
- // IHNM has multiple voice files
- multipleVoices = true;
- // Note: it is assumed that the voice files are always last in the list
- if (Common::File::exists("voices4.res") || Common::File::exists("voices4.cmp")) {
- _contextsCount += 6; // voices1-voices6
- } else {
- // The German and French versions of IHNM don't have Nimdok's chapter,
- // therefore the voices file for that chapter is missing
- _contextsCount += 5; // voices1-voices3, voices4-voices5
- censoredVersion = true;
- }
- }
-
- break;
- }
- }
-
- if (!fileFound) {
- if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
- // The Macintosh version of IHNM has no voices.res, and it has all
- // its voice files in subdirectories, so don't do anything here
- } else {
- warning("No voice file found, voices will be disabled");
- _vm->_voicesEnabled = false;
- _vm->_subtitlesEnabled = true;
- _vm->_voiceFilesExist = false;
- }
- }
-
- //// Detect and add ITE music files /////////////////////////////////////////
- // We don't set the compressed flag here
- SoundFileInfo musicFilesITE[] = {
- { "music.rsc", true },
- { "music.cmp", true },
- { "musicd.rsc", true },
- { "musicd.cmp", true },
- };
-
- // Check for digital music in ITE
- if (_vm->getGameId() == GID_ITE) {
- fileFound = false;
-
- for (i = 0; i < 4; i++) {
- if (Common::File::exists(musicFilesITE[i].fileName)) {
- _contextsCount++;
- digitalMusic = true;
- fileFound = true;
- strcpy(musicFileName, musicFilesITE[i].fileName);
- break;
- }
- }
-
- if (!fileFound) {
- // No sound file found, don't add any file to the array
- digitalMusic = false;
- }
- }
-
- _contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts));
-
- for (i = 0; i < _contextsCount; i++) {
- context = &_contexts[i];
- context->file = new Common::File();
- context->serial = 0;
-
- // For ITE, add the digital music file and sfx file information here
- if (_vm->getGameId() == GID_ITE && digitalMusic && i == _contextsCount - 1) {
- context->fileName = musicFileName;
- context->fileType = GAME_MUSICFILE;
- } else if (!soundFileInArray && i == soundFileIndex) {
- context->fileName = soundFileName;
- context->fileType = GAME_SOUNDFILE;
- } else if (_vm->_voiceFilesExist && i == voicesFileIndex) {
- context->fileName = _voicesFileName[0];
- // can be GAME_VOICEFILE or GAME_SOUNDFILE | GAME_VOICEFILE or GAME_VOICEFILE | GAME_SWAPENDIAN
- context->fileType = voiceFileType;
- } else {
- if (!(_vm->_voiceFilesExist && multipleVoices && (i > voicesFileIndex))) {
- context->fileName = _vm->getFilesDescriptions()[i].fileName;
- context->fileType = _vm->getFilesDescriptions()[i].fileType;
- } else {
- int token = (censoredVersion && (i - voicesFileIndex >= 4)) ? 1 : 0; // censored versions don't have voice4
-
- if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
- sprintf(_voicesFileName[i - voicesFileIndex + token], "voices%i.cmp", i - voicesFileIndex + token);
- else
- sprintf(_voicesFileName[i - voicesFileIndex + token], "voices%i.res", i - voicesFileIndex + token);
-
- context->fileName = _voicesFileName[i - voicesFileIndex + token];
- context->fileType = GAME_VOICEFILE;
-
- // IHNM has several different voice files, so we need to allow
- // multiple resource contexts of the same type. We tell them
- // apart by assigning each of the duplicates a unique serial
- // number. The default behaviour when requesting a context will
- // be to look for serial number 0.
- context->serial = i - voicesFileIndex + token;
- }
- }
-
- if (!loadContext(context)) {
- return false;
- }
- }
- return true;
-}
-
-void Resource::clearContexts() {
- int i;
- size_t j;
- ResourceContext *context;
- if (_contexts == NULL) {
- return;
- }
- for (i = 0; i < _contextsCount; i++) {
- context = &_contexts[i];
- delete context->file;
- if (context->table != NULL) {
- for (j = 0; j < context->count; j++) {
- delete context->table[j].patchData;
- }
- }
- free(context->table);
- }
- free(_contexts);
- _contexts = NULL;
-}
-
-uint32 Resource::convertResourceId(uint32 resourceId) {
-
- if (_vm->getGameId() == GID_ITE && _vm->isMacResources()) {
- if (resourceId > 1537) {
- return resourceId - 2;
- } else {
- if (resourceId == 1535 || resourceId == 1536) {
- error("Wrong resource number %d for Mac ITE", resourceId);
- }
- }
- }
-
- return resourceId;
-}
-
-void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize) {
- Common::File *file;
- uint32 resourceOffset;
- ResourceData *resourceData;
-
- debug(8, "loadResource %d", resourceId);
-
- resourceData = context->getResourceData(resourceId);
-
- file = context->getFile(resourceData);
-
- resourceOffset = resourceData->offset;
- resourceSize = resourceData->size;
-
- resourceBuffer = (byte*)malloc(resourceSize);
-
- file->seek((long)resourceOffset, SEEK_SET);
-
- if (file->read(resourceBuffer, resourceSize) != resourceSize) {
- error("Resource::loadResource() failed to read");
- }
-
- // ITE uses several patch files which are loaded and then not needed
- // anymore (as they're in memory), so close them here. IHNM uses only
- // 1 patch file, which is reused, so don't close it
- if (resourceData->patchData != NULL && _vm->getGameId() == GID_ITE)
- file->close();
-}
-
-static int metaResourceTable[] = { 0, 326, 517, 677, 805, 968, 1165, 0, 1271 };
-static int metaResourceTableDemo[] = { 0, 0, 0, 0, 0, 0, 0, 285, 0 };
-
-void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
- if (chapter < 0)
- chapter = (!(_vm->getFeatures() & GF_IHNM_DEMO)) ? 8 : 7;
-
- _vm->_script->_globalVoiceLUT.freeMem();
-
- // TODO: close chapter context, or rather reassign it in our case
-
- ResourceContext *resourceContext;
- ResourceContext *soundContext;
- int i;
-
- resourceContext = _vm->_resource->getContext(GAME_RESOURCEFILE);
- if (resourceContext == NULL) {
- error("Resource::loadGlobalResources() resource context not found");
- }
-
- soundContext = _vm->_resource->getContext(GAME_SOUNDFILE);
- if (soundContext == NULL) {
- error("Resource::loadGlobalResources() sound context not found");
- }
-
- byte *resourcePointer;
- size_t resourceLength;
-
- if (!(_vm->getFeatures() & GF_IHNM_DEMO)) {
- _vm->_resource->loadResource(resourceContext, metaResourceTable[chapter],
- resourcePointer, resourceLength);
- } else {
- _vm->_resource->loadResource(resourceContext, metaResourceTableDemo[chapter],
- resourcePointer, resourceLength);
- }
-
- if (resourceLength == 0) {
- error("Resource::loadGlobalResources wrong metaResource");
- }
-
- MemoryReadStream metaS(resourcePointer, resourceLength);
-
- _metaResource.sceneIndex = metaS.readSint16LE();
- _metaResource.objectCount = metaS.readSint16LE();
- _metaResource.objectsStringsResourceID = metaS.readSint32LE();
- _metaResource.inventorySpritesID = metaS.readSint32LE();
- _metaResource.mainSpritesID = metaS.readSint32LE();
- _metaResource.objectsResourceID = metaS.readSint32LE();
- _metaResource.actorCount = metaS.readSint16LE();
- _metaResource.actorsStringsResourceID = metaS.readSint32LE();
- _metaResource.actorsResourceID = metaS.readSint32LE();
- _metaResource.protagFaceSpritesID = metaS.readSint32LE();
- _metaResource.field_22 = metaS.readSint32LE();
- _metaResource.field_26 = metaS.readSint16LE();
- _metaResource.protagStatesCount = metaS.readSint16LE();
- _metaResource.protagStatesResourceID = metaS.readSint32LE();
- _metaResource.cutawayListResourceID = metaS.readSint32LE();
- _metaResource.songTableID = metaS.readSint32LE();
-
- free(resourcePointer);
-
- _vm->_actor->loadActorList(actorsEntrance, _metaResource.actorCount,
- _metaResource.actorsResourceID, _metaResource.protagStatesCount,
- _metaResource.protagStatesResourceID);
-
- _vm->_actor->_protagonist->_sceneNumber = _metaResource.sceneIndex;
-
- _vm->_actor->_objectsStrings.freeMem();
-
- _vm->_resource->loadResource(resourceContext, _metaResource.objectsStringsResourceID, resourcePointer, resourceLength);
- _vm->loadStrings(_vm->_actor->_objectsStrings, resourcePointer, resourceLength);
- free(resourcePointer);
-
- if (chapter >= _vm->_sndRes->_fxTableIDsLen) {
- error("Chapter ID exceeds fxTableIDs length");
- }
-
- debug(0, "Going to read %d of %d", chapter, _vm->_sndRes->_fxTableIDs[chapter]);
- _vm->_resource->loadResource(soundContext, _vm->_sndRes->_fxTableIDs[chapter],
- resourcePointer, resourceLength);
-
- if (resourceLength == 0) {
- error("Resource::loadGlobalResources Can't load sound effects for current track");
- }
-
- free(_vm->_sndRes->_fxTable);
-
- _vm->_sndRes->_fxTableLen = resourceLength / 4;
- _vm->_sndRes->_fxTable = (FxTable *)malloc(sizeof(FxTable) * _vm->_sndRes->_fxTableLen);
-
- MemoryReadStream fxS(resourcePointer, resourceLength);
-
- for (i = 0; i < _vm->_sndRes->_fxTableLen; i++) {
- _vm->_sndRes->_fxTable[i].res = fxS.readSint16LE();
- _vm->_sndRes->_fxTable[i].vol = fxS.readSint16LE();
- }
- free(resourcePointer);
-
- _vm->_interface->_defPortraits.freeMem();
- _vm->_sprite->loadList(_metaResource.protagFaceSpritesID, _vm->_interface->_defPortraits);
-
- _vm->_actor->_actorsStrings.freeMem();
-
- _vm->_resource->loadResource(resourceContext, _metaResource.actorsStringsResourceID, resourcePointer, resourceLength);
- _vm->loadStrings(_vm->_actor->_actorsStrings, resourcePointer, resourceLength);
- free(resourcePointer);
-
- _vm->_sprite->_inventorySprites.freeMem();
- _vm->_sprite->loadList(_metaResource.inventorySpritesID, _vm->_sprite->_inventorySprites);
-
- _vm->_sprite->_mainSprites.freeMem();
- _vm->_sprite->loadList(_metaResource.mainSpritesID, _vm->_sprite->_mainSprites);
-
- _vm->_actor->loadObjList(_metaResource.objectCount, _metaResource.objectsResourceID);
-
- _vm->_resource->loadResource(resourceContext, _metaResource.cutawayListResourceID, resourcePointer, resourceLength);
-
- if (resourceLength == 0) {
- error("Resource::loadGlobalResources Can't load cutaway list");
- }
-
- _vm->_anim->loadCutawayList(resourcePointer, resourceLength);
-
- if (_metaResource.songTableID > 0) {
- _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength);
-
- if (chapter == 6) {
- int32 id = READ_LE_UINT32(&resourcePointer[actorsEntrance * 4]);
- free(resourcePointer);
- _vm->_resource->loadResource(resourceContext, id, resourcePointer, resourceLength);
- }
-
- if (resourceLength == 0) {
- error("Resource::loadGlobalResources Can't load songs list for current track");
- }
-
- free(_vm->_music->_songTable);
-
- _vm->_music->_songTableLen = resourceLength / 4;
- _vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen);
-
- MemoryReadStream songS(resourcePointer, resourceLength);
-
- for (i = 0; i < _vm->_music->_songTableLen; i++)
- _vm->_music->_songTable[i] = songS.readSint32LE();
- free(resourcePointer);
- } else {
- // The IHNM demo has a fixed music track and doesn't load a song table
- _vm->_music->setVolume(_vm->_musicVolume, 1);
- _vm->_music->play(3, MUSIC_LOOP);
- free(resourcePointer);
- }
-
- int voiceLUTResourceID = 0;
-
- if (chapter != 7) {
- int voiceBank = (chapter == 8) ? 0 : chapter;
- _vm->_sndRes->setVoiceBank(voiceBank);
- voiceLUTResourceID = 22 + voiceBank;
- } else {
- // IHNM demo
- _vm->_sndRes->setVoiceBank(0);
- voiceLUTResourceID = 17;
- }
-
- if (voiceLUTResourceID) {
- _vm->_resource->loadResource(resourceContext, voiceLUTResourceID, resourcePointer, resourceLength);
- _vm->_script->loadVoiceLUT(_vm->_script->_globalVoiceLUT, resourcePointer, resourceLength);
- free(resourcePointer);
- }
-
- _vm->_spiritualBarometer = 0;
- _vm->_scene->setChapterNumber(chapter);
-}
-
-} // End of namespace Saga
Deleted: scummvm/trunk/engines/saga/rscfile.h
===================================================================
--- scummvm/trunk/engines/saga/rscfile.h 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/rscfile.h 2008-12-22 14:13:15 UTC (rev 35484)
@@ -1,168 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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$
- *
- */
-
-// RSC Resource file management header file
-
-#ifndef SAGA_RSCFILE_H
-#define SAGA_RSCFILE_H
-
-#include "common/file.h"
-
-namespace Saga {
-
-#define MAC_BINARY_HEADER_SIZE 128
-#define RSC_TABLEINFO_SIZE 8
-#define RSC_TABLEENTRY_SIZE 8
-
-#define RSC_MIN_FILESIZE (RSC_TABLEINFO_SIZE + RSC_TABLEENTRY_SIZE + 1)
-
-struct PatchData {
- bool _deletePatchFile;
- Common::File *_patchFile;
- const GamePatchDescription *_patchDescription;
-
- PatchData(const GamePatchDescription *patchDescription): _patchDescription(patchDescription), _deletePatchFile(true) {
- _patchFile = new Common::File();
- }
- PatchData(Common::File *patchFile): _patchDescription(NULL), _patchFile(patchFile), _deletePatchFile(false) {
- }
-
- ~PatchData() {
- if (_deletePatchFile) {
- delete _patchFile;
- }
- }
-};
-
-struct ResourceData {
- size_t offset;
- size_t size;
- PatchData *patchData;
- void fillSoundPatch(const GameSoundInfo *&soundInfo) {
- if (patchData != NULL) {
- if (patchData->_patchDescription != NULL) {
- if (patchData->_patchDescription->soundInfo != NULL) {
- soundInfo = patchData->_patchDescription->soundInfo;
- }
- }
- }
- }
-};
-
-struct ResourceContext {
- const char *fileName;
- uint16 fileType;
- Common::File *file;
- int serial;
-
- bool isBigEndian;
- ResourceData *table;
- size_t count;
-
- Common::File *getFile(ResourceData *resourceData) const {
- if (resourceData->patchData != NULL) {
- if (!resourceData->patchData->_patchFile->isOpen())
- resourceData->patchData->_patchFile->open(resourceData->patchData->_patchDescription->fileName);
- return resourceData->patchData->_patchFile;
- } else {
- return file;
- }
- }
-
- bool validResourceId(uint32 resourceId) const {
- return (resourceId < count);
- }
-
- ResourceData *getResourceData(uint32 resourceId) const {
- if (resourceId >= count) {
- error("ResourceContext::getResourceData() wrong resourceId %d", resourceId);
- }
- return &table[resourceId];
- }
-
-};
-
-struct MetaResource {
- int16 sceneIndex;
- int16 objectCount;
- int32 objectsStringsResourceID;
- int32 inventorySpritesID;
- int32 mainSpritesID;
- int32 objectsResourceID;
- int16 actorCount;
- int32 actorsStringsResourceID;
- int32 actorsResourceID;
- int32 protagFaceSpritesID;
- int32 field_22;
- int16 field_26;
- int16 protagStatesCount;
- int32 protagStatesResourceID;
- int32 cutawayListResourceID;
- int32 songTableID;
-
- MetaResource() {
- memset(this, 0, sizeof(*this));
- }
-};
-
-class Resource {
-public:
- Resource(SagaEngine *vm);
- ~Resource();
- bool createContexts();
- void clearContexts();
- void loadResource(ResourceContext *context, uint32 resourceId, byte*&resourceBuffer, size_t &resourceSize);
- uint32 convertResourceId(uint32 resourceId);
-
- void loadGlobalResources(int chapter, int actorsEntrance);
-
- ResourceContext *getContext(uint16 fileType, int serial = 0) {
- int i;
- for (i = 0; i < _contextsCount; i++) {
- if ((_contexts[i].fileType & fileType) && _contexts[i].serial == serial) {
- return &_contexts[i];
- }
- }
- return NULL;
- }
-
-private:
- SagaEngine *_vm;
- ResourceContext *_contexts;
- int _contextsCount;
- char _voicesFileName[8][256];
-
- bool loadContext(ResourceContext *context);
- bool loadMacContext(ResourceContext *context);
- bool loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize);
- bool loadHResContext(ResourceContext *context, uint32 contextSize);
-
-public:
- MetaResource _metaResource;
-};
-
-} // End of namespace Saga
-
-#endif
Modified: scummvm/trunk/engines/saga/saga.cpp
===================================================================
--- scummvm/trunk/engines/saga/saga.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/saga.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -34,7 +34,7 @@
#include "saga/saga.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/gfx.h"
#include "saga/render.h"
#include "saga/actor.h"
@@ -164,7 +164,18 @@
if (_readingSpeed > 3)
_readingSpeed = 0;
- _resource = new Resource(this);
+ switch(getGameId()) {
+ case GID_ITE:
+ _resource = new Resource_RSC(this);
+ break;
+ case GID_IHNM:
+ _resource = new Resource_RES(this);
+ break;
+ case GID_DINO:
+ case GID_FTA2:
+ _resource = new Resource_HRS(this);
+ break;
+ }
// Detect game and open resource files
if (!initGame()) {
Modified: scummvm/trunk/engines/saga/scene.cpp
===================================================================
--- scummvm/trunk/engines/saga/scene.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/scene.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -42,7 +42,7 @@
#include "saga/scene.h"
#include "saga/actor.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "graphics/iff.h"
#include "common/util.h"
@@ -667,7 +667,7 @@
if (_vm->getGameId() == GID_IHNM) {
if (loadSceneParams->loadFlag == kLoadBySceneNumber) // When will we get rid of it?
if (loadSceneParams->sceneDescriptor <= 0)
- loadSceneParams->sceneDescriptor = _vm->_resource->_metaResource.sceneIndex;
+ loadSceneParams->sceneDescriptor = _vm->_resource->getMetaResource()->sceneIndex;
}
switch (loadSceneParams->loadFlag) {
Modified: scummvm/trunk/engines/saga/script.cpp
===================================================================
--- scummvm/trunk/engines/saga/script.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/script.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -37,7 +37,7 @@
#include "saga/actor.h"
#include "saga/objectmap.h"
#include "saga/isomap.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
namespace Saga {
Modified: scummvm/trunk/engines/saga/sfuncs.cpp
===================================================================
--- scummvm/trunk/engines/saga/sfuncs.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/sfuncs.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -40,7 +40,7 @@
#include "saga/render.h"
#include "saga/sound.h"
#include "saga/sndres.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/script.h"
#include "saga/objectmap.h"
Modified: scummvm/trunk/engines/saga/sndres.cpp
===================================================================
--- scummvm/trunk/engines/saga/sndres.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/sndres.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -28,7 +28,7 @@
#include "saga/saga.h"
#include "saga/itedata.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/sndres.h"
#include "saga/sound.h"
Modified: scummvm/trunk/engines/saga/sprite.cpp
===================================================================
--- scummvm/trunk/engines/saga/sprite.cpp 2008-12-22 11:49:49 UTC (rev 35483)
+++ scummvm/trunk/engines/saga/sprite.cpp 2008-12-22 14:13:15 UTC (rev 35484)
@@ -29,7 +29,7 @@
#include "saga/gfx.h"
#include "saga/scene.h"
-#include "saga/rscfile.h"
+#include "saga/resource.h"
#include "saga/font.h"
#include "saga/sprite.h"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list