aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorMax Horn2009-10-04 18:36:58 +0000
committerMax Horn2009-10-04 18:36:58 +0000
commit0da9ad5ff59e910c91becf1ba62ee5e864d25c32 (patch)
tree0e4aaec84aa8940782d99c92032b851fcbc17c48 /engines/sci/engine
parent07353be65a030261f673d1816d01f08bd35c7b90 (diff)
downloadscummvm-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.cpp9
-rw-r--r--engines/sci/engine/seg_manager.cpp77
-rw-r--r--engines/sci/engine/seg_manager.h13
-rw-r--r--engines/sci/engine/state.cpp9
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;