aboutsummaryrefslogtreecommitdiff
path: root/engines/saga/rscfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/saga/rscfile.cpp')
-rw-r--r--engines/saga/rscfile.cpp230
1 files changed, 211 insertions, 19 deletions
diff --git a/engines/saga/rscfile.cpp b/engines/saga/rscfile.cpp
index 33e8a7d603..4d3ff1e47c 100644
--- a/engines/saga/rscfile.cpp
+++ b/engines/saga/rscfile.cpp
@@ -24,6 +24,7 @@
*/
// RSC Resource file management module
+
#include "saga/saga.h"
#include "saga/actor.h"
@@ -329,6 +330,7 @@ bool Resource::loadContext(ResourceContext *context) {
if (resourceData->patchData->_patchFile->open(patchDescription->fileName)) {
resourceData->offset = 0;
resourceData->size = resourceData->patchData->_patchFile->size();
+ resourceData->patchData->_patchFile->close();
} else {
delete resourceData->patchData;
resourceData->patchData = NULL;
@@ -343,18 +345,188 @@ bool Resource::loadContext(ResourceContext *context) {
bool Resource::createContexts() {
int i;
ResourceContext *context;
+ char musicFileName[256];
+ char soundFileName[256];
+ char voicesFileName[256];
+ int soundFileIndex = 0;
+ int voicesFileIndex = 0;
+ bool digitalMusic = false;
+ bool soundFileInArray = false;
+ bool voicesFileInArray = false;
+ bool multipleVoices = false;
+ bool censoredVersion = false;
+ uint16 voiceFileType = GAME_VOICEFILE;
_contextsCount = 0;
- for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++)
+ for (i = 0; _vm->getFilesDescriptions()[i].fileName; i++) {
_contextsCount++;
+ if (_vm->getFilesDescriptions()[i].fileType == GAME_SOUNDFILE)
+ soundFileInArray = true;
+ if (_vm->getFilesDescriptions()[i].fileType == GAME_VOICEFILE)
+ voicesFileInArray = true;
+ }
+
+ if (!soundFileInArray) {
+ if (_vm->getGameType() == GType_ITE) {
+ // If the sound file is not specified in the detector table, add it here
+ if (Common::File::exists("sounds.rsc") || Common::File::exists("sounds.cmp")) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(soundFileName, "sounds.cmp");
+ else
+ sprintf(soundFileName, "sounds.rsc");
+ } else if (Common::File::exists("soundsd.rsc") || Common::File::exists("soundsd.cmp")) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(soundFileName, "soundsd.cmp");
+ else
+ sprintf(soundFileName, "soundsd.rsc");
+ } else {
+ // No sound file found, don't add any file to the array
+ soundFileInArray = true;
+ // ITE floppy versions have both voices and sounds in voices.rsc
+ voiceFileType = GAME_SOUNDFILE | GAME_VOICEFILE;
+ }
+ } else {
+ // If the sound file is not specified in the detector table, add it here
+ if (Common::File::exists("sfx.res") || Common::File::exists("sfx.cmp")) {
+ _contextsCount++;
+ soundFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(soundFileName, "sfx.cmp");
+ else
+ sprintf(soundFileName, "sfx.res");
+ } else {
+ // No sound file found, don't add any file to the array
+ soundFileInArray = true;
+ }
+ }
+ }
+
+ if (!voicesFileInArray) {
+ if (_vm->getGameType() == GType_ITE) {
+ // If the voices file is not specified in the detector table, add it here
+ if (Common::File::exists("voices.rsc") || Common::File::exists("voices.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voices.cmp");
+ else
+ sprintf(voicesFileName, "voices.rsc");
+ } else if (Common::File::exists("voicesd.rsc") || Common::File::exists("voicesd.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voicesd.cmp");
+ else
+ sprintf(voicesFileName, "voicesd.rsc");
+ } else if (Common::File::exists("inherit the earth voices") ||
+ Common::File::exists("inherit the earth voices.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "inherit the earth voices.cmp");
+ else
+ sprintf(voicesFileName, "inherit the earth voices");
+ // 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
+ } else {
+ // No voice file found, don't add any file to the array
+ voicesFileInArray = true;
+ }
+ } else {
+ // If the voices file is not specified in the detector table, add it here
+ if (Common::File::exists("voicess.res") || Common::File::exists("voicess.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ // IHNM has multiple voice files
+ multipleVoices = true;
+ // Note: it is assumed that the voices 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;
+ }
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voicess.cmp");
+ else
+ sprintf(voicesFileName, "voicess.res");
+ } else if (Common::File::exists("voicesd.res") || Common::File::exists("voicesd.cmp")) {
+ _contextsCount++;
+ voicesFileIndex = _contextsCount - 1;
+ if (_vm->getFeatures() & GF_COMPRESSED_SOUNDS)
+ sprintf(voicesFileName, "voicesd.cmp");
+ else
+ sprintf(voicesFileName, "voicesd.res");
+ } else {
+ // No voice file found, don't add any file to the array
+ voicesFileInArray = true;
+ }
+ }
+ }
+
+ if (_vm->getGameType() == GType_ITE) {
+ // Check for digital music in ITE
+ if (Common::File::exists("music.rsc") || Common::File::exists("music.cmp")) {
+ _contextsCount++;
+ digitalMusic = true;
+ if (Common::File::exists("music.cmp"))
+ sprintf(musicFileName, "music.cmp");
+ else
+ sprintf(musicFileName, "music.rsc");
+ } else if (Common::File::exists("musicd.rsc") || Common::File::exists("musicd.cmp")) {
+ _contextsCount++;
+ digitalMusic = true;
+ if (Common::File::exists("musicd.cmp"))
+ sprintf(musicFileName, "musicd.cmp");
+ else
+ sprintf(musicFileName, "musicd.rsc");
+ } else {
+ digitalMusic = false;
+ }
+ }
_contexts = (ResourceContext*)calloc(_contextsCount, sizeof(*_contexts));
for (i = 0; i < _contextsCount; i++) {
context = &_contexts[i];
context->file = new Common::File();
- context->fileName = _vm->getFilesDescriptions()[i].fileName;
- context->fileType = _vm->getFilesDescriptions()[i].fileType;
+
+ // For ITE, add the digital music file and sfx file information here
+ if (_vm->getGameType() == GType_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 (!voicesFileInArray && i == voicesFileIndex) {
+ context->fileName = voicesFileName;
+ // can be GAME_VOICEFILE or GAME_SOUNDFILE | GAME_VOICEFILE or GAME_VOICEFILE | GAME_SWAPENDIAN
+ context->fileType = voiceFileType;
+ } else {
+ if (!(!voicesFileInArray && 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, "voices%i.cmp", i - voicesFileIndex + token);
+ else
+ sprintf(voicesFileName, "voices%i.res", i - voicesFileIndex + token);
+
+ context->fileName = voicesFileName;
+ context->fileType = GAME_VOICEFILE;
+ }
+ }
context->serial = 0;
// IHNM has serveral different voice files, so we need to allow
@@ -434,13 +606,20 @@ void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&r
if (file->read(resourceBuffer, resourceSize) != resourceSize) {
error("Resource::loadResource() failed to read");
}
+ if (resourceData->patchData != NULL)
+ 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 = 8;
+ if (chapter < 0) {
+ if (_vm->getGameId() != GID_IHNM_DEMO)
+ chapter = 8;
+ else
+ chapter = 7;
+ }
// TODO
//if (module.voiceLUT)
@@ -465,8 +644,13 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
byte *resourcePointer;
size_t resourceLength;
- _vm->_resource->loadResource(resourceContext, metaResourceTable[chapter],
- resourcePointer, resourceLength);
+ if (_vm->getGameId() != GID_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");
@@ -555,22 +739,27 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
_vm->_anim->loadCutawayList(resourcePointer, resourceLength);
- _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength);
+ if (_metaResource.songTableID > 0) {
+ _vm->_resource->loadResource(resourceContext, _metaResource.songTableID, resourcePointer, resourceLength);
- if (resourceLength == 0) {
- error("Resource::loadGlobalResources Can't load songs list for current track");
- }
+ 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);
+ free(_vm->_music->_songTable);
+
+ _vm->_music->_songTableLen = resourceLength / 4;
+ _vm->_music->_songTable = (int32 *)malloc(sizeof(int32) * _vm->_music->_songTableLen);
- MemoryReadStream songS(resourcePointer, resourceLength);
+ MemoryReadStream songS(resourcePointer, resourceLength);
- for (i = 0; i < _vm->_music->_songTableLen; i++)
- _vm->_music->_songTable[i] = songS.readSint32LE();
- free(resourcePointer);
+ 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->play(3, MUSIC_LOOP);
+ }
int voiceLUTResourceID = 0;
@@ -602,6 +791,9 @@ void Resource::loadGlobalResources(int chapter, int actorsEntrance) {
voiceLUTResourceID = 28;
break;
case 7:
+ // IHNM demo
+ _vm->_sndRes->setVoiceBank(0);
+ voiceLUTResourceID = 17;
break;
case 8:
_vm->_sndRes->setVoiceBank(0);