diff options
Diffstat (limited to 'engines/gob/inter.cpp')
-rw-r--r-- | engines/gob/inter.cpp | 152 |
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 ¶ms) { + 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 ¶ms) { + 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; } |