aboutsummaryrefslogtreecommitdiff
path: root/engines/agi/op_test.cpp
diff options
context:
space:
mode:
authorJussi Pitkanen2011-06-13 22:15:13 +0300
committerEugene Sandulenko2011-08-13 23:26:51 +0100
commita4e0cd53f01afeac9f6cf0467a6b4174bf64215e (patch)
tree147a8c9b9fac4bb7a32877f46be32add92fd859f /engines/agi/op_test.cpp
parente1153cf11fd0ddddfdc326d0ff677799fd0bb4db (diff)
downloadscummvm-rg350-a4e0cd53f01afeac9f6cf0467a6b4174bf64215e.tar.gz
scummvm-rg350-a4e0cd53f01afeac9f6cf0467a6b4174bf64215e.tar.bz2
scummvm-rg350-a4e0cd53f01afeac9f6cf0467a6b4174bf64215e.zip
AGI: Refactor interpreter core (somewhat akin to SCI)
* Instruction tables are now defined in opcodes.{cpp,h}. * Move opcode handlers from Agi::AgiEngine to Agi * Opcode handlers take as parameter a pointer to AGI state (AgiGame)
Diffstat (limited to 'engines/agi/op_test.cpp')
-rw-r--r--engines/agi/op_test.cpp168
1 files changed, 85 insertions, 83 deletions
diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp
index 24dd397ef9..0054fad6e8 100644
--- a/engines/agi/op_test.cpp
+++ b/engines/agi/op_test.cpp
@@ -26,158 +26,158 @@
namespace Agi {
-#define ip (_curLogic->cIP)
-#define code (_curLogic->data)
+#define ip (state->_curLogic->cIP)
+#define code (state->_curLogic->data)
+
+#define getvar(a) state->_vm->getvar(a)
+#define getflag(a) state->_vm->getflag(a)
#define testEqual(v1, v2) (getvar(v1) == (v2))
#define testLess(v1, v2) (getvar(v1) < (v2))
#define testGreater(v1, v2) (getvar(v1) > (v2))
#define testIsSet(flag) (getflag(flag))
-#define testHas(obj) (objectGetLocation(obj) == EGO_OWNED)
-#define testObjInRoom(obj, v) (objectGetLocation(obj) == getvar(v))
+#define testHas(obj) (state->_vm->objectGetLocation(obj) == EGO_OWNED)
+#define testObjInRoom(obj, v) (state->_vm->objectGetLocation(obj) == getvar(v))
-int AgiEngine::cond_end(uint8 *p) {
- _endTest = true;
- return true;
+void cond_end(AgiGame *state, uint8 *p) {
+ state->endTest = true;
+ state->ec = true;
}
-int AgiEngine::cond_equal(uint8 *p) {
+void cond_equal(AgiGame *state, uint8 *p) {
if (p[0] == 11)
- _timerHack++;
+ state->_vm->_timerHack++;
ip += 2;
- return testEqual(p[0], p[1]);
+ state->ec = testEqual(p[0], p[1]);
}
-int AgiEngine::cond_equalv(uint8 *p) {
+void cond_equalv(AgiGame *state, uint8 *p) {
if (p[0] == 11 || p[1] == 11)
- _timerHack++;
+ state->_vm->_timerHack++;
ip += 2;
- return testEqual(p[0], getvar(p[1]));
+ state->ec = testEqual(p[0], getvar(p[1]));
}
-int AgiEngine::cond_less(uint8 *p) {
+void cond_less(AgiGame *state, uint8 *p) {
if (p[0] == 11)
- _timerHack++;
+ state->_vm->_timerHack++;
ip += 2;
- return testLess(p[0], p[1]);
+ state->ec = testLess(p[0], p[1]);
}
-int AgiEngine::cond_lessv(uint8 *p) {
+void cond_lessv(AgiGame *state, uint8 *p) {
if (p[0] == 11 || p[1] == 11)
- _timerHack++;
+ state->_vm->_timerHack++;
ip += 2;
- return testLess(p[0], getvar(p[1]));
+ state->ec = testLess(p[0], getvar(p[1]));
}
-int AgiEngine::cond_greater(uint8 *p) {
+void cond_greater(AgiGame *state, uint8 *p) {
if (p[0] == 11)
- _timerHack++;
+ state->_vm->_timerHack++;
ip += 2;
- return testGreater(p[0], p[1]);
+ state->ec = testGreater(p[0], p[1]);
}
-int AgiEngine::cond_greaterv(uint8 *p) {
+void cond_greaterv(AgiGame *state, uint8 *p) {
if (p[0] == 11 || p[1] == 11)
- _timerHack++;
+ state->_vm->_timerHack++;
ip += 2;
- return testGreater(p[0], getvar(p[1]));
+ state->ec = testGreater(p[0], getvar(p[1]));
}
-int AgiEngine::cond_isset(uint8 *p) {
+void cond_isset(AgiGame *state, uint8 *p) {
ip += 1;
- return testIsSet(p[0]);
+ state->ec = testIsSet(p[0]);
}
-int AgiEngine::cond_issetv(uint8 *p) {
+void cond_issetv(AgiGame *state, uint8 *p) {
ip += 1;
- return testIsSet(getvar(p[1]));
+ state->ec = testIsSet(getvar(p[1]));
}
-int AgiEngine::cond_has(uint8 *p) {
+void cond_has(AgiGame *state, uint8 *p) {
ip += 1;
- return testHas(p[0]);
+ state->ec = testHas(p[0]);
}
-int AgiEngine::cond_obj_in_room(uint8 *p) {
+void cond_obj_in_room(AgiGame *state, uint8 *p) {
ip += 2;
- return testObjInRoom(p[0], p[1]);
+ state->ec = testObjInRoom(p[0], p[1]);
}
-int AgiEngine::cond_posn(uint8 *p) {
+void cond_posn(AgiGame *state, uint8 *p) {
ip += 5;
- return testPosn(p[0], p[1], p[2], p[3], p[4]);
+ state->ec = state->_vm->testPosn(p[0], p[1], p[2], p[3], p[4]);
}
-int AgiEngine::cond_controller(uint8 *p) {
+void cond_controller(AgiGame *state, uint8 *p) {
ip += 1;
- return testController(p[0]);
+ state->ec = state->_vm->testController(p[0]);
}
-int AgiEngine::cond_have_key(uint8 *p) {
- return testKeypressed();
+void cond_have_key(AgiGame *state, uint8 *p) {
+ state->ec = state->_vm->testKeypressed();
}
-int AgiEngine::cond_said(uint8 *p) {
- int ec = testSaid(p[0], p + 1);
+void cond_said(AgiGame *state, uint8 *p) {
+ int ec = state->_vm->testSaid(p[0], p + 1);
ip += p[0] * 2; // skip num_words * 2
ip++; // skip num_words opcode
- return ec;
+ state->ec = ec;
}
-int AgiEngine::cond_compare_strings(uint8 *p) {
- debugC(7, kDebugLevelScripts, "comparing [%s], [%s]", _game.strings[p[0]], _game.strings[p[1]]);
+void cond_compare_strings(AgiGame *state, uint8 *p) {
+ debugC(7, kDebugLevelScripts, "comparing [%s], [%s]", state->strings[p[0]], state->strings[p[1]]);
ip += 2;
- return testCompareStrings(p[0], p[1]);
+ state->ec = state->_vm->testCompareStrings(p[0], p[1]);
}
-int AgiEngine::cond_obj_in_box(uint8 *p) {
+void cond_obj_in_box(AgiGame *state, uint8 *p) {
ip += 5;
- return testObjInBox(p[0], p[1], p[2], p[3], p[4]);
+ state->ec = state->_vm->testObjInBox(p[0], p[1], p[2], p[3], p[4]);
}
-int AgiEngine::cond_center_posn(uint8 *p) {
+void cond_center_posn(AgiGame *state, uint8 *p) {
ip += 5;
- return testObjCenter(p[0], p[1], p[2], p[3], p[4]);
+ state->ec = state->_vm->testObjCenter(p[0], p[1], p[2], p[3], p[4]);
}
-int AgiEngine::cond_right_posn(uint8 *p) {
+void cond_right_posn(AgiGame *state, uint8 *p) {
ip += 5;
- return testObjRight(p[0], p[1], p[2], p[3], p[4]);
+ state->ec = state->_vm->testObjRight(p[0], p[1], p[2], p[3], p[4]);
}
-int AgiEngine::cond_unknown_13(uint8 *p) {
+void cond_unknown_13(AgiGame *state, uint8 *p) {
// My current theory is that this command checks whether the ego is currently moving
// and that that movement has been caused using the mouse and not using the keyboard.
// I base this theory on the game's behavior on an Amiga emulator, not on disassembly.
// This command is used at least in the Amiga version of Gold Rush! v2.05 1989-03-09
// (AGI 2.316) in logics 1, 3, 5, 6, 137 and 192 (Logic.192 revealed this command's nature).
// TODO: Check this command's implementation using disassembly just to be sure.
- int ec = _game.viewTable[0].flags & ADJ_EGO_XY;
+ int ec = state->viewTable[0].flags & ADJ_EGO_XY;
debugC(7, kDebugLevelScripts, "op_test: in.motion.using.mouse = %s (Amiga-specific testcase 19)", ec ? "true" : "false");
- return ec;
+ state->ec = ec;
}
-int AgiEngine::cond_unknown(uint8 *p) {
- _endTest = true;
- return false;
+void cond_unknown(AgiGame *state, uint8 *p) {
+ state->endTest = true;
}
-int AgiEngine::cond_not(uint8 *p) {
- _notTest = !_notTest;
- return false;
+void cond_not(AgiGame *state, uint8 *p) {
+ state->notTest = !state->notTest;
}
-int AgiEngine::cond_or(uint8 *p) {
+void cond_or(AgiGame *state, uint8 *p) {
// if or_test is ON and we hit 0xFC, end of OR, then
// or is STILL false so break.
- if (_orTest) {
- _orTest = false;
- _testVal &= _orVal;
+ if (state->orTest) {
+ state->orTest = false;
+ state->testVal &= state->orVal;
} else {
- _orTest = true;
- _orVal = false;
+ state->orTest = true;
+ state->orVal = false;
}
- return true;
}
uint8 AgiEngine::testCompareStrings(uint8 s1, uint8 s2) {
@@ -291,6 +291,7 @@ uint8 AgiEngine::testObjRight(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2) {
// When player has entered something, it is parsed elsewhere
uint8 AgiEngine::testSaid(uint8 nwords, uint8 *cc) {
+ AgiGame *state = &_game;
int c, n = _game.numEgoWords;
int z = 0;
@@ -346,17 +347,18 @@ uint8 AgiEngine::testSaid(uint8 nwords, uint8 *cc) {
}
int AgiEngine::testIfCode(int lognum) {
- int ec = true;
+ AgiGame *state = &_game;
uint8 op = 0;
uint16 lastIp = ip;
uint8 p[16] = { 0 };
- _notTest = false;
- _orTest = false;
- _endTest = false;
- _testVal = true;
+ state->ec = true;
+ state->notTest = false;
+ state->orTest = false;
+ state->endTest = false;
+ state->testVal = true;
- while (!(shouldQuit() || _restartGame) && !_endTest) {
+ while (!(shouldQuit() || _restartGame) && !state->endTest) {
if (_debug.enabled && (_debug.logic0 || lognum))
debugConsole(lognum, lTEST_MODE, NULL);
@@ -364,32 +366,32 @@ int AgiEngine::testIfCode(int lognum) {
op = *(code + ip++);
memmove(p, (code + ip), 16);
- ec = (this->*_agiCondCommands[op])(p);
+ _agiCondCommands[op](state, p);
if (op == 0xFF || op == 0xFD || op == 0xFC)
continue;
// not is only enabled for 1 test command
- if (_notTest)
- ec = !ec;
- _notTest = false;
+ if (state->notTest)
+ state->ec = !state->ec;
+ state->notTest = false;
- if (_orTest)
- _orVal |= ec;
+ if (state->orTest)
+ state->orVal |= state->ec;
else
- _testVal &= ec;
+ state->testVal &= state->ec;
}
// Execute the following IF block if the condition is true, otherwise
// skip the block.
- if (_testVal)
+ if (state->testVal)
ip += 2;
else
ip += READ_LE_UINT16(code + ip) + 2;
if (_debug.enabled && (_debug.logic0 || lognum))
- debugConsole(lognum, 0xFF, _testVal ? "=true" : "=false");
+ debugConsole(lognum, 0xFF, state->testVal ? "=true" : "=false");
- return _testVal;
+ return state->testVal;
}
} // End of namespace Agi