aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorFilippos Karapetis2010-06-10 09:22:30 +0000
committerFilippos Karapetis2010-06-10 09:22:30 +0000
commitcc6f5eb3e42bb4f7af47a70802a236fdbffc7b74 (patch)
tree7ee38a9ecb2c85f75ae8ea24d143a1d159fa6573 /engines/sci
parenteb4ec596cdb8e541d5221263b3db185bd01b206f (diff)
downloadscummvm-rg350-cc6f5eb3e42bb4f7af47a70802a236fdbffc7b74.tar.gz
scummvm-rg350-cc6f5eb3e42bb4f7af47a70802a236fdbffc7b74.tar.bz2
scummvm-rg350-cc6f5eb3e42bb4f7af47a70802a236fdbffc7b74.zip
Unified invokeSelector() and invokeSelectorArgv(), and removed the INV_SEL kludge. Also, removed the selectorInvocation parameter - if invokeSelector() fails, the error is in most cases unrecoverable, and the error description thrown covers all cases where kContinueOnInvalidSelector was used. This uncovered a bug too: in some places, non reg_t parameters were parsed
svn-id: r49564
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/klists.cpp9
-rw-r--r--engines/sci/engine/kmovement.cpp34
-rw-r--r--engines/sci/engine/kparse.cpp6
-rw-r--r--engines/sci/engine/selector.cpp26
-rw-r--r--engines/sci/engine/selector.h19
5 files changed, 23 insertions, 71 deletions
diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp
index f06f3eec77..18d6638e92 100644
--- a/engines/sci/engine/klists.cpp
+++ b/engines/sci/engine/klists.cpp
@@ -424,7 +424,8 @@ reg_t kSort(EngineState *s, int argc, reg_t *argv) {
i = 0;
while (node) {
- invokeSelector(INV_SEL(s, order_func, doit, kStopOnInvalidSelector), 1, node->value);
+ reg_t params[1] = { node->value };
+ invokeSelector(s, order_func, SELECTOR(doit), argc, argv, 1, params);
temp_array[i].key = node->key;
temp_array[i].value = node->value;
temp_array[i].order = s->r_acc;
@@ -523,7 +524,7 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) {
writeSelector(s->_segMan, curObject, slc, argv[2]);
}
} else {
- invokeSelectorArgv(s, curObject, slc, kContinueOnInvalidSelector, argc, argv, argc - 2, argv + 2);
+ invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2);
}
curNode = s->_segMan->lookupNode(nextNode);
@@ -552,7 +553,7 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) {
// Can this happen with variable selectors?
warning("kListFirstTrue: Attempted to access a variable selector");
} else {
- invokeSelectorArgv(s, curObject, slc, kContinueOnInvalidSelector, argc, argv, argc - 2, argv + 2);
+ invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2);
// Check if the result is true
if (!s->r_acc.isNull())
@@ -586,7 +587,7 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) {
// Can this happen with variable selectors?
warning("kListAllTrue: Attempted to access a variable selector");
} else {
- invokeSelectorArgv(s, curObject, slc, kContinueOnInvalidSelector, argc, argv, argc - 2, argv + 2);
+ invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2);
// Check if the result isn't true
if (s->r_acc.isNull())
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index 499aeabcc6..e45e55373b 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -315,11 +315,11 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
debugC(2, kDebugLevelBresen, "New data: (x,y)=(%d,%d), di=%d", x, y, bdi);
- if (g_sci->getKernel()->_selectorCache.cantBeHere != -1) {
- invokeSelector(INV_SEL(s, client, cantBeHere, kStopOnInvalidSelector), 0);
+ if (SELECTOR(cantBeHere) != -1) {
+ invokeSelector(s, client, SELECTOR(cantBeHere), argc, argv);
s->r_acc = make_reg(0, !s->r_acc.offset);
} else {
- invokeSelector(INV_SEL(s, client, canBeHere, kStopOnInvalidSelector), 0);
+ invokeSelector(s, client, SELECTOR(canBeHere), argc, argv);
}
if (!s->r_acc.offset) { // Contains the return value
@@ -335,7 +335,7 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
if ((getSciVersion() >= SCI_VERSION_1_EGA))
if (completed)
- invokeSelector(INV_SEL(s, mover, moveDone, kStopOnInvalidSelector), 0);
+ invokeSelector(s, mover, SELECTOR(moveDone), argc, argv);
return make_reg(0, completed);
}
@@ -399,20 +399,13 @@ reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) {
debugC(2, kDebugLevelBresen, "Doing avoider %04x:%04x (dest=%d,%d)", PRINT_REG(avoider), destx, desty);
- if (invokeSelector(INV_SEL(s, mover, doit, kContinueOnInvalidSelector) , 0)) {
- error("Mover %04x:%04x of avoider %04x:%04x doesn't have a doit() funcselector", PRINT_REG(mover), PRINT_REG(avoider));
- return NULL_REG;
- }
+ invokeSelector(s, mover, SELECTOR(doit), argc, argv);
mover = readSelector(segMan, client, SELECTOR(mover));
if (!mover.segment) // Mover has been disposed?
return s->r_acc; // Return gracefully.
- if (invokeSelector(INV_SEL(s, client, isBlocked, kContinueOnInvalidSelector) , 0)) {
- error("Client %04x:%04x of avoider %04x:%04x doesn't"
- " have an isBlocked() funcselector", PRINT_REG(client), PRINT_REG(avoider));
- return NULL_REG;
- }
+ invokeSelector(s, client, SELECTOR(isBlocked), argc, argv);
dx = destx - readSelectorValue(segMan, client, SELECTOR(x));
dy = desty - readSelectorValue(segMan, client, SELECTOR(y));
@@ -439,11 +432,7 @@ reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) {
debugC(2, kDebugLevelBresen, "Pos (%d,%d): Trying angle %d; delta=(%d,%d)", oldx, oldy, angle, move_x, move_y);
- if (invokeSelector(INV_SEL(s, client, canBeHere, kContinueOnInvalidSelector) , 0)) {
- error("Client %04x:%04x of avoider %04x:%04x doesn't"
- " have a canBeHere() funcselector", PRINT_REG(client), PRINT_REG(avoider));
- return NULL_REG;
- }
+ invokeSelector(s, client, SELECTOR(canBeHere), argc, argv);
writeSelectorValue(segMan, client, SELECTOR(x), oldx);
writeSelectorValue(segMan, client, SELECTOR(y), oldy);
@@ -472,12 +461,11 @@ reg_t kDoAvoider(EngineState *s, int argc, reg_t *argv) {
s->r_acc = make_reg(0, angle);
+ reg_t params[2] = { make_reg(0, angle), client };
+
if (looper.segment) {
- if (invokeSelector(INV_SEL(s, looper, doit, kContinueOnInvalidSelector), 2, angle, client)) {
- error("Looper %04x:%04x of avoider %04x:%04x doesn't"
- " have a doit() funcselector", PRINT_REG(looper), PRINT_REG(avoider));
- } else
- return s->r_acc;
+ invokeSelector(s, looper, SELECTOR(doit), 2, params);
+ return s->r_acc;
} else {
// No looper? Fall back to DirLoop
_k_dirloop(client, (uint16)angle, s, argc, argv);
diff --git a/engines/sci/engine/kparse.cpp b/engines/sci/engine/kparse.cpp
index 465bc177a0..bb9a49c7e8 100644
--- a/engines/sci/engine/kparse.cpp
+++ b/engines/sci/engine/kparse.cpp
@@ -94,8 +94,8 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
ResultWordList words;
reg_t event = argv[1];
Vocabulary *voc = g_sci->getVocabulary();
-
voc->parser_event = event;
+ reg_t params[2] = { voc->parser_base, stringpos };
bool res = voc->tokenizeString(words, string.c_str(), &error);
voc->parserIsValid = false; /* not valid */
@@ -118,7 +118,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
s->r_acc = make_reg(0, 1);
writeSelectorValue(segMan, event, SELECTOR(claimed), 1);
- invokeSelector(INV_SEL(s, g_sci->getGameObject(), syntaxFail, kStopOnInvalidSelector), 2, voc->parser_base, stringpos);
+ invokeSelector(s, g_sci->getGameObject(), SELECTOR(syntaxFail), 2, params);
/* Issue warning */
debugC(2, kDebugLevelParser, "Tree building failed");
@@ -141,7 +141,7 @@ reg_t kParse(EngineState *s, int argc, reg_t *argv) {
debugC(2, kDebugLevelParser, "Word unknown: %s", error);
/* Issue warning: */
- invokeSelector(INV_SEL(s, g_sci->getGameObject(), wordFail, kStopOnInvalidSelector), 2, voc->parser_base, stringpos);
+ invokeSelector(s, g_sci->getGameObject(), SELECTOR(wordFail), 2, params);
free(error);
return make_reg(0, 1); /* Tell them that it didn't work */
}
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 04a1b8fbba..eafed029c5 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -200,7 +200,7 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t
*address.getPointer(segMan) = value;
}
-int invokeSelectorArgv(EngineState *s, reg_t object, int selectorId, SelectorInvocation noinvalid,
+void invokeSelector(EngineState *s, reg_t object, int selectorId,
int k_argc, StackPtr k_argp, int argc, const reg_t *argv) {
int i;
int framesize = 2 + 1 * argc;
@@ -214,16 +214,12 @@ int invokeSelectorArgv(EngineState *s, reg_t object, int selectorId, SelectorInv
slc_type = lookupSelector(s->_segMan, object, selectorId, NULL, &address);
if (slc_type == kSelectorNone) {
- warning("Selector '%s' of object at %04x:%04x could not be invoked",
+ error("Selector '%s' of object at %04x:%04x could not be invoked",
g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object));
- if (noinvalid == kStopOnInvalidSelector)
- error("[Kernel] Not recoverable: VM was halted");
- return 1;
}
if (slc_type == kSelectorVariable) {
warning("Attempting to invoke variable selector %s of object %04x:%04x",
g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object));
- return 0;
}
for (i = 0; i < argc; i++)
@@ -238,24 +234,6 @@ int invokeSelectorArgv(EngineState *s, reg_t object, int selectorId, SelectorInv
xstack->fp += argc + 2;
run_vm(s, false); // Start a new vm
-
- return 0;
-}
-
-int invokeSelector(EngineState *s, reg_t object, int selectorId, SelectorInvocation noinvalid,
- int k_argc, StackPtr k_argp, int argc, ...) {
- va_list argp;
- reg_t *args = new reg_t[argc];
-
- va_start(argp, argc);
- for (int i = 0; i < argc; i++)
- args[i] = va_arg(argp, reg_t);
- va_end(argp);
-
- int retval = invokeSelectorArgv(s, object, selectorId, noinvalid, k_argc, k_argp, argc, args);
-
- delete[] args;
- return retval;
}
SelectorType lookupSelector(SegManager *segMan, reg_t obj_location, Selector selectorId, ObjVarRef *varp, reg_t *fptr) {
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index f50b9ab1b3..851ff6bc81 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -34,11 +34,6 @@
namespace Sci {
-enum SelectorInvocation {
- kStopOnInvalidSelector = 0,
- kContinueOnInvalidSelector = 1
-};
-
/**
* Map a selector name to a selector id. Shortcut for accessing the selector cache.
*/
@@ -71,18 +66,8 @@ void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t
/**
* Invokes a selector from an object.
*/
-int invokeSelector(EngineState *s, reg_t object, int selectorId, SelectorInvocation noinvalid,
- int k_argc, StackPtr k_argp, int argc, ...);
-int invokeSelectorArgv(EngineState *s, reg_t object, int selectorId, SelectorInvocation noinvalid,
- int k_argc, StackPtr k_argp, int argc, const reg_t *argv);
-
-/**
- * Kludge for use with invokeSelector(). Used for compatibility with compilers
- * that cannot handle vararg macros.
- */
-#define INV_SEL(s, _object_, _selector_, _noinvalid_) \
- s, _object_, g_sci->getKernel()->_selectorCache._selector_, _noinvalid_, argc, argv
-
+void invokeSelector(EngineState *s, reg_t object, int selectorId,
+ int k_argc, StackPtr k_argp, int argc = 0, const reg_t *argv = 0);
} // End of namespace Sci