aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/inter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/inter.cpp')
-rw-r--r--engines/gob/inter.cpp152
1 files changed, 90 insertions, 62 deletions
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index ce7f2ba319..8be07034c6 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -33,7 +33,8 @@
#include "gob/util.h"
#include "gob/draw.h"
#include "gob/game.h"
-#include "gob/parse.h"
+#include "gob/expression.h"
+#include "gob/script.h"
#include "gob/scenery.h"
#include "gob/sound/sound.h"
@@ -67,65 +68,93 @@ Inter::~Inter() {
delocateVars();
}
-void Inter::initControlVars(char full) {
- *_nestLevel = 0;
- *_breakFromLevel = -1;
+void Inter::setupOpcodes() {
+ setupOpcodesDraw();
+ setupOpcodesFunc();
+ setupOpcodesGob();
+}
- *_vm->_scenery->_pCaptureCounter = 0;
+void Inter::executeOpcodeDraw(byte i) {
+ debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", i, i, getDescOpcodeDraw(i));
- _break = false;
- _terminate = 0;
+ if (_opcodesDraw[i].proc && _opcodesDraw[i].proc->isValid())
+ (*_opcodesDraw[i].proc)();
+ else
+ warning("unimplemented opcodeDraw: %d [0x%X]", i, i);
+}
- if (full == 1) {
- for (int i = 0; i < 8; i++)
- _animPalDir[i] = 0;
- _soundEndTimeKey = 0;
+bool Inter::executeOpcodeFunc(byte i, byte j, OpFuncParams &params) {
+ debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)",
+ i, j, i, j, getDescOpcodeFunc(i, j));
+
+ if ((i > 4) || (j > 15)) {
+ warning("unimplemented opcodeFunc: %d.%d [0x%X.0x%X]", i, j, i, j);
+ return false;
}
+
+ i = i * 16 + j;
+ if (_opcodesFunc[i].proc && _opcodesFunc[i].proc->isValid())
+ return (*_opcodesFunc[i].proc)(params);
+ else
+ warning("unimplemented opcodeFunc: %d.%d [0x%X.0x%X]", i, j, i, j);
+
+ return false;
}
-int16 Inter::load16() {
- int16 tmp = (int16) READ_LE_UINT16(_vm->_global->_inter_execPtr);
- _vm->_global->_inter_execPtr += 2;
- return tmp;
+void Inter::executeOpcodeGob(int i, OpGobParams &params) {
+ debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)",
+ i, i, getDescOpcodeGob(i));
+
+ OpcodeEntry<OpcodeGob> *op = 0;
+
+ if (_opcodesGob.contains(i))
+ op = &_opcodesGob.getVal(i);
+
+ if (op && op->proc && op->proc->isValid()) {
+ (*op->proc)(params);
+ return;
+ }
+
+ _vm->_game->_script->skip(params.paramCount << 1);
+ warning("unimplemented opcodeGob: %d [0x%X]", i, i);
}
-char Inter::evalExpr(int16 *pRes) {
- byte token;
+const char *Inter::getDescOpcodeDraw(byte i) {
+ const char *desc = _opcodesDraw[i].desc;
- _vm->_parse->printExpr(99);
+ return ((desc) ? desc : "");
+}
- _vm->_parse->parseExpr(99, &token);
- if (!pRes)
- return token;
+const char *Inter::getDescOpcodeFunc(byte i, byte j) {
+ if ((i > 4) || (j > 15))
+ return "";
- switch (token) {
- case 20:
- *pRes = _vm->_global->_inter_resVal;
- break;
+ const char *desc = _opcodesFunc[i * 16 + j].desc;
- case 22:
- case 23:
- *pRes = 0;
- break;
+ return ((desc) ? desc : "");
+}
- case 24:
- *pRes = 1;
- break;
- }
+const char *Inter::getDescOpcodeGob(int i) {
+ if (_opcodesGob.contains(i))
+ return _opcodesGob.getVal(i).desc;
- return token;
+ return "";
}
-bool Inter::evalBoolResult() {
- byte token;
+void Inter::initControlVars(char full) {
+ *_nestLevel = 0;
+ *_breakFromLevel = -1;
+
+ *_vm->_scenery->_pCaptureCounter = 0;
- _vm->_parse->printExpr(99);
+ _break = false;
+ _terminate = 0;
- _vm->_parse->parseExpr(99, &token);
- if ((token == 24) || ((token == 20) && _vm->_global->_inter_resVal))
- return true;
- else
- return false;
+ if (full == 1) {
+ for (int i = 0; i < 8; i++)
+ _animPalDir[i] = 0;
+ _soundEndTimeKey = 0;
+ }
}
void Inter::renewTimeInVars() {
@@ -185,14 +214,14 @@ void Inter::storeKey(int16 key) {
void Inter::writeVar(uint32 offset, uint16 type, uint32 value) {
switch (type) {
- case 16:
- case 18:
+ case TYPE_VAR_INT8:
+ case TYPE_ARRAY_INT8:
WRITE_VARO_UINT8(offset, value);
break;
- case 17:
- case 24:
- case 27:
+ case TYPE_VAR_INT16:
+ case TYPE_VAR_INT32_AS_INT16:
+ case TYPE_ARRAY_INT16:
WRITE_VARO_UINT16(offset, value);
break;
@@ -209,20 +238,20 @@ void Inter::funcBlock(int16 retFlag) {
params.retFlag = retFlag;
- if (!_vm->_global->_inter_execPtr)
+ if (_vm->_game->_script->isFinished())
return;
_break = false;
- _vm->_global->_inter_execPtr++;
- params.cmdCount = *_vm->_global->_inter_execPtr++;
- _vm->_global->_inter_execPtr += 2;
+ _vm->_game->_script->skip(1);
+ params.cmdCount = _vm->_game->_script->readByte();
+ _vm->_game->_script->skip(2);
if (params.cmdCount == 0) {
- _vm->_global->_inter_execPtr = 0;
+ _vm->_game->_script->setFinished(true);
return;
}
- int startaddr = _vm->_global->_inter_execPtr - _vm->_game->_totFileData;
+ int startaddr = _vm->_game->_script->pos();
params.counter = 0;
do {
@@ -237,7 +266,7 @@ void Inter::funcBlock(int16 retFlag) {
(_vm->getPlatform() == Common::kPlatformMacintosh) ||
(_vm->getPlatform() == Common::kPlatformWindows))) {
- int addr = _vm->_global->_inter_execPtr-_vm->_game->_totFileData;
+ int addr = _vm->_game->_script->pos();
if ((startaddr == 0x18B4 && addr == 0x1A7F && // Zombie, EGA
!strncmp(_vm->_game->_curTotFile, "avt005.tot", 10)) ||
@@ -263,20 +292,19 @@ void Inter::funcBlock(int16 retFlag) {
} // End of workaround
- cmd = *_vm->_global->_inter_execPtr;
+ cmd = _vm->_game->_script->readByte();
if ((cmd >> 4) >= 12) {
cmd2 = 16 - (cmd >> 4);
cmd &= 0xF;
} else
cmd2 = 0;
- _vm->_global->_inter_execPtr++;
params.counter++;
if (cmd2 == 0)
cmd >>= 4;
- if (executeFuncOpcode(cmd2, cmd, params))
+ if (executeOpcodeFunc(cmd2, cmd, params))
return;
if (_vm->shouldQuit())
@@ -292,17 +320,17 @@ void Inter::funcBlock(int16 retFlag) {
}
} while (params.counter != params.cmdCount);
- _vm->_global->_inter_execPtr = 0;
+ _vm->_game->_script->setFinished(true);
return;
}
void Inter::callSub(int16 retFlag) {
byte block;
- while (!_vm->shouldQuit() && _vm->_global->_inter_execPtr &&
- (_vm->_global->_inter_execPtr != _vm->_game->_totFileData)) {
+ while (!_vm->shouldQuit() && !_vm->_game->_script->isFinished() &&
+ (_vm->_game->_script->pos() != 0)) {
- block = *_vm->_global->_inter_execPtr;
+ block = _vm->_game->_script->peekByte();
if (block == 1)
funcBlock(retFlag);
else if (block == 2)
@@ -311,7 +339,7 @@ void Inter::callSub(int16 retFlag) {
error("Unknown block type %d in Inter::callSub()", block);
}
- if (_vm->_global->_inter_execPtr == _vm->_game->_totFileData)
+ if (!_vm->_game->_script->isFinished() && (_vm->_game->_script->pos() == 0))
_terminate = 1;
}