diff options
author | sylvaintv | 2012-04-28 18:52:15 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2018-03-28 17:36:57 +0200 |
commit | 6dfec1f58e62ee0f3fe8237bf9460c2542d946b0 (patch) | |
tree | a967d79206448e7605348ce22104e07ca062ae53 /engines/lilliput | |
parent | 2462b8d340c5345d4d2b18b138888cf9399ee902 (diff) | |
download | scummvm-rg350-6dfec1f58e62ee0f3fe8237bf9460c2542d946b0.tar.gz scummvm-rg350-6dfec1f58e62ee0f3fe8237bf9460c2542d946b0.tar.bz2 scummvm-rg350-6dfec1f58e62ee0f3fe8237bf9460c2542d946b0.zip |
LILLIPUT: Last opcodes1 + first step of script decompiler
Diffstat (limited to 'engines/lilliput')
-rw-r--r-- | engines/lilliput/lilliput.cpp | 2 | ||||
-rw-r--r-- | engines/lilliput/script.cpp | 243 | ||||
-rw-r--r-- | engines/lilliput/script.h | 3 |
3 files changed, 235 insertions, 13 deletions
diff --git a/engines/lilliput/lilliput.cpp b/engines/lilliput/lilliput.cpp index a3e0217f7c..9afa97a307 100644 --- a/engines/lilliput/lilliput.cpp +++ b/engines/lilliput/lilliput.cpp @@ -2030,6 +2030,8 @@ void LilliputEngine::handleGameScripts() { assert(tmpVal < _gameScriptIndexSize); debugC(1, kDebugEngine, "================= Game Script %d for character %d ==================", tmpVal, index); + ScriptStream script = ScriptStream(&_arrayGameScripts[_arrayGameScriptIndex[tmpVal]], _arrayGameScriptIndex[tmpVal + 1] - _arrayGameScriptIndex[tmpVal]); + //_scriptHandler->disasmScript(script); _scriptHandler->runScript(ScriptStream(&_arrayGameScripts[_arrayGameScriptIndex[tmpVal]], _arrayGameScriptIndex[tmpVal + 1] - _arrayGameScriptIndex[tmpVal])); debugC(1, kDebugEngine, "============= End Game Script %d for character %d ==================", tmpVal, index); diff --git a/engines/lilliput/script.cpp b/engines/lilliput/script.cpp index c9c3512d8e..2479fed2e7 100644 --- a/engines/lilliput/script.cpp +++ b/engines/lilliput/script.cpp @@ -551,6 +551,164 @@ void LilliputScript::handleOpcodeType2(int curWord) { } } +enum KValueType { + kNone, + kImmediateValue, + kCompareOperation, + kGetValue1, + kGetValue2, +}; + + +struct OpCode { + const char* _opName; + int _numArgs; + KValueType _arg1; + KValueType _arg2; + KValueType _arg3; + KValueType _arg4; + KValueType _arg5; +}; + +static const OpCode opCodes1[] = { + { "OC_sub173DF", 1, kGetValue2, kNone, kNone, kNone, kNone }, + { "OC_sub173F0", 2, kGetValue1, kGetValue2, kNone, kNone, kNone }, + { "OC_sub1740A", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub17434", 4, kGetValue1, kImmediateValue, kCompareOperation, kImmediateValue, kNone }, + { "OC_sub17468", 2, kCompareOperation, kImmediateValue, kNone, kNone, kNone }, + { "OC_getRandom", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_for", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone }, + { "OC_compWord18776", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_checkSaveFlag", 0, kNone, kNone, kNone, kNone, kNone }, + { "OC_compByte16F04", 2, kCompareOperation, kImmediateValue, kNone, kNone, kNone }, + { "OC_sub174D8", 2, kGetValue1, kGetValue1, kNone, kNone, kNone }, + { "OC_sub1750E", 2, kGetValue1, kGetValue1, kNone, kNone, kNone }, + { "OC_compareCoords_1", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_compareCoords_2", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone }, + { "OC_sub1757C", 3, kGetValue2, kCompareOperation, kImmediateValue, kNone, kNone }, + { "OC_sub1759E", 3, kGetValue1, kCompareOperation, kImmediateValue, kNone, kNone }, + { "OC_compWord16EF8", 1, kGetValue1, kNone, kNone, kNone, kNone }, + { "OC_sub175C8", 2, kImmediateValue, kGetValue1, kNone, kNone, kNone }, + { "OC_sub17640", 2, kImmediateValue, kGetValue1, kNone, kNone, kNone }, + { "OC_sub176C4", 2, kImmediateValue, kGetValue1, kNone, kNone, kNone }, + { "OC_compWord10804", 1, kGetValue1, kNone, kNone, kNone, kNone }, + { "OC_sub17766", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub17782", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub1779E", 4, kGetValue2, kImmediateValue, kImmediateValue, kCompareOperation, kNone }, + { "OC_sub177C6", 1, kGetValue1, kNone, kNone, kNone, kNone }, + { "OC_compWord16EFE", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub177F5", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone }, + { "OC_sub17812", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub17825", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub17844", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub1785C", 3, kImmediateValue, kCompareOperation, kImmediateValue, kNone, kNone }, + { "OC_sub17886", 1, kGetValue2, kNone, kNone, kNone, kNone }, + { "OC_sub178A8", 2, kGetValue1, kGetValue1, kNone, kNone, kNone }, + { "OC_sub178BA", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub178C2", 0, kNone, kNone, kNone, kNone, kNone }, + { "OC_sub178D2", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone }, + { "OC_sub178E8", 3, kGetValue1, kImmediateValue, kImmediateValue, kNone, kNone }, + { "OC_sub178FC", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub1790F", 1, kGetValue1, kNone, kNone, kNone, kNone }, + { "OC_sub1792A", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub1793E", 0, kNone, kNone, kNone, kNone, kNone }, + { "OC_sub1795E", 0, kNone, kNone, kNone, kNone, kNone }, + { "OC_sub1796E", 2, kGetValue1, kImmediateValue, kNone, kNone, kNone }, + { "OC_sub17984", 2, kImmediateValue, kImmediateValue, kNone, kNone, kNone }, + { "OC_checkSavedMousePos", 0, kNone, kNone, kNone, kNone, kNone }, + { "OC_sub179AE", 0, kNone, kNone, kNone, kNone, kNone }, + { "OC_sub179C2", 1, kGetValue2, kNone, kNone, kNone, kNone }, + { "OC_sub179E5", 1, kImmediateValue, kNone, kNone, kNone, kNone }, + { "OC_sub17A07", 3, kImmediateValue, kImmediateValue, kImmediateValue, kNone, kNone }, + { "OC_sub17757", 1, kGetValue1, kNone, kNone, kNone, kNone }, +}; + +static const OpCode opCodes2[] = { + { "test", 1, kNone, kNone, kNone, kNone } +}; + +void LilliputScript::disasmScript( ScriptStream script) { + + while(!script.eos()) { + uint16 val = script.readUint16LE(); + if (val == 0xFFF6) // end of script + return; + + bool hasIf = false; + + if(val != 0xFFF8) { + hasIf = true; + debugC(2, kDebugScript, "if ("); + } + + // check the conditions. + while (val != 0xFFF8) { + + bool neg = false; + + if (val > 1000) { + val -= 1000; + // negative condition + neg = true; + } + + // op code type 1 + assert(val < sizeof(opCodes1)/sizeof(OpCode)); + const OpCode* opCode = &opCodes1[val]; + const KValueType* opArgType = &opCode->_arg1; + + Common::String str; + + str = " "; + if (neg) str += "not "; + str += Common::String(opCode->_opName); + str += "("; + + for (int p = 0; p < opCode->_numArgs; p++) { + if(*opArgType == kImmediateValue) { + str += Common::String::format("%d", script.readUint16LE()); + } else if (*opArgType == kGetValue1) { + str += Common::String::format("getValue1(%d)", script.readUint16LE()); + } else if (*opArgType == kGetValue2) { + str += Common::String::format("getValue2(%d)", script.readUint16LE()); + } else if (*opArgType == kCompareOperation) { + int comp = script.readUint16LE(); + if(comp != '<' && comp != '>') + comp = '='; + str += Common::String::format("%c", comp ); + } + + if(p != opCode->_numArgs - 1) + str += ", "; + + opArgType++; + } + str += ")"; + + debugC(2, kDebugScript, str.c_str()); + + val = script.readUint16LE(); + + } + + if( hasIf ) { + debugC(2, kDebugScript, ")"); + } + + + debugC(2, kDebugScript,"{ "); + + while (val != 0xFFF7) { + // op code type 2 TODO + + val = script.readUint16LE(); + } + + debugC(2, kDebugScript,"} "); + + } +} + int LilliputScript::handleOpcode(ScriptStream *script) { debugC(2, kDebugScript, "handleOpcode"); _currScript = script; @@ -592,6 +750,8 @@ void LilliputScript::runScript(ScriptStream script) { _vm->update(); } + + void LilliputScript::runMenuScript(ScriptStream script) { debugC(1, kDebugScript, "runMenuScript"); warning("========================== Menu Script =============================="); @@ -1057,8 +1217,17 @@ byte LilliputScript::OC_sub174D8() { } byte LilliputScript::OC_sub1750E() { - warning("OC_sub1750E"); - return 0; + debugC(1, kDebugScript, "OC_sub1750E()"); + + byte* buf1 = getBuffer215Ptr(); + int var1 = *buf1; + + int operation = _currScript->readUint16LE(); + + byte* buf2 = getBuffer215Ptr(); + int var2 = *buf2; + + return compareValues(var1, operation, var2); } byte LilliputScript::OC_compareCoords_1() { @@ -1078,8 +1247,16 @@ byte LilliputScript::OC_compareCoords_1() { } byte LilliputScript::OC_compareCoords_2() { - warning("compareCoords_2"); - return 0; + debugC(1, kDebugScript, "OC_compareCoords_2()"); + int var1 = getValue1(); + var1 = (_array16123[var1] << 8) + _array1614B[var1]; + int var2 = _currScript->readUint16LE(); + int var3 = _vm->_rulesBuffer12_1[var2]; + int var4 = _vm->_rulesBuffer12_2[var2]; + + if (((var1 >> 8) < (var3 >> 8)) || ((var1 >> 8) > (var3 & 0xFF)) || ((var1 & 0xFF) < (var4 >> 8)) || ((var1 & 0xFF) > (var4 & 0xFF))) + return 0; + return 1; } byte LilliputScript::OC_sub1757C() { warning("OC_sub1757C"); @@ -1297,7 +1474,7 @@ byte LilliputScript::OC_sub1779E() { byte LilliputScript::OC_sub177C6() { debugC(1, kDebugScript, "OC_sub177C6()"); - int index = _currScript->readUint16LE(); + int index = getValue1(); if (_vm->_characterPositionX[index] == 0xFFFF) return 0; @@ -1384,16 +1561,31 @@ byte LilliputScript::OC_sub1785C() { } byte LilliputScript::OC_sub17886() { - warning("OC_sub17886"); + debugC(1, kDebugScript, "OC_sub17886()"); + + int var1 = getValue2(); + int x = var1 >> 8; + int y = var1 & 0xFF; + + int dx = x - _viewportX; + int dy = y - _viewportY; + + if ( dx >= 0 && dx < 8 && dy >= 0 && dy < 8) + return 1; return 0; } byte LilliputScript::OC_sub178A8() { - warning("OC_sub178A8"); + debugC(1, kDebugScript, "OC_sub178A8()"); + + int var1 = getValue1(); + int var2 = getValue2(); + if (var1 == var2) + return 1; return 0; } byte LilliputScript::OC_sub178BA() { - warning("OC_sub178BA"); - return 0; + _currScript->readUint16LE(); + return 1; } byte LilliputScript::OC_sub178C2() { @@ -1491,7 +1683,13 @@ byte LilliputScript::OC_sub1795E() { } byte LilliputScript::OC_sub1796E() { - warning("OC_sub1796E"); + debugC(1, kDebugScript, "OC_sub1796E()"); + + int var1 = getValue1(); + int var2 = _currScript->readUint16LE(); + + if (_vm->_rulesBuffer2_9[var1] == var2) + return 1; return 0; } @@ -1528,11 +1726,25 @@ byte LilliputScript::OC_sub179AE() { } byte LilliputScript::OC_sub179C2() { - warning("OC_sub179C2"); + debugC(1, kDebugScript, "OC_sub179C2()"); + int var1 = getValue2(); + + if (_vm->_array10999[_vm->_rulesBuffer2PrevIndx] == var1 >> 8 + && _vm->_array109C1[_vm->_rulesBuffer2PrevIndx] == var1 & 0xFF) + return 1; + return 0; } byte LilliputScript::OC_sub179E5() { - warning("OC_sub179E5"); + debugC(1, kDebugScript, "OC_sub17A07()"); + + static const byte _byte179DB[10] = {0x44, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43}; + + int var1 = (_currScript->readUint16LE() & 0xFF) - 0x30; + + if (_byte179DB[var1] == _vm->_byte16F09) + return 1; + return 0; } @@ -1559,7 +1771,12 @@ byte LilliputScript::OC_sub17A07() { } byte LilliputScript::OC_sub17757() { - warning("OC_sub17757"); + debugC(1, kDebugScript, "OC_sub17757()"); + + int var1 = getValue1(); + if ( var1 == _viewportCharacterTarget ) + return 1; + return 0; } diff --git a/engines/lilliput/script.h b/engines/lilliput/script.h index 19094e81fb..3bb2c92577 100644 --- a/engines/lilliput/script.h +++ b/engines/lilliput/script.h @@ -68,6 +68,7 @@ public: LilliputScript(LilliputEngine *vm); ~LilliputScript(); + void disasmScript(ScriptStream script); void runScript(ScriptStream script); void runMenuScript(ScriptStream script); private: @@ -93,6 +94,8 @@ private: int handleOpcode(ScriptStream *script); byte handleOpcodeType1(int curWord); void handleOpcodeType2(int curWord); + + void sub1863B(); void sub185ED(byte index, byte subIndex); |