diff options
author | Jussi Pitkanen | 2011-06-12 17:31:45 +0300 |
---|---|---|
committer | Eugene Sandulenko | 2011-08-13 23:26:46 +0100 |
commit | eb797b692fbee2515d20fbb0b98fe06108c72825 (patch) | |
tree | 1db903fb6a94cb663cf141aea42377d660e291cb | |
parent | 7a80c4cdb39f003fb893361dde25d40ecd08101a (diff) | |
download | scummvm-rg350-eb797b692fbee2515d20fbb0b98fe06108c72825.tar.gz scummvm-rg350-eb797b692fbee2515d20fbb0b98fe06108c72825.tar.bz2 scummvm-rg350-eb797b692fbee2515d20fbb0b98fe06108c72825.zip |
AGI: Simplify handling of IF conditions
Execute all test commands in a condition even when not strictly needed.
-rw-r--r-- | engines/agi/agi.h | 3 | ||||
-rw-r--r-- | engines/agi/op_test.cpp | 106 |
2 files changed, 27 insertions, 82 deletions
diff --git a/engines/agi/agi.h b/engines/agi/agi.h index dbbd87e077..6c4d5bc6a8 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -1093,8 +1093,9 @@ private: AgiLogic *_curLogic; int _endTest; int _orTest; + int _orVal; int _notTest; - int _retval; + int _testVal; int _timerHack; // Workaround for timer loop in MH1 logic 153 void setupOpcodes(); diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp index 1722b16157..3748e4fc60 100644 --- a/engines/agi/op_test.cpp +++ b/engines/agi/op_test.cpp @@ -168,16 +168,16 @@ int AgiEngine::cond_not(uint8 *p) { } int AgiEngine::cond_or(uint8 *p) { - int ec = true; // if or_test is ON and we hit 0xFC, end of OR, then // or is STILL false so break. if (_orTest) { - ec = false; - _retval = false; - _endTest = true; + _orTest = false; + _testVal &= _orVal; + } else { + _orTest = true; + _orVal = false; } - _orTest = true; - return ec; + return true; } uint8 AgiEngine::testCompareStrings(uint8 s1, uint8 s2) { @@ -347,15 +347,16 @@ uint8 AgiEngine::testSaid(uint8 nwords, uint8 *cc) { int AgiEngine::testIfCode(int lognum) { int ec = true; - _retval = true; uint8 op = 0; - _notTest = false; - _orTest = false; uint16 lastIp = ip; uint8 p[16] = { 0 }; + + _notTest = false; + _orTest = false; _endTest = false; + _testVal = true; - while (_retval && !(shouldQuit() || _restartGame) && !_endTest) { + while (!(shouldQuit() || _restartGame) && !_endTest) { if (_debug.enabled && (_debug.logic0 || lognum)) debugConsole(lognum, lTEST_MODE, NULL); @@ -364,87 +365,30 @@ int AgiEngine::testIfCode(int lognum) { memmove(p, (code + ip), 16); ec = (this->*_agiCondCommands[op])(p); - if (op == 0xFD || op == 0xFC) + if (op == 0xFF || op == 0xFD || op == 0xFC) continue; - if (!_endTest) { -// if (op <= 0x12) -// ip += logicNamesTest[op].numArgs; - - // exchange ec value - if (_notTest) - ec = !ec; - - // not is only enabled for 1 test command - _notTest = false; - - if (_orTest && ec) { - // a true inside an OR statement passes - // ENTIRE statement scan for end of OR - - // CM: test for opcode < 0xfc changed from 'op' to - // '*(code+ip)', to avoid problem with the 0xfd (NOT) - // opcode byte. Changed a bad ip += ... ip++ construct. - // This should fix the crash with Larry's logic.0 code: - // - // if ((isset(4) || - // !isset(2) || - // v30 == 2 || - // v30 == 1)) { - // goto Label1; - // } - // - // The bytecode is: - // ff fc 07 04 fd 07 02 01 1e 02 01 1e 01 fc ff - - // find end of OR - while (*(code + ip) != 0xFC) { - if (*(code + ip) == 0x0E) { // said - ip++; - - // cover count + ^words - ip += 1 + ((*(code + ip)) * 2); - continue; - } - - if (*(code + ip) < 0xFC) - ip += logicNamesTest[*(code + ip)].numArgs; - ip++; - } - ip++; - - _orTest = false; - _retval = true; - } else { - _retval = _orTest ? _retval || ec : _retval && ec; - } - } + // not is only enabled for 1 test command + if (_notTest) + ec = !ec; + _notTest = false; + + if (_orTest) + _orVal |= ec; + else + _testVal &= ec; } // if false, scan for end of IP? - if (_retval) + if (_testVal) ip += 2; - else { - ip = lastIp; - while (*(code + ip) != 0xff) { - if (*(code + ip) == 0x0e) { - ip++; - ip += (*(code + ip)) * 2 + 1; - } else if (*(code + ip) < 0xfc) { - ip += logicNamesTest[*(code + ip)].numArgs; - ip++; - } else { - ip++; - } - } - ip++; // skip over 0xFF + else ip += READ_LE_UINT16(code + ip) + 2; - } if (_debug.enabled && (_debug.logic0 || lognum)) - debugConsole(lognum, 0xFF, _retval ? "=true" : "=false"); + debugConsole(lognum, 0xFF, _testVal ? "=true" : "=false"); - return _retval; + return _testVal; } } // End of namespace Agi |