aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2019-06-09 12:25:33 -0700
committerPaul Gilbert2019-06-09 15:00:46 -0700
commitb01e711d65e6ef85df90eecde64a857b389a8dbd (patch)
tree5b927001a08fb22df9cde7c8fdac779847ddada4
parent39764f46d2b722e1fbab06eb1489ca7e93e97676 (diff)
downloadscummvm-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.cpp4
-rw-r--r--engines/glk/advsys/game.h5
-rw-r--r--engines/glk/advsys/vm.cpp39
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() {