diff options
author | Max Horn | 2009-10-04 18:36:58 +0000 |
---|---|---|
committer | Max Horn | 2009-10-04 18:36:58 +0000 |
commit | 0da9ad5ff59e910c91becf1ba62ee5e864d25c32 (patch) | |
tree | 0e4aaec84aa8940782d99c92032b851fcbc17c48 /engines/sci/engine | |
parent | 07353be65a030261f673d1816d01f08bd35c7b90 (diff) | |
download | scummvm-rg350-0da9ad5ff59e910c91becf1ba62ee5e864d25c32.tar.gz scummvm-rg350-0da9ad5ff59e910c91becf1ba62ee5e864d25c32.tar.bz2 scummvm-rg350-0da9ad5ff59e910c91becf1ba62ee5e864d25c32.zip |
SCI: Add SegManager::findObjectByName() method, make parse_reg_t() local to console.cpp, and switch other code using it to use findObjectByName() instead.
svn-id: r44628
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/kmovement.cpp | 9 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 77 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 13 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 9 |
4 files changed, 97 insertions, 11 deletions
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp index 3a21704469..43cba3eb4d 100644 --- a/engines/sci/engine/kmovement.cpp +++ b/engines/sci/engine/kmovement.cpp @@ -24,7 +24,6 @@ */ #include "sci/sci.h" -#include "sci/console.h" // for parse_reg_t #include "sci/resource.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" @@ -256,10 +255,10 @@ static int checksum_bytes(byte *data, int size) { } static void bresenham_autodetect(EngineState *s) { - reg_t motion_class; + reg_t motionClass = s->segMan->findObjectByName("Motion"); - if (!parse_reg_t(s, "?Motion", &motion_class)) { - Object *obj = s->segMan->getObject(motion_class); + if (!motionClass.isNull()) { + Object *obj = s->segMan->getObject(motionClass); reg_t fptr; byte *buf; @@ -269,7 +268,7 @@ static void bresenham_autodetect(EngineState *s) { return; } - if (lookup_selector(s->segMan, motion_class, s->_kernel->_selectorCache.doit, NULL, &fptr) != kSelectorMethod) { + if (lookup_selector(s->segMan, motionClass, s->_kernel->_selectorCache.doit, NULL, &fptr) != kSelectorMethod) { warning("bresenham_autodetect failed"); handle_movecnt = INCREMENT_MOVECNT; // Most games do this, so best guess return; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 43c48e3988..b8412da8fb 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -272,6 +272,81 @@ const char *SegManager::getObjectName(reg_t pos) { return name; } +reg_t SegManager::findObjectByName(const Common::String &name, int index) { + reg_t retVal = NULL_REG; + + // Now all values are available; iterate over all objects. + int timesFound = 0; + for (uint i = 0; i < _heap.size(); i++) { + SegmentObj *mobj = _heap[i]; + int idx = 0; + int max_index = 0; + ObjMap::iterator it; + Script *scr = 0; + CloneTable *ct = 0; + + if (mobj) { + if (mobj->getType() == SEG_TYPE_SCRIPT) { + scr = (Script *)mobj; + max_index = scr->_objects.size(); + it = scr->_objects.begin(); + } else if (mobj->getType() == SEG_TYPE_CLONES) { + ct = (CloneTable *)mobj; + max_index = ct->_table.size(); + } + } + + // It's a script or a clone table, scan all objects in it + for (; idx < max_index; ++idx) { + Object *obj = NULL; + reg_t objpos; + objpos.offset = 0; + objpos.segment = i; + + if (mobj->getType() == SEG_TYPE_SCRIPT) { + obj = &(it->_value); + objpos.offset = obj->_pos.offset; + ++it; + } else if (mobj->getType() == SEG_TYPE_CLONES) { + if (!ct->isValidEntry(idx)) + continue; + obj = &(ct->_table[idx]); + objpos.offset = idx; + } + + const char *objname = getObjectName(objpos); + if (name == objname) { + // Found a match! + if ((index < 0) && (timesFound > 0)) { + if (timesFound == 1) { + // First time we realized the ambiguity + printf("Ambiguous:\n"); + printf(" %3x: [%04x:%04x] %s\n", 0, PRINT_REG(retVal), name.c_str()); + } + printf(" %3x: [%04x:%04x] %s\n", timesFound, PRINT_REG(objpos), name.c_str()); + } + if (index < 0 || timesFound == index) + retVal = objpos; + ++timesFound; + } + } + + } + + if (!timesFound) + return NULL_REG; + + if (timesFound > 1 && index < 0) { + printf("Ambiguous: Aborting.\n"); + return NULL_REG; // Ambiguous + } + + if (timesFound <= index) + return NULL_REG; // Not found + + return retVal; +} + // validate the seg // return: // false - invalid seg @@ -623,7 +698,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { #if 0 if (obj->_variables[5].offset != 0xffff) { obj->_variables[5] = INST_LOOKUP_CLASS(obj->_variables[5].offset); - base_obj = s->segMan->getObject(obj->_variables[5]); + base_obj = getObject(obj->_variables[5]); obj->variable_names_nr = base_obj->variables_nr; obj->base_obj = base_obj->base_obj; } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index c8b99764bf..6226d1ce76 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -419,6 +419,19 @@ public: */ const char *getObjectName(reg_t pos); + /** + * Find the address of an object by its name. In case multiple objects + * with the same name occur, the optional index parameter can be used + * to distinguish between them. If index is -1, then if there is a + * unique object with the specified name, its address is returned; + * if there are multiple matches, or none, then NULL_REG is returned. + * + * @param name the name of the object we are looking for + * @param index the index of the object in case there are multiple + * @return the address of the object, or NULL_REG + */ + reg_t findObjectByName(const Common::String &name, int index = -1); + void scriptRelocateExportsSci11(SegmentId seg); void scriptInitialiseObjectsSci11(SegmentId seg); diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index effaac0ca5..d9671239dc 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -26,7 +26,6 @@ #include "sci/engine/state.h" #include "sci/engine/vm.h" #include "sci/engine/script.h" -#include "sci/console.h" // For parse_reg_t namespace Sci { @@ -266,9 +265,9 @@ int EngineState::methodChecksum(reg_t objAddress, Selector sel, int offset, uint SciVersion EngineState::detectDoSoundType() { if (_doSoundType == SCI_VERSION_AUTODETECT) { - reg_t soundClass; + reg_t soundClass = segMan->findObjectByName("Sound"); - if (!parse_reg_t(this, "?Sound", &soundClass)) { + if (!soundClass.isNull()) { int sum = methodChecksum(soundClass, _kernel->_selectorCache.play, -6, 6); switch (sum) { @@ -337,10 +336,10 @@ SciVersion EngineState::detectLofsType() { return _lofsType; } - reg_t gameClass; Object *obj = NULL; + reg_t gameClass = segMan->findObjectByName("Game"); - if (!parse_reg_t(this, "?Game", &gameClass)) + if (!gameClass.isNull()) obj = segMan->getObject(gameClass); bool couldBeAbs = true; |