aboutsummaryrefslogtreecommitdiff
path: root/engines/agi/op_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agi/op_test.cpp')
-rw-r--r--engines/agi/op_test.cpp33
1 files changed, 25 insertions, 8 deletions
diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp
index 4505668fd1..6afddf844a 100644
--- a/engines/agi/op_test.cpp
+++ b/engines/agi/op_test.cpp
@@ -376,7 +376,7 @@ uint8 AgiEngine::testSaid(uint8 nwords, uint8 *cc) {
return true;
}
-int AgiEngine::testIfCode(int lognum) {
+bool AgiEngine::testIfCode(int16 logicNr) {
AgiGame *state = &_game;
uint8 op;
uint8 p[16];
@@ -387,8 +387,8 @@ int AgiEngine::testIfCode(int lognum) {
int result = true;
while (!(shouldQuit() || _restartGame) && !endTest) {
- if (_debug.enabled && (_debug.logic0 || lognum))
- debugConsole(lognum, lTEST_MODE, NULL);
+ if (_debug.enabled && (_debug.logic0 || logicNr))
+ debugConsole(logicNr, lTEST_MODE, NULL);
op = *(code + ip++);
memmove(p, (code + ip), 16);
@@ -418,7 +418,14 @@ int AgiEngine::testIfCode(int lognum) {
default:
// Evaluate the command and skip the rest of the instruction
- _agiCondCommands[op](state, this, p);
+ _opCodesCond[op].functionPtr(state, this, p);
+ if (state->exitAllLogics) {
+ // required even here, because of at least the timer heuristic
+ // which when triggered waits a bit and processes ScummVM events and user may therefore restore a saved game
+ // fixes bug #9707
+ // TODO: maybe delay restoring the game instead, when GMM is used?
+ return true;
+ }
skipInstruction(op);
// NOT mode is enabled only for one instruction
@@ -457,8 +464,8 @@ int AgiEngine::testIfCode(int lognum) {
else
ip += READ_LE_UINT16(code + ip) + 2;
- if (_debug.enabled && (_debug.logic0 || lognum))
- debugConsole(lognum, 0xFF, result ? "=true" : "=false");
+ if (_debug.enabled && (_debug.logic0 || logicNr))
+ debugConsole(logicNr, 0xFF, result ? "=true" : "=false");
return result;
}
@@ -469,16 +476,26 @@ void AgiEngine::skipInstruction(byte op) {
return;
if (op == 0x0E && state->_vm->getVersion() >= 0x2000) // said
ip += *(code + ip) * 2 + 1;
- else
- ip += logicNamesTest[op].argumentsLength();
+ else {
+ ip += _opCodesCond[op].parameterSize;
+ }
}
void AgiEngine::skipInstructionsUntil(byte v) {
AgiGame *state = &_game;
+ int originalIP = state->_curLogic->cIP;
+
while (1) {
byte op = *(code + ip++);
if (op == v)
return;
+
+ if (op < 0xFC) {
+ if (!_opCodesCond[op].functionPtr) {
+ // security-check
+ error("illegal opcode %x during skipinstructions in script %d at %d (triggered at %d)", op, state->curLogicNr, ip, originalIP);
+ }
+ }
skipInstruction(op);
}
}