diff options
author | Walter van Niftrik | 2009-06-07 19:15:55 +0000 |
---|---|---|
committer | Walter van Niftrik | 2009-06-07 19:15:55 +0000 |
commit | a6ed05740f1f46639f38ccf0afb9c444564cc84f (patch) | |
tree | 310b79a435f54f2d8e22555234ccb33f62848969 | |
parent | 4dd29a5985a4190f99446865209850a40f12e2e4 (diff) | |
download | scummvm-rg350-a6ed05740f1f46639f38ccf0afb9c444564cc84f.tar.gz scummvm-rg350-a6ed05740f1f46639f38ccf0afb9c444564cc84f.tar.bz2 scummvm-rg350-a6ed05740f1f46639f38ccf0afb9c444564cc84f.zip |
SCI: Moved resource36 handling into resource manager.
svn-id: r41349
-rw-r--r-- | engines/sci/console.cpp | 48 | ||||
-rw-r--r-- | engines/sci/engine/game.cpp | 18 | ||||
-rw-r--r-- | engines/sci/engine/kernel.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 49 | ||||
-rw-r--r-- | engines/sci/engine/ksound.cpp | 57 | ||||
-rw-r--r-- | engines/sci/engine/kstring.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/message.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/script.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 4 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.cpp | 10 | ||||
-rw-r--r-- | engines/sci/resource.cpp | 390 | ||||
-rw-r--r-- | engines/sci/resource.h | 47 | ||||
-rw-r--r-- | engines/sci/sfx/softseq/adlib.cpp | 2 | ||||
-rw-r--r-- | engines/sci/vocabulary.cpp | 22 |
16 files changed, 334 insertions, 339 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index ed132a3930..b7cf44a739 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -548,7 +548,7 @@ bool Console::cmdHexDump(int argc, const char **argv) { if (res == kResourceTypeInvalid) DebugPrintf("Resource type '%s' is not valid\n", argv[1]); else { - Resource *resource = _vm->getResMgr()->findResource(res, resNum, 0); + Resource *resource = _vm->getResMgr()->findResource(ResourceId(res, resNum), 0); if (resource) { Common::hexdump(resource->data, resource->size, 16, 0); DebugPrintf("Resource %s.%03d has been dumped to standard output\n", argv[1], resNum); @@ -609,7 +609,7 @@ bool Console::cmdResourceSize(int argc, const char **argv) { if (res == kResourceTypeInvalid) DebugPrintf("Resource type '%s' is not valid\n", argv[1]); else { - Resource *resource = _vm->getResMgr()->findResource(res, resNum, 0); + Resource *resource = _vm->getResMgr()->findResource(ResourceId(res, resNum), 0); if (resource) { DebugPrintf("Resource size: %d\n", resource->size); } else { @@ -679,7 +679,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) { } for (; resNumber <= resMax; resNumber++) { - if ((script = _vm->getResMgr()->findResource(restype, resNumber, 0))) { + if ((script = _vm->getResMgr()->findResource(ResourceId(restype, resNumber), 0))) { unsigned int seeker = 0, seekerold = 0; uint32 comppos = 0; int output_script_name = 0; @@ -713,7 +713,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) { } bool Console::cmdList(int argc, const char **argv) { - if (argc != 2) { + if (argc < 2) { DebugPrintf("Lists all the resources of a given type\n"); cmdResourceTypes(argc, argv); return true; @@ -724,16 +724,38 @@ bool Console::cmdList(int argc, const char **argv) { if (res == kResourceTypeInvalid) DebugPrintf("Unknown resource type: '%s'\n", argv[1]); else { - int j = 0; - for (int i = 0; i < sci_max_resource_nr[_vm->getResMgr()->_sciVersion]; i++) { - if (_vm->getResMgr()->testResource(res, i)) { - DebugPrintf("%s.%03d | ", getResourceTypeName((ResourceType)res), i); - if (j % 5 == 0) + int number = -1; + + if ((res == kResourceTypeAudio36) || (res == kResourceTypeSync36)) { + if (argc != 3) { + DebugPrintf("Please specify map number\n"); + return true; + } + number = atoi(argv[2]); + } + + Common::List<ResourceId> *resources = _vm->getResMgr()->listResources(res, number); + sort(resources->begin(), resources->end(), ResourceIdLess()); + Common::List<ResourceId>::iterator itr = resources->begin(); + + int cnt = 0; + while (itr != resources->end()) { + if (number == -1) { + DebugPrintf("%8i", itr->number); + if (++cnt % 10 == 0) DebugPrintf("\n"); - j++; } + else if (number == (int)itr->number) { + DebugPrintf("(%3i, %3i, %3i, %3i) ", (itr->tuple >> 24) & 0xff, (itr->tuple >> 16) & 0xff, + (itr->tuple >> 8) & 0xff, itr->tuple & 0xff); + if (++cnt % 4 == 0) + DebugPrintf("\n"); + } + itr++; } DebugPrintf("\n"); + + delete resources; } return true; @@ -2391,7 +2413,7 @@ bool Console::cmdIsSample(int argc, const char **argv) { return true; } - Resource *song = _vm->getResMgr()->findResource(kResourceTypeSound, atoi(argv[1]), 0); + Resource *song = _vm->getResMgr()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0); SongIterator *songit; Audio::AudioStream *data; @@ -2429,7 +2451,7 @@ bool Console::cmdSfx01Header(int argc, const char **argv) { return true; } - Resource *song = _vm->getResMgr()->findResource(kResourceTypeSound, atoi(argv[1]), 0); + Resource *song = _vm->getResMgr()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0); if (!song) { DebugPrintf("Doesn't exist\n"); @@ -2594,7 +2616,7 @@ bool Console::cmdSfx01Track(int argc, const char **argv) { return true; } - Resource *song = _vm->getResMgr()->findResource(kResourceTypeSound, atoi(argv[1]), 0); + Resource *song = _vm->getResMgr()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0); int offset = atoi(argv[2]); diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 5a250529cd..bbb29ada3b 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -64,13 +64,13 @@ int _reset_graphics_input(EngineState *s) { s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal1_amiga(file)); file.close(); } else { - resource = s->resmgr->findResource(kResourceTypePalette, 999, 1); + resource = s->resmgr->findResource(ResourceId(kResourceTypePalette, 999), 1); if (resource) { if (s->_version < SCI_VERSION_1_1) s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal1(999, resource->data, resource->size)); else s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal11(999, resource->data, resource->size)); - s->resmgr->unlockResource(resource, 999, kResourceTypePalette); + s->resmgr->unlockResource(resource); } else { debug(2, "Couldn't find the default palette!"); } @@ -96,7 +96,7 @@ int _reset_graphics_input(EngineState *s) { font_nr = -1; do { - resource = s->resmgr->testResource(kResourceTypeFont, ++font_nr); + resource = s->resmgr->testResource(ResourceId(kResourceTypeFont, ++font_nr)); } while ((!resource) && (font_nr < sci_max_resource_nr[s->resmgr->_sciVersion])); if (!resource) { @@ -196,7 +196,7 @@ int create_class_table_sci11(EngineState *s) { char *seeker_ptr; int classnr; - Resource *vocab996 = s->resmgr->findResource(kResourceTypeVocab, 996, 1); + Resource *vocab996 = s->resmgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); if (!vocab996) s->_classtable.resize(20); @@ -204,7 +204,7 @@ int create_class_table_sci11(EngineState *s) { s->_classtable.resize(vocab996->size >> 2); for (scriptnr = 0; scriptnr < 1000; scriptnr++) { - Resource *heap = s->resmgr->findResource(kResourceTypeHeap, scriptnr, 0); + Resource *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, scriptnr), 0); if (heap) { int global_vars = READ_LE_UINT16(heap->data + 2); @@ -236,7 +236,7 @@ int create_class_table_sci11(EngineState *s) { } } - s->resmgr->unlockResource(vocab996, 996, kResourceTypeVocab); + s->resmgr->unlockResource(vocab996); vocab996 = NULL; return 0; } @@ -247,7 +247,7 @@ static int create_class_table_sci0(EngineState *s) { int classnr; int magic_offset; // For strange scripts in older SCI versions - Resource *vocab996 = s->resmgr->findResource(kResourceTypeVocab, 996, 1); + Resource *vocab996 = s->resmgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); if (!vocab996) s->_classtable.resize(20); @@ -256,7 +256,7 @@ static int create_class_table_sci0(EngineState *s) { for (scriptnr = 0; scriptnr < 1000; scriptnr++) { int objtype = 0; - Resource *script = s->resmgr->findResource(kResourceTypeScript, scriptnr, 0); + Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scriptnr), 0); if (script) { if (s->_flags & GF_SCI0_OLD) @@ -318,7 +318,7 @@ static int create_class_table_sci0(EngineState *s) { } } - s->resmgr->unlockResource(vocab996, 996, kResourceTypeVocab); + s->resmgr->unlockResource(vocab996); vocab996 = NULL; return 0; } diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 3b998c7092..baf45d80c7 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -495,7 +495,7 @@ Kernel::~Kernel() { bool Kernel::loadSelectorNames(bool isOldSci0) { int count; - Resource *r = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES, 0); + Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0); if (!r) // No such resource? return false; @@ -520,7 +520,7 @@ bool Kernel::loadSelectorNames(bool isOldSci0) { bool Kernel::loadOpcodes() { int count, i = 0; - Resource* r = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES, 0); + Resource* r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES), 0); _opcodes.clear(); @@ -862,7 +862,7 @@ static void _vocab_get_knames0alt(const Resource *r, Common::StringList &names) static void vocab_get_knames0(ResourceManager *resmgr, Common::StringList &names) { int count, i, index = 2, empty_to_add = 1; - Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0); + Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0); if (!r) { // No kernel name table found? Fall back to default table names.resize(SCI0_KNAMES_DEFAULT_ENTRIES_NR); @@ -925,7 +925,7 @@ static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &name */ //unsigned int size = 64, pos = 3; int len; - Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0); + Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0); if(r == NULL) // failed to open vocab.999 (happens with SCI1 demos) return; // FIXME: should return a default table for this engine const byte nCnt = *r->data; diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 2479696630..d82f8ff132 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -125,19 +125,27 @@ reg_t kLoad(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kLock(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int restype = argv[0].toUint16() & 0x7f; - int resnr = argv[1].toUint16(); int state = argc > 2 ? argv[2].toUint16() : 1; + ResourceType type = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceId id = ResourceId(type, argv[1].toUint16()); Resource *which; switch (state) { case 1 : - s->resmgr->findResource((ResourceType)restype, resnr, 1); + s->resmgr->findResource(id, 1); break; case 0 : - which = s->resmgr->findResource((ResourceType)restype, resnr, 0); - s->resmgr->unlockResource(which, resnr, (ResourceType)restype); + which = s->resmgr->findResource(id, 0); + + if (which) + s->resmgr->unlockResource(which); + else { + if (id.type == kResourceTypeInvalid) + warning("[Resmgr] Attempt to unlock resource %i of invalid type %i", id.number, type); + else + warning("[Resmgr] Attempt to unlock non-existant resource %s", id.toString().c_str()); + } break; } return s->r_acc; @@ -155,26 +163,23 @@ reg_t kUnLoad(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kResCheck(EngineState *s, int funct_nr, int argc, reg_t *argv) { + Resource *res = NULL; ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); - switch (restype) { - case kResourceTypeAudio36: - case kResourceTypeSync36: { - assert(argc >= 6); - - uint module = argv[1].toUint16(); - uint noun = argv[2].toUint16(); - uint verb = argv[3].toUint16(); - uint cond = argv[4].toUint16(); - uint seq = argv[5].toUint16(); - warning("ResCheck: checking for currently unsupported %s resource: module %i; tuple (%i, %i, %i, %i)", - getResourceTypeName(restype), module, noun, verb, cond, seq); - return make_reg(0, 1); - } - default: - Resource *res = s->resmgr->testResource(restype, argv[1].toUint16()); - return make_reg(0, res != NULL); + if ((restype == kResourceTypeAudio36) || (restype == kResourceTypeSync36)) { + if (argc >= 6) { + uint noun = argv[2].toUint16() & 0xff; + uint verb = argv[3].toUint16() & 0xff; + uint cond = argv[4].toUint16() & 0xff; + uint seq = argv[5].toUint16() & 0xff; + + res = s->resmgr->testResource(ResourceId(restype, argv[1].toUint16(), noun, verb, cond, seq)); + } + } else { + res = s->resmgr->testResource(ResourceId(restype, argv[1].toUint16())); } + + return make_reg(0, res != NULL); } reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index f899fa9a84..b742c93a52 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -123,7 +123,7 @@ enum AudioSyncCommands { static void script_set_priority(EngineState *s, reg_t obj, int priority) { int song_nr = GET_SEL32V(obj, number); - Resource *song = s->resmgr->findResource(kResourceTypeSound, song_nr, 0); + Resource *song = s->resmgr->findResource(ResourceId(kResourceTypeSound, song_nr), 0); int flags = GET_SEL32V(obj, flags); if (priority == -1) { @@ -140,7 +140,7 @@ static void script_set_priority(EngineState *s, reg_t obj, int priority) { } SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, songit_id_t id) { - Resource *song = s->resmgr->findResource(kResourceTypeSound, song_nr, 0); + Resource *song = s->resmgr->findResource(ResourceId(kResourceTypeSound, song_nr), 0); if (!song) return NULL; @@ -503,7 +503,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { //int vol = GET_SEL32V(obj, vol); //int pri = GET_SEL32V(obj, pri); - if (obj.segment && (s->resmgr->testResource(kResourceTypeSound, number))) { + if (obj.segment && (s->resmgr->testResource(ResourceId(kResourceTypeSound, number)))) { sciprintf("Initializing song number %d\n", number); s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, handle), 0, handle, number); @@ -807,7 +807,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { } if (!GET_SEL32V(obj, nodePtr) && obj.segment) { - if (!s->resmgr->testResource(kResourceTypeSound, number)) { + if (!s->resmgr->testResource(ResourceId(kResourceTypeSound, number))) { sciprintf("Could not open song number %d\n", number); return NULL_REG; } @@ -837,7 +837,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->_sound.sfx_remove_song(handle); } - if (obj.segment && (s->resmgr->testResource(kResourceTypeSound, number))) { + if (obj.segment && (s->resmgr->testResource(ResourceId(kResourceTypeSound, number)))) { sciprintf("Initializing song number %d\n", number); s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, handle), 0, handle, number); @@ -991,15 +991,12 @@ reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { if (audioStream) mixer->playInputStream(Audio::Mixer::kSpeechSoundType, s->_sound._audioResource->getAudioHandle(), audioStream); } else if (argc == 6) { // SQ4CD or newer - //uint32 volume = argv[1].toUint16(); // Make a BE number uint32 audioNumber = (((argv[2].toUint16() & 0xFF) << 24) & 0xFF000000) | (((argv[3].toUint16() & 0xFF) << 16) & 0x00FF0000) | (((argv[4].toUint16() & 0xFF) << 8) & 0x0000FF00) | ( (argv[5].toUint16() & 0xFF) & 0x000000FF); - printf("%d %d %d %d -> %d\n", argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16(), audioNumber); // debugging - Audio::AudioStream *audioStream = s->_sound._audioResource->getAudioStream(audioNumber, argv[1].toUint16(), &sampleLen); if (audioStream) @@ -1042,28 +1039,34 @@ reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) { switch (argv[0].toUint16()) { - case kSciAudioSyncStart: - if (argc == 3) { // KQ5CD, KQ6 floppy - if (s->_sound._soundSync) { - s->resmgr->unlockResource(s->_sound._soundSync, s->_sound._soundSync->id.number, kResourceTypeSync); - } + case kSciAudioSyncStart: { + ResourceId id; + + if (s->_sound._soundSync) + s->resmgr->unlockResource(s->_sound._soundSync); + + // Load sound sync resource and lock it + if (argc == 3) { + id = ResourceId(kResourceTypeSync, argv[2].toUint16()); + } else if (argc == 7) { + id = ResourceId(kResourceTypeSync36, argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), + argv[5].toUint16(), argv[6].toUint16()); + } else { + warning("kDoSync: Start called with an unknown number of parameters (%d)", argc); + return s->r_acc; + } - // Load sound sync resource and lock it - s->_sound._soundSync = (ResourceSync *)s->resmgr->findResource(kResourceTypeSync, argv[2].toUint16(), 1); + s->_sound._soundSync = (ResourceSync *)s->resmgr->findResource(id, 1); - if (s->_sound._soundSync) { - s->_sound._soundSync->startSync(s, argv[1]); - } else { - // Notify the scripts to stop sound sync - PUT_SEL32V(argv[1], syncCue, -1); - } - } else if (argc == 7) { // SQ4CD or newer - // TODO - warning("kDoSync: Start called with new semantics - 6 parameters: %d %d %d %d %d %d", argv[1].toUint16(), argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16(), argv[6].toUint16()); - } else { // Hopefully, this should never happen - warning("kDoSync: Start called with an unknown number of parameters (%d)", argc); + if (s->_sound._soundSync) { + s->_sound._soundSync->startSync(s, argv[1]); + } else { + warning("DoSync: failed to find resource %s", id.toString().c_str()); + // Notify the scripts to stop sound sync + PUT_SEL32V(argv[1], syncCue, -1); } break; + } case kSciAudioSyncNext: if (s->_sound._soundSync) { s->_sound._soundSync->nextSync(s, argv[1]); @@ -1072,7 +1075,7 @@ reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) { case kSciAudioSyncStop: if (s->_sound._soundSync) { s->_sound._soundSync->stopSync(); - s->resmgr->unlockResource(s->_sound._soundSync, s->_sound._soundSync->id.number, kResourceTypeSync); + s->resmgr->unlockResource(s->_sound._soundSync); s->_sound._soundSync = NULL; } break; diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index cb2f9ea07c..2a30a103b6 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -48,7 +48,7 @@ char *kernel_lookup_text(EngineState *s, reg_t address, int index) { else { int textlen; int _index = index; - textres = s->resmgr->findResource(kResourceTypeText, address.offset, 0); + textres = s->resmgr->findResource(ResourceId(kResourceTypeText, address.offset), 0); if (!textres) { error("text.%03d not found", address.offset); @@ -646,7 +646,7 @@ reg_t kStrLen(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kGetFarText(EngineState *s, int funct_nr, int argc, reg_t *argv) { - Resource *textres = s->resmgr->findResource(kResourceTypeText, argv[0].toUint16(), 0); + Resource *textres = s->resmgr->findResource(ResourceId(kResourceTypeText, argv[0].toUint16()), 0); char *seeker; int counter = argv[1].toUint16(); diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index 4f5efa106c..c019f7a3bc 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -229,11 +229,11 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) { } // Otherwise, free the old resource - resmgr->unlockResource(_currentResource, _module, kResourceTypeMessage); + resmgr->unlockResource(_currentResource); _locked = false; } - _currentResource = resmgr->findResource(kResourceTypeMessage, module, lock); + _currentResource = resmgr->findResource(ResourceId(kResourceTypeMessage, module), lock); if (_currentResource == NULL || _currentResource->data == NULL) { warning("Message: failed to load %d.msg", module); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 8e3b8a5304..b04e5b144a 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -544,9 +544,9 @@ static void load_script(EngineState *s, SegmentId seg) { scr->buf = (byte *)malloc(scr->buf_size); assert(scr->buf); - script = s->resmgr->findResource(kResourceTypeScript, scr->nr, 0); + script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scr->nr), 0); if (s->_version >= SCI_VERSION_1_1) - heap = s->resmgr->findResource(kResourceTypeHeap, scr->nr, 0); + heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, scr->nr), 0); memcpy(scr->buf, script->data, script->size); if (s->seg_manager->isSci1_1) diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 74bbaa8854..a0bfdeddc9 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -295,7 +295,7 @@ void Kernel::dumpScriptClass(char *data, int seeker, int objsize) { void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) { int objectctr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned int _seeker = 0; - Resource *script = _resmgr->findResource(kResourceTypeScript, scriptNumber, 0); + Resource *script = _resmgr->findResource(ResourceId(kResourceTypeScript, scriptNumber), 0); if (!script) { sciprintf("Script not found!\n"); diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index dcf7180501..98fbd8bad7 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -129,8 +129,8 @@ Script *SegManager::allocateScript(EngineState *s, int script_nr, SegmentId *seg } void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) { - Resource *script = s->resmgr->findResource(kResourceTypeScript, script_nr, 0); - Resource *heap = s->resmgr->findResource(kResourceTypeHeap, script_nr, 0); + Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0); + Resource *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); scr.script_size = script->size; scr.heap_size = 0; // Set later diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index b01e5054af..f788629892 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1609,9 +1609,9 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script, *was_new = 1; - *script = s->resmgr->findResource(kResourceTypeScript, script_nr, 0); + *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0); if (s->_version >= SCI_VERSION_1_1) - *heap = s->resmgr->findResource(kResourceTypeHeap, script_nr, 0); + *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); if (!*script || (s->_version >= SCI_VERSION_1_1 && !heap)) { sciprintf("Script 0x%x requested but not found\n", script_nr); diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index 19c3455366..521eda091b 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -65,7 +65,7 @@ GfxResManager::GfxResManager(int version, bool isVGA, gfx_options_t *options, Gf GFXDEBUG("Palettes are not yet supported in this SCI version\n"); #endif } else { - Resource *res = resManager->findResource(kResourceTypePalette, 999, 0); + Resource *res = resManager->findResource(ResourceId(kResourceTypePalette, 999), 0); if (res && res->data) _staticPalette = gfxr_read_pal1(res->id.number, res->data, res->size); } @@ -77,7 +77,7 @@ GfxResManager::~GfxResManager() { } int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr) { - Resource *res = _resManager->findResource(kResourceTypePic, nr, 0); + Resource *res = _resManager->findResource(ResourceId(kResourceTypePic, nr), 0); int need_unscaled = unscaled_pic != NULL; gfxr_pic0_params_t style, basic_style; @@ -524,7 +524,7 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { res = resMap.contains(nr) ? resMap[nr] : NULL; if (!res || res->mode != hash) { - Resource *viewRes = _resManager->findResource(kResourceTypeView, nr, 0); + Resource *viewRes = _resManager->findResource(ResourceId(kResourceTypeView, nr), 0); if (!viewRes || !viewRes->data) return NULL; @@ -621,7 +621,7 @@ gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) { res = resMap.contains(num) ? resMap[num] : NULL; if (!res || res->mode != hash) { - Resource *fontRes = _resManager->findResource(kResourceTypeFont, num, 0); + Resource *fontRes = _resManager->findResource(ResourceId(kResourceTypeFont, num), 0); if (!fontRes || !fontRes->data) return NULL; @@ -658,7 +658,7 @@ gfx_pixmap_t *GfxResManager::getCursor(int num) { res = resMap.contains(num) ? resMap[num] : NULL; if (!res || res->mode != hash) { - Resource *cursorRes = _resManager->findResource(kResourceTypeCursor, num, 0); + Resource *cursorRes = _resManager->findResource(ResourceId(kResourceTypeCursor, num), 0); if (!cursorRes || !cursorRes->data) return NULL; diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index d4923306eb..b7d70db04a 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -94,7 +94,10 @@ static const char *resourceTypeSuffixes[] = { }; const char *getResourceTypeName(ResourceType restype) { - return resourceTypeNames[restype]; + if (restype != kResourceTypeInvalid) + return resourceTypeNames[restype]; + else + return "invalid"; } //-- Resource main functions -- @@ -236,8 +239,9 @@ bool ResourceManager::loadFromAudioVolume(Resource *res) { file.seek(res->file_offset, SEEK_SET); - int type = file.readByte() & 0x7f; - if (type != res->id.type) { + ResourceType type = (ResourceType)(file.readByte() & 0x7f); + if (((res->id.type == kResourceTypeAudio || res->id.type == kResourceTypeAudio36) && (type != kResourceTypeAudio)) + || ((res->id.type == kResourceTypeSync || res->id.type == kResourceTypeSync36) && (type != kResourceTypeSync))) { warning("Resource type mismatch loading %s from %s", res->id.toString().c_str(), filename); res->unalloc(); return false; @@ -298,8 +302,10 @@ void ResourceManager::loadResource(Resource *res) { if (res->source->source_type == kSourcePatch && loadFromPatchFile(res)) return; - if (res->source->source_type == kSourceAudioVolume && loadFromAudioVolume(res)) + if (res->source->source_type == kSourceAudioVolume) { + loadFromAudioVolume(res); return; + } // Either loading from volume or patch loading failed file = getVolumeFile(res->source->location_name.c_str()); if (!file) { @@ -317,9 +323,9 @@ void ResourceManager::loadResource(Resource *res) { } -Resource *ResourceManager::testResource(ResourceType type, int number) { - if (_resMap.contains(ResourceId(type, number))) - return _resMap.getVal(ResourceId(type, number)); +Resource *ResourceManager::testResource(ResourceId id) { + if (_resMap.contains(id)) + return _resMap.getVal(id); return NULL; } @@ -344,7 +350,7 @@ int ResourceManager::guessSciVersion() { int i; for (i = 0; i < 1000; i++) { - res = testResource(kResourceTypeView, i); + res = testResource(ResourceId(kResourceTypeView, i)); if (!res) continue; @@ -368,7 +374,7 @@ int ResourceManager::guessSciVersion() { // Try the same thing with pics for (i = 0; i < 1000; i++) { - res = testResource(kResourceTypePic, i); + res = testResource(ResourceId(kResourceTypePic, i)); if (!res) continue; @@ -418,13 +424,18 @@ int ResourceManager::addAppropriateSources() { } int ResourceManager::addInternalSources() { - if (testResource(kResourceTypeMap, 65535)) { - ResourceSource *src = addSource(NULL, kSourceIntMap, "65535.MAP", 65535); + Common::List<ResourceId> *resources = listResources(kResourceTypeMap); + Common::List<ResourceId>::iterator itr = resources->begin(); - if (Common::File::exists("RESOURCE.SFX")) + while (itr != resources->end()) { + ResourceSource *src = addSource(NULL, kSourceIntMap, "MAP", itr->number); + + if ((itr->number == 65535) && Common::File::exists("RESOURCE.SFX")) addSource(src, kSourceAudioVolume, "RESOURCE.SFX", 0); else if (Common::File::exists("RESOURCE.AUD")) addSource(src, kSourceAudioVolume, "RESOURCE.AUD", 0); + + itr++; } return 1; @@ -462,8 +473,7 @@ int ResourceManager::scanNewSources(ResourceSource *source) { } break; case kSourceIntMap: - if (source->volume_number == 65535) - resource_error = readMap65535(source); + resource_error = readMap(source); break; default: break; @@ -507,12 +517,12 @@ ResourceManager::ResourceManager(int version, int maxMemory) { if (version == SCI_VERSION_AUTODETECT) switch (_mapVersion) { case SCI_VERSION_0: - if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB)) { + if (testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB))) { version = guessSciVersion() ? SCI_VERSION_01_VGA : SCI_VERSION_0; - } else if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB)) { + } else if (testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB))) { version = guessSciVersion(); if (version != SCI_VERSION_01_VGA) { - version = testResource(kResourceTypeVocab, 912) ? SCI_VERSION_0 : SCI_VERSION_01; + version = testResource(ResourceId(kResourceTypeVocab, 912)) ? SCI_VERSION_0 : SCI_VERSION_01; } } else { version = guessSciVersion() ? SCI_VERSION_01_VGA : SCI_VERSION_0; @@ -522,7 +532,7 @@ ResourceManager::ResourceManager(int version, int maxMemory) { version = _mapVersion; break; case SCI_VERSION_1: { - Resource *res = testResource(kResourceTypeScript, 0); + Resource *res = testResource(ResourceId(kResourceTypeScript, 0)); _sciVersion = version = SCI_VERSION_1_EARLY; loadResource(res); @@ -651,17 +661,30 @@ void ResourceManager::freeOldResources(int last_invulnerable) { } } -Resource *ResourceManager::findResource(ResourceType type, int number, bool lock) { +Common::List<ResourceId> *ResourceManager::listResources(ResourceType type, int mapNumber) { + Common::List<ResourceId> *resources = new Common::List<ResourceId>; + + ResourceMap::iterator itr = _resMap.begin(); + while (itr != _resMap.end()) { + if ((itr->_value->id.type == type) && ((mapNumber == -1) || (itr->_value->id.number == mapNumber))) + resources->push_back(itr->_value->id); + itr++; + } + + return resources; +} + +Resource *ResourceManager::findResource(ResourceId id, bool lock) { Resource *retval; - if (number >= sci_max_resource_nr[_sciVersion]) { - int modded_number = number % sci_max_resource_nr[_sciVersion]; - sciprintf("[resmgr] Requested invalid resource %s.%d, mapped to %s.%d\n", - getResourceTypeName(type), number, getResourceTypeName(type), modded_number); - number = modded_number; + if (id.number >= sci_max_resource_nr[_sciVersion]) { + ResourceId moddedId = ResourceId(id.type, id.number % sci_max_resource_nr[_sciVersion], id.tuple); + sciprintf("[resmgr] Requested invalid resource %s, mapped to %s\n", + id.toString().c_str(), moddedId.toString().c_str()); + id = moddedId; } - retval = testResource(type, number); + retval = testResource(id); if (!retval) return NULL; @@ -695,17 +718,11 @@ Resource *ResourceManager::findResource(ResourceType type, int number, bool lock } } -void ResourceManager::unlockResource(Resource *res, int resnum, ResourceType restype) { - if (!res) { - if (restype == kResourceTypeInvalid) - sciprintf("Resmgr: Warning: Attempt to unlock non-existant resource %03d.%03d!\n", restype, resnum); - else - sciprintf("Resmgr: Warning: Attempt to unlock non-existant resource %s.%03d!\n", getResourceTypeName(restype), resnum); - return; - } +void ResourceManager::unlockResource(Resource *res) { + assert(res); if (res->status != kResStatusLocked) { - sciprintf("Resmgr: Warning: Attempt to unlock unlocked resource %s\n", res->id.toString().c_str()); + warning("[Resmgr] Attempt to unlock unlocked resource %s", res->id.toString().c_str()); return; } @@ -1080,65 +1097,136 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { return 0; } -int ResourceManager::readMap65535(ResourceSource *map) { - // Early SCI1.1 65535.MAP structure (uses RESOURCE.AUD): - // ========= - // 6-byte entries: - // w nEntry - // dw offset - - // Late SCI1.1 65535.MAP structure (uses RESOURCE.SFX): - // ========= - // 5-byte entries: - // w nEntry - // tb offset (cumulative) +void ResourceManager::addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size) { + // Adding new resource only if it does not exist + if (_resMap.contains(resId) == false) { + Resource *res; + if ((resId.type == kResourceTypeSync) || (resId.type == kResourceTypeSync36)) + res = new ResourceSync; + else + res = new Resource; + _resMap.setVal(resId, res); + res->id = resId; + res->source = src; + res->file_offset = offset; + res->size = size; + } +} - Resource *mapRes = findResource(kResourceTypeMap, map->volume_number, false); +// Early SCI1.1 65535.MAP structure (uses RESOURCE.AUD): +// ========= +// 6-byte entries: +// w nEntry +// dw offset + +// Late SCI1.1 65535.MAP structure (uses RESOURCE.SFX): +// ========= +// 5-byte entries: +// w nEntry +// tb offset (cumulative) + +// Early SCI1.1 MAP structure: +// =============== +// 10-byte entries: +// b noun +// b verb +// b cond +// b seq +// dw offset +// w syncSize + syncAscSize + +// Late SCI1.1 MAP structure: +// =============== +// Header: +// dw baseOffset +// Followed by 7 or 11-byte entries: +// b noun +// b verb +// b cond +// b seq +// tb cOffset (cumulative offset) +// w syncSize (iff seq has bit 7 set) +// w syncAscSize (iff seq has bit 6 set) + +int ResourceManager::readMap(ResourceSource *map) { + bool isEarly = true; + uint32 offset = 0; + Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->volume_number), false); if (!mapRes) { - warning("Failed to open 65535.MAP"); + warning("Failed to open %i.MAP", map->volume_number); return SCI_ERROR_RESMAP_NOT_FOUND; } ResourceSource *src = getVolume(map, 0); - if (!src) { - warning("No audio resource files found"); + if (!src) return SCI_ERROR_NO_RESOURCE_FILES_FOUND; - } - - bool isEarly = true; byte *ptr = mapRes->data; - // Heuristic to detect late SCI1.1 map format - if ((mapRes->size >= 6) && (ptr[mapRes->size - 6] != 0xff)) - isEarly = false; - uint32 offset = 0; + if (map->volume_number == 65535) { + // Heuristic to detect late SCI1.1 map format + if ((mapRes->size >= 6) && (ptr[mapRes->size - 6] != 0xff)) + isEarly = false; + + while (ptr < mapRes->data + mapRes->size) { + uint16 n = READ_LE_UINT16(ptr); + ptr += 2; - while (ptr < mapRes->data + mapRes->size) { - uint16 n = READ_LE_UINT16(ptr); - ptr += 2; + if (n == 0xffff) + break; - if (n == 0xffff) - break; + if (isEarly) { + offset = READ_LE_UINT32(ptr); + ptr += 4; + } else { + offset += READ_LE_UINT24(ptr); + ptr += 3; + } + + addResource(ResourceId(kResourceTypeAudio, n), src, offset); + } + } else { + // Heuristic to detect late SCI1.1 map format + if ((mapRes->size >= 11) && (ptr[mapRes->size - 11] == 0xff)) + isEarly = false; - if (isEarly) { + if (!isEarly) { offset = READ_LE_UINT32(ptr); ptr += 4; - } else { - offset += READ_LE_UINT24(ptr); - ptr += 3; } - ResourceId resId = ResourceId(kResourceTypeAudio, n); - // Adding new resource only if it does not exist - if (_resMap.contains(resId) == false) { - Resource *res = new Resource; - _resMap.setVal(resId, res); - res->id = resId; - res->source = src; - res->file_offset = offset; + while (ptr < mapRes->data + mapRes->size) { + uint32 n = READ_BE_UINT32(ptr); + int syncSize = 0; + ptr += 4; + + if (n == 0xffffffff) + break; + + if (isEarly) { + offset = READ_LE_UINT32(ptr); + ptr += 4; + } else { + offset += READ_LE_UINT24(ptr); + ptr += 3; + } + + if (isEarly || (n & 0x80)) { + syncSize = READ_LE_UINT16(ptr); + ptr += 2; + + if (syncSize > 0) + addResource(ResourceId(kResourceTypeSync36, map->volume_number, n & 0xffffff3f), src, offset, syncSize); + } + + if (n & 0x40) { + syncSize += READ_LE_UINT16(ptr); + ptr += 2; + } + + addResource(ResourceId(kResourceTypeAudio36, map->volume_number, n & 0xffffff3f), src, offset + syncSize); } } @@ -1321,7 +1409,7 @@ AudioResource::~AudioResource() { } } else { if (_audioMapSCI11) - _resMgr->unlockResource(_audioMapSCI11, _audioMapSCI11->id.number, kResourceTypeMap); + _resMgr->unlockResource(_audioMapSCI11); } } @@ -1381,151 +1469,6 @@ bool AudioResource::findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &o return false; } -bool AudioResource::findAudEntrySCI11Late(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size) { - // Map structure: - // =============== - // Header: - // dw baseOffset - // Followed by 7 or 11-byte entries: - // b noun - // b verb - // b cond - // b seq - // tb cOffset (cumulative offset) - // w syncSize (iff seq has bit 7 set) - // w syncAscSize (iff seq has bit 6 set) - - uint32 n; - offset = 0; - - byte *ptr = _audioMapSCI11->data; - - offset = READ_LE_UINT32(ptr); - ptr += 4; - - while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) { - n = READ_BE_UINT32(ptr); - ptr += 4; - - if (n == 0xffffffff) - break; - - offset += READ_LE_UINT24(ptr); - ptr += 3; - - int syncSkip = 0; - - if (n & 0x80) { - n ^= 0x80; - - if (getSync) { - if (size) - *size = READ_LE_UINT16(ptr); - } else { - syncSkip = READ_LE_UINT16(ptr); - } - - ptr += 2; - - if (n & 0x40) { - n ^= 0x40; - - if (!getSync) - syncSkip += READ_LE_UINT16(ptr); - - ptr += 2; - } - - offset += syncSkip; - - if (n == audioNumber) - return true; - - } else { - if (n == audioNumber) - return !getSync; - } - - offset -= syncSkip; - } - - return false; -} - -bool AudioResource::findAudEntrySCI11Early(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size) { - // Map structure: - // =============== - // 10-byte entries: - // b noun - // b verb - // b cond - // b seq - // dw offset - // w syncSize + syncAscSize - - uint32 n; - offset = 0; - - byte *ptr = _audioMapSCI11->data; - - while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) { - n = READ_BE_UINT32(ptr); - ptr += 4; - - if (n == 0xffffffff) - break; - - offset = READ_LE_UINT32(ptr); - ptr += 4; - - int syncSize = READ_LE_UINT16(ptr); - ptr += 2; - - if (n == audioNumber) { - if (getSync) { - if (size) - *size = syncSize; - return true; - } else { - offset += syncSize; - return true; - } - } - } - - return false; -} - -bool AudioResource::findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync, uint32 *size) { - if (_audioMapSCI11 && _audioMapSCI11->id.number != volume) { - _resMgr->unlockResource(_audioMapSCI11, _audioMapSCI11->id.number, kResourceTypeMap); - _audioMapSCI11 = 0; - } - - if (!_audioMapSCI11) { - _audioMapSCI11 = _resMgr->findResource(kResourceTypeMap, volume, 1); - } - - byte *ptr = _audioMapSCI11->data; - - if (volume == 65535) - return false; - - // In early SCI1.1 the map is terminated with 10x 0xff, in late SCI1.1 - // with 11x 0xff. If we look at the 11th last byte in an early SCI1.1 - // map, this will be the high byte of the Sync length of the last entry. - // As Sync resources are relative small, we should never encounter a - // Sync with a size of 0xffnn. As such, the following heuristic should be - // sufficient to tell these map formats apart. - if (_audioMapSCI11->size >= 11 && (ptr[_audioMapSCI11->size - 11] == 0xff)) - return findAudEntrySCI11Late(audioNumber, offset, getSync, size); - else { - return findAudEntrySCI11Early(audioNumber, offset, getSync, size); - } - - return false; -} - // FIXME: Move this to sound/adpcm.cpp? // Note that the 16-bit version is also used in coktelvideo.cpp static const uint16 tableDPCM16[128] = { @@ -1638,7 +1581,9 @@ Audio::AudioStream* AudioResource::getAudioStream(uint32 audioNumber, uint32 vol // Try to load from resource manager if (volume == 65535) - audioRes = _resMgr->findResource(kResourceTypeAudio, audioNumber, false); + audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio, audioNumber), false); + else + audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio36, volume, audioNumber), false); if (audioRes) { if (_sciVersion < SCI_VERSION_1_1) { @@ -1670,9 +1615,6 @@ Audio::AudioStream* AudioResource::getAudioStream(uint32 audioNumber, uint32 vol found = findAudEntrySCI1(audioNumber, sci1Volume, offset, size); sprintf(filename, "AUDIO%03d.%03d", _lang, sci1Volume); flags |= Audio::Mixer::FLAG_UNSIGNED; - } else { - found = findAudEntrySCI11(audioNumber, volume, offset); - strcpy(filename, "RESOURCE.AUD"); } if (found) { diff --git a/engines/sci/resource.h b/engines/sci/resource.h index 211e160144..172817912e 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -148,7 +148,18 @@ public: uint32 tuple; // Only used for audio36 and sync36 ResourceId() : type(kResourceTypeInvalid), number(0), tuple(0) { }; - ResourceId(ResourceType type_, uint16 number_, uint32 tuple_ = 0) : type(type_), number(number_), tuple(tuple_) { } + + ResourceId(ResourceType type_, uint16 number_, uint32 tuple_ = 0) : type(type_), number(number_), tuple(tuple_) { + if ((type < kResourceTypeView) || (type > kResourceTypeInvalid)) + type = kResourceTypeInvalid; + } + + ResourceId(ResourceType type_, uint16 number_, byte noun, byte verb, byte cond, byte seq) : type(type_), number(number_) { + tuple = (noun << 24) | (verb << 16) | (cond << 8) | seq; + + if ((type < kResourceTypeView) || (type > kResourceTypeInvalid)) + type = kResourceTypeInvalid; + } Common::String toString() { char buf[32]; @@ -173,6 +184,13 @@ struct ResourceIdEqualTo : public Common::BinaryFunction<ResourceId, ResourceId, bool operator()(const ResourceId &x, const ResourceId &y) const { return (x.type == y.type) && (x.number == y.number) && (x.tuple == y.tuple); } }; +struct ResourceIdLess : public Common::BinaryFunction<ResourceId, ResourceId, bool> { + bool operator()(const ResourceId &x, const ResourceId &y) const { + return (x.type < y.type) || ((x.type == y.type) && (x.number < y.number)) + || ((x.type == y.type) && (x.number == y.number) && (x.tuple < y.tuple)); + } +}; + /** Class for storing resources in memory */ class Resource { friend class ResourceManager; @@ -219,26 +237,22 @@ public: /** * Looks up a resource's data. - * @param type: The resource type to look for - * @param number: The resource number to search + * @param id: The resource type to look for * @param lock: non-zero iff the resource should be locked * @return (Resource *): The resource, or NULL if it doesn't exist * @note Locked resources are guaranteed not to have their contents freed until * they are unlocked explicitly (by unlockResource). */ - Resource *findResource(ResourceType type, int number, bool lock); + Resource *findResource(ResourceId id, bool lock); /* Unlocks a previously locked resource ** (Resource *) res: The resource to free - ** (int) number: Number of the resource to check (ditto) - ** (ResourceType) type: Type of the resource to check (for error checking) ** Returns : (void) */ - void unlockResource(Resource *res, int restype, ResourceType resnum); + void unlockResource(Resource *res); /* Tests whether a resource exists - ** (ResourceType) type: Type of the resource to check - ** (int) number: Number of the resource to check + ** (ResourceId) id: Id of the resource to check ** Returns : (Resource *) non-NULL if the resource exists, NULL otherwise ** This function may often be much faster than finding the resource ** and should be preferred for simple tests. @@ -246,7 +260,15 @@ public: ** it should be used with care, as it may be unallocated. ** Use scir_find_resource() if you want to use the data contained in the resource. */ - Resource *testResource(ResourceType type, int number); + Resource *testResource(ResourceId id); + + /** + * Returns a list of all resources of the specified type. + * @param type: The resource type to look for + * @param mapNumber: For audio36 and sync36, limit search to this map + * @return: The resource list + */ + Common::List<ResourceId> *listResources(ResourceType type, int mapNumber = -1); protected: int _maxMemory; //!< Config option: Maximum total byte number allocated @@ -307,6 +329,7 @@ protected: void freeOldResources(int last_invulnerable); int decompress(Resource *res, Common::File *file); int readResourceInfo(Resource *res, Common::File *file, uint32&szPacked, ResourceCompression &compression); + void addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size = 0); /**--- Resource map decoding functions ---*/ int detectMapVersion(); @@ -325,10 +348,10 @@ protected: int readResourceMapSCI1(ResourceSource *map); /** - * Reads the SCI1.1 65535.map resource + * Reads SCI1.1 MAP resources * @return 0 on success, an SCI_ERROR_* code otherwise */ - int readMap65535(ResourceSource *map); + int readMap(ResourceSource *map); /**--- Patch management functions ---*/ diff --git a/engines/sci/sfx/softseq/adlib.cpp b/engines/sci/sfx/softseq/adlib.cpp index d5debdd995..0bb13e120c 100644 --- a/engines/sci/sfx/softseq/adlib.cpp +++ b/engines/sci/sfx/softseq/adlib.cpp @@ -627,7 +627,7 @@ int MidiPlayer_Adlib::open(ResourceManager *resmgr) { assert(resmgr != NULL); // Load up the patch.003 file, parse out the instruments - Resource *res = resmgr->findResource(kResourceTypePatch, 3, 0); + Resource *res = resmgr->findResource(ResourceId(kResourceTypePatch, 3), 0); if (!res) { warning("ADLIB: Failed to load patch.003"); diff --git a/engines/sci/vocabulary.cpp b/engines/sci/vocabulary.cpp index 40b5be3da9..c877053060 100644 --- a/engines/sci/vocabulary.cpp +++ b/engines/sci/vocabulary.cpp @@ -62,7 +62,7 @@ int *vocab_get_classes(ResourceManager *resmgr, int* count) { int *c; unsigned int i; - if ((r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES, 0)) == NULL) + if ((r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES), 0)) == NULL) return 0; c = (int *)malloc(sizeof(int) * r->size / 2); @@ -77,7 +77,7 @@ int *vocab_get_classes(ResourceManager *resmgr, int* count) { int vocab_get_class_count(ResourceManager *resmgr) { Resource* r; - if ((r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES, 0)) == 0) + if ((r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES), 0)) == 0) return 0; return r->size / 4; @@ -115,11 +115,11 @@ bool Vocabulary::loadParserWords() { int currentwordpos = 0; // First try to load the SCI0 vocab resource. - Resource *resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB, 0); + Resource *resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB), 0); if (!resource) { warning("SCI0: Could not find a main vocabulary, trying SCI01"); - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB), 0); _vocabVersion = kVocabularySCI1; } @@ -198,9 +198,9 @@ bool Vocabulary::loadSuffixes() { Resource* resource = NULL; if (_vocabVersion == kVocabularySCI0) - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB, 1); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB), 1); else - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB, 1); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB), 1); if (!resource) return false; // No vocabulary found @@ -237,12 +237,12 @@ void Vocabulary::freeSuffixes() { Resource* resource = NULL; if (_vocabVersion == kVocabularySCI0) - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB), 0); else - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB), 0); if (resource) - _resmgr->unlockResource(resource, resource->id.number, kResourceTypeVocab); + _resmgr->unlockResource(resource); _parserSuffixes.clear(); } @@ -251,9 +251,9 @@ bool Vocabulary::loadBranches() { Resource *resource = NULL; if (_vocabVersion == kVocabularySCI0) - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES), 0); else - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES), 0); _parserBranches.clear(); |