aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2009-06-07 19:15:55 +0000
committerWalter van Niftrik2009-06-07 19:15:55 +0000
commita6ed05740f1f46639f38ccf0afb9c444564cc84f (patch)
tree310b79a435f54f2d8e22555234ccb33f62848969
parent4dd29a5985a4190f99446865209850a40f12e2e4 (diff)
downloadscummvm-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.cpp48
-rw-r--r--engines/sci/engine/game.cpp18
-rw-r--r--engines/sci/engine/kernel.cpp8
-rw-r--r--engines/sci/engine/kscripts.cpp49
-rw-r--r--engines/sci/engine/ksound.cpp57
-rw-r--r--engines/sci/engine/kstring.cpp4
-rw-r--r--engines/sci/engine/message.cpp4
-rw-r--r--engines/sci/engine/savegame.cpp4
-rw-r--r--engines/sci/engine/script.cpp2
-rw-r--r--engines/sci/engine/seg_manager.cpp4
-rw-r--r--engines/sci/engine/vm.cpp4
-rw-r--r--engines/sci/gfx/gfx_resmgr.cpp10
-rw-r--r--engines/sci/resource.cpp390
-rw-r--r--engines/sci/resource.h47
-rw-r--r--engines/sci/sfx/softseq/adlib.cpp2
-rw-r--r--engines/sci/vocabulary.cpp22
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();