diff options
author | Filippos Karapetis | 2008-12-22 14:13:15 +0000 |
---|---|---|
committer | Filippos Karapetis | 2008-12-22 14:13:15 +0000 |
commit | 437384a83842c63dea3d0bd542332ed7ea48294f (patch) | |
tree | f5fcc6b8b8abc4e31143145a61ebfb89be644ac8 | |
parent | 1f669687a35b68d790b4a0ad54a19e11ec2a951b (diff) | |
download | scummvm-rg350-437384a83842c63dea3d0bd542332ed7ea48294f.tar.gz scummvm-rg350-437384a83842c63dea3d0bd542332ed7ea48294f.tar.bz2 scummvm-rg350-437384a83842c63dea3d0bd542332ed7ea48294f.zip |
- 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
svn-id: r35484
-rw-r--r-- | engines/saga/actor.cpp | 2 | ||||
-rw-r--r-- | engines/saga/animation.cpp | 2 | ||||
-rw-r--r-- | engines/saga/detection.cpp | 2 | ||||
-rw-r--r-- | engines/saga/events.cpp | 2 | ||||
-rw-r--r-- | engines/saga/font.cpp | 2 | ||||
-rw-r--r-- | engines/saga/gfx.cpp | 2 | ||||
-rw-r--r-- | engines/saga/interface.cpp | 2 | ||||
-rw-r--r-- | engines/saga/introproc_ihnm.cpp | 2 | ||||
-rw-r--r-- | engines/saga/introproc_ite.cpp | 2 | ||||
-rw-r--r-- | engines/saga/module.mk | 5 | ||||
-rw-r--r-- | engines/saga/music.cpp | 2 | ||||
-rw-r--r-- | engines/saga/resource.cpp (renamed from engines/saga/rscfile.cpp) | 431 | ||||
-rw-r--r-- | engines/saga/resource.h (renamed from engines/saga/rscfile.h) | 65 | ||||
-rw-r--r-- | engines/saga/resource_hrs.cpp | 47 | ||||
-rw-r--r-- | engines/saga/resource_res.cpp | 217 | ||||
-rw-r--r-- | engines/saga/resource_rsc.cpp | 212 | ||||
-rw-r--r-- | engines/saga/saga.cpp | 15 | ||||
-rw-r--r-- | engines/saga/scene.cpp | 4 | ||||
-rw-r--r-- | engines/saga/script.cpp | 2 | ||||
-rw-r--r-- | engines/saga/sfuncs.cpp | 2 | ||||
-rw-r--r-- | engines/saga/sndres.cpp | 2 | ||||
-rw-r--r-- | engines/saga/sprite.cpp | 2 |
22 files changed, 624 insertions, 400 deletions
diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp index 4f97f32189..2fa40c22ae 100644 --- a/engines/saga/actor.cpp +++ b/engines/saga/actor.cpp @@ -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" diff --git a/engines/saga/animation.cpp b/engines/saga/animation.cpp index d514d5f217..5c9cb647d9 100644 --- a/engines/saga/animation.cpp +++ b/engines/saga/animation.cpp @@ -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" diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp index 45fa0e76f3..8cc8dc430e 100644 --- a/engines/saga/detection.cpp +++ b/engines/saga/detection.cpp @@ -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" diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp index 7144a1cbd1..b4a436fa31 100644 --- a/engines/saga/events.cpp +++ b/engines/saga/events.cpp @@ -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" diff --git a/engines/saga/font.cpp b/engines/saga/font.cpp index cb44e9ad08..5ea7124184 100644 --- a/engines/saga/font.cpp +++ b/engines/saga/font.cpp @@ -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" diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp index fa586f0dc7..b548753c88 100644 --- a/engines/saga/gfx.cpp +++ b/engines/saga/gfx.cpp @@ -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" diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp index c1c3b4a1d7..8418a8656b 100644 --- a/engines/saga/interface.cpp +++ b/engines/saga/interface.cpp @@ -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" diff --git a/engines/saga/introproc_ihnm.cpp b/engines/saga/introproc_ihnm.cpp index 99e2b4aa31..1cd1079d83 100644 --- a/engines/saga/introproc_ihnm.cpp +++ b/engines/saga/introproc_ihnm.cpp @@ -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" diff --git a/engines/saga/introproc_ite.cpp b/engines/saga/introproc_ite.cpp index 5ce5762124..058b704991 100644 --- a/engines/saga/introproc_ite.cpp +++ b/engines/saga/introproc_ite.cpp @@ -36,7 +36,7 @@ #include "saga/music.h" #include "saga/scene.h" -#include "saga/rscfile.h" +#include "saga/resource.h" namespace Saga { diff --git a/engines/saga/module.mk b/engines/saga/module.mk index 93198055a6..24ebc40a4e 100644 --- a/engines/saga/module.mk +++ b/engines/saga/module.mk @@ -24,7 +24,10 @@ MODULE_OBJS := \ 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 \ diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 202c870a77..3124deba57 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -27,7 +27,7 @@ #include "saga/saga.h" -#include "saga/rscfile.h" +#include "saga/resource.h" #include "saga/music.h" #include "sound/audiostream.h" diff --git a/engines/saga/rscfile.cpp b/engines/saga/resource.cpp index dfdba864ba..4176488117 100644 --- a/engines/saga/rscfile.cpp +++ b/engines/saga/resource.cpp @@ -31,7 +31,7 @@ #include "saga/animation.h" #include "saga/interface.h" #include "saga/music.h" -#include "saga/rscfile.h" +#include "saga/resource.h" #include "saga/scene.h" #include "saga/sndres.h" @@ -39,32 +39,6 @@ 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; @@ -74,7 +48,7 @@ Resource::~Resource() { clearContexts(); } -bool Resource::loadResContext(ResourceContext *context, uint32 contextOffset, uint32 contextSize) { +bool Resource::loadResContext_v1(ResourceContext *context, uint32 contextOffset, uint32 contextSize) { size_t i; bool result; byte tableInfo[RSC_TABLEINFO_SIZE]; @@ -132,141 +106,6 @@ bool Resource::loadResContext(ResourceContext *context, uint32 contextOffset, ui 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; @@ -293,16 +132,8 @@ bool Resource::loadContext(ResourceContext *context) { 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; - } + if (!loadResContext(context, 0, context->file->size())) { + return false; } } else { if (!loadMacContext(context)) { @@ -401,22 +232,44 @@ bool Resource::createContexts() { //// Detect and add SFX files //////////////////////////////////////////////// SoundFileInfo sfxFilesITE[] = { - { "sounds.rsc", false }, - { "sounds.cmp", true }, - { "soundsd.rsc", false }, - { "soundsd.cmp", true } + { "sounds.rsc", false }, + { "sounds.cmp", true }, + { "soundsd.rsc", false }, + { "soundsd.cmp", true } }; SoundFileInfo sfxFilesIHNM[] = { - { "sfx.res", false }, - { "sfx.cmp", true } + { "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; - curSoundfiles = _vm->getGameId() == GID_ITE ? sfxFilesITE : sfxFilesIHNM; - maxFile = _vm->getGameId() == GID_ITE ? 4 : 2; + + 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)) { @@ -457,10 +310,32 @@ bool Resource::createContexts() { { "voicesd.cmp", true }, }; + SoundFileInfo voiceFilesFTA2[] = { + { "ftavoice.hrs", false }, + }; + // Detect and add voice files fileFound = false; - curSoundfiles = _vm->getGameId() == GID_ITE ? voiceFilesITE : voiceFilesIHNM; - maxFile = _vm->getGameId() == GID_ITE ? 7 : 4; + + 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)) { @@ -614,21 +489,6 @@ void Resource::clearContexts() { _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; @@ -658,179 +518,4 @@ void Resource::loadResource(ResourceContext *context, uint32 resourceId, byte*&r 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 diff --git a/engines/saga/rscfile.h b/engines/saga/resource.h index c263796f05..a93ba7ae30 100644 --- a/engines/saga/rscfile.h +++ b/engines/saga/resource.h @@ -25,8 +25,8 @@ // RSC Resource file management header file -#ifndef SAGA_RSCFILE_H -#define SAGA_RSCFILE_H +#ifndef SAGA_RESOURCE_H +#define SAGA_RESOURCE_H #include "common/file.h" @@ -134,9 +134,9 @@ public: 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); + virtual uint32 convertResourceId(uint32 resourceId) = 0; + virtual void loadGlobalResources(int chapter, int actorsEntrance) = 0; ResourceContext *getContext(uint16 fileType, int serial = 0) { int i; @@ -148,21 +148,70 @@ public: return NULL; } -private: +protected: 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); + 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 diff --git a/engines/saga/resource_hrs.cpp b/engines/saga/resource_hrs.cpp new file mode 100644 index 0000000000..500b3d04d5 --- /dev/null +++ b/engines/saga/resource_hrs.cpp @@ -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 diff --git a/engines/saga/resource_res.cpp b/engines/saga/resource_res.cpp new file mode 100644 index 0000000000..282eac3fc1 --- /dev/null +++ b/engines/saga/resource_res.cpp @@ -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 diff --git a/engines/saga/resource_rsc.cpp b/engines/saga/resource_rsc.cpp new file mode 100644 index 0000000000..8176d6ec02 --- /dev/null +++ b/engines/saga/resource_rsc.cpp @@ -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 diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index 61fa29ecd1..bcad5e03be 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -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 @@ Common::Error SagaEngine::init() { 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()) { diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp index 086ec4be4c..b4283effce 100644 --- a/engines/saga/scene.cpp +++ b/engines/saga/scene.cpp @@ -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 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { 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) { diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp index e369edabde..bf2ddb905a 100644 --- a/engines/saga/script.cpp +++ b/engines/saga/script.cpp @@ -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 { diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp index f626850dd2..2aef7e5df3 100644 --- a/engines/saga/sfuncs.cpp +++ b/engines/saga/sfuncs.cpp @@ -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" diff --git a/engines/saga/sndres.cpp b/engines/saga/sndres.cpp index 2b6498a753..6121890e9b 100644 --- a/engines/saga/sndres.cpp +++ b/engines/saga/sndres.cpp @@ -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" diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp index 9e8e29ab33..9a4594c54b 100644 --- a/engines/saga/sprite.cpp +++ b/engines/saga/sprite.cpp @@ -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" |