diff options
author | Paul Gilbert | 2019-06-09 12:25:33 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-06-09 15:00:46 -0700 |
commit | b01e711d65e6ef85df90eecde64a857b389a8dbd (patch) | |
tree | 5b927001a08fb22df9cde7c8fdac779847ddada4 | |
parent | 39764f46d2b722e1fbab06eb1489ca7e93e97676 (diff) | |
download | scummvm-rg350-b01e711d65e6ef85df90eecde64a857b389a8dbd.tar.gz scummvm-rg350-b01e711d65e6ef85df90eecde64a857b389a8dbd.tar.bz2 scummvm-rg350-b01e711d65e6ef85df90eecde64a857b389a8dbd.zip |
GLK: ADVSYS: Implementing VM opcodes
-rw-r--r-- | engines/glk/advsys/game.cpp | 4 | ||||
-rw-r--r-- | engines/glk/advsys/game.h | 5 | ||||
-rw-r--r-- | engines/glk/advsys/vm.cpp | 39 |
3 files changed, 44 insertions, 4 deletions
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp index a20178d9e2..22b1d11476 100644 --- a/engines/glk/advsys/game.cpp +++ b/engines/glk/advsys/game.cpp @@ -220,13 +220,15 @@ int Game::getObjectProperty(int obj, int prop) { return NIL; } -void Game::setObjectProperty(int obj, int prop, int val) { +int Game::setObjectProperty(int obj, int prop, int val) { int field; for (; obj; obj = getObjectField(obj, O_CLASS)) { if ((field = findProperty(obj, prop)) != 0) return setObjectField(obj, field, val); } + + return NIL; } int Game::getObjectLocation(int obj) const { diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h index 40b4fb65ec..5ffb31b20e 100644 --- a/engines/glk/advsys/game.h +++ b/engines/glk/advsys/game.h @@ -250,7 +250,7 @@ public: /** * Sets an object property */ - void setObjectProperty(int obj, int prop, int val); + int setObjectProperty(int obj, int prop, int val); /** * Gets a field from an object @@ -262,8 +262,9 @@ public: /** * Sets a field in an object */ - void setObjectField(int obj, int offset, int val) { + int setObjectField(int obj, int offset, int val) { WRITE_LE_UINT16(_residentBase + getObjectLocation(obj) + offset, val); + return val; } /** diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp index a467a592d2..46d2133dd0 100644 --- a/engines/glk/advsys/vm.cpp +++ b/engines/glk/advsys/vm.cpp @@ -25,6 +25,8 @@ namespace Glk { namespace AdvSys { +#define TRUE -1 + OpcodeMethod VM::_METHODS[0x34] = { &VM::opBRT, &VM::opBRF, @@ -117,71 +119,105 @@ void VM::executeOpcode() { error("Unknown opcode %x at offset %d", opcode, _pc); } } - void VM::opBRT() { + _pc = _stack.back() ? readCodeWord() : _pc + 2; } void VM::opBRF() { + _pc = !_stack.back() ? readCodeWord() : _pc + 2; } void VM::opBR() { + _pc = readCodeWord(); } void VM::opT() { + _stack.back() = TRUE; } void VM::opNIL() { + _stack.back() = NIL; } void VM::opPUSH() { + _stack.push(NIL); } void VM::opNOT() { + _stack.back() = _stack.back() ? NIL : TRUE; } void VM::opADD() { + int v = _stack.pop(); + _stack.back() += v; } void VM::opSUB() { + int v = _stack.pop(); + _stack.back() -= v; } void VM::opMUL() { + int v = _stack.pop(); + _stack.back() *= v; } void VM::opDIV() { + int v = _stack.pop(); + _stack.back() = (v == 0) ? 0 : _stack.back() / v; } void VM::opREM() { + int v = _stack.pop(); + _stack.back() = (v == 0) ? 0 : _stack.back() % v; } void VM::opBAND() { + int v = _stack.pop(); + _stack.back() &= v; } void VM::opBOR() { + int v = _stack.pop(); + _stack.back() |= v; } void VM::opBNOT() { + _stack.back() = ~_stack.back(); } void VM::opLT() { + int v = _stack.pop(); + _stack.back() = (_stack.back() < v) ? TRUE : NIL; } void VM::opEQ() { + int v = _stack.pop(); + _stack.back() = (_stack.back() == v) ? TRUE : NIL; } void VM::opGT() { + int v = _stack.pop(); + _stack.back() = (_stack.back() > v) ? TRUE : NIL; } void VM::opLIT() { + _stack.back() = readCodeWord(); } void VM::opVAR() { + _stack.back() = getVariable(readCodeWord()); } void VM::opGETP() { + int v = _stack.pop(); + _stack.back() = getObjectProperty(_stack.back(), v); } void VM::opSETP() { + int v3 = _stack.pop(); + int v2 = _stack.pop(); + _stack.back() = setObjectProperty(_stack.back(), v2, v3); } void VM::opSET() { @@ -215,6 +251,7 @@ void VM::opCALL() { } void VM::opSVAR() { + _stack.back() = getVariable(readCodeByte()); } void VM::opSSET() { |