diff options
Diffstat (limited to 'kyra/script_v1.cpp')
-rw-r--r-- | kyra/script_v1.cpp | 354 |
1 files changed, 201 insertions, 153 deletions
diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp index 7ae03be931..2f8252ea1a 100644 --- a/kyra/script_v1.cpp +++ b/kyra/script_v1.cpp @@ -24,219 +24,267 @@ #include "kyra/script.h" namespace Kyra { -// Command procs -void VMContext::c1_unknownCommand(void) { - debug("unknown command '0x%x'.", _currentCommand); - debug("\targument: '0x%x'", _argument); - - _error = true; -} - -void VMContext::c1_goToLine(void) { - _instructionPos = _argument << 1; +void ScriptHelper::c1_jmpTo() { + _curScript->ip = _curScript->dataPtr->data + (_parameter << 1); } -void VMContext::c1_setReturn(void) { - _returnValue = _argument; +void ScriptHelper::c1_setRetValue() { + _curScript->retValue = _parameter; } -void VMContext::c1_pushRetRec(void) { - if (!_argument) { - pushStack(_returnValue); - } else { - int32 rec = ((int16)_tempPos << 16) | ((_instructionPos >> 1) + 1); - pushStack(rec); - _tempPos = _instructionPos; +void ScriptHelper::c1_pushRetOrPos() { + switch (_parameter) { + case 0: + _curScript->stack[--_curScript->sp] = _curScript->retValue; + break; + + case 1: + _curScript->stack[--_curScript->sp] = (_curScript->ip - _curScript->dataPtr->data) / 2 + 1; + _curScript->stack[--_curScript->sp] = _curScript->bp; + _curScript->bp = _curScript->sp + 2; + break; + + default: + _continue = false; + _curScript->ip = 0; + break; } } -void VMContext::c1_push(void) { - pushStack(_argument); +void ScriptHelper::c1_push() { + _curScript->stack[--_curScript->sp] = _parameter; } -void VMContext::c1_pushVar(void) { - pushStack(_registers[_argument]); +void ScriptHelper::c1_pushVar() { + _curScript->stack[--_curScript->sp] = _curScript->variables[_parameter]; } -void VMContext::c1_pushFrameNeg(void) { - pushStack(_stack[_tempPos + _argument]); +void ScriptHelper::c1_pushBPNeg() { + _curScript->stack[--_curScript->sp] = _curScript->stack[(-(_parameter + 2)) + _curScript->bp]; } -void VMContext::c1_pushFramePos(void) { - pushStack(_stack[_tempPos - _argument]); +void ScriptHelper::c1_pushBPAdd() { + _curScript->stack[--_curScript->sp] = _curScript->stack[(_parameter - 1) + _curScript->bp]; } -void VMContext::c1_popRetRec(void) { - if (!_argument) { - _returnValue = popStack(); - } else { - if (_stackPos <= 0) { - _scriptState = kScriptStopped; - } - int32 rec = popStack(); - - _tempPos = (int16)((rec & 0xFFFF0000) >> 16); - _instructionPos = (rec & 0x0000FFFF) * 2; +void ScriptHelper::c1_popRetOrPos() { + switch (_parameter) { + case 0: + _curScript->retValue = _curScript->stack[++_curScript->sp-1]; + break; + + case 1: + if (_curScript->sp >= 60) { + _continue = false; + _curScript->ip = 0; + } else { + _curScript->bp = _curScript->stack[++_curScript->sp-1]; + _curScript->ip = _curScript->dataPtr->data + (_curScript->stack[++_curScript->sp-1] << 1); + } + break; + + default: + _continue = false; + _curScript->ip = 0; + break; } } -void VMContext::c1_popVar(void) { - _registers[_argument] = popStack(); +void ScriptHelper::c1_popVar() { + _curScript->variables[_parameter] = _curScript->stack[++_curScript->sp-1]; } -void VMContext::c1_popFrameNeg(void) { - _stack[_tempPos + _argument] = popStack(); +void ScriptHelper::c1_popBPNeg() { + _curScript->stack[(-(_parameter + 2)) + _curScript->bp] = _curScript->stack[++_curScript->sp-1]; } -void VMContext::c1_popFramePos(void) { - _stack[_tempPos - _argument] = popStack(); +void ScriptHelper::c1_popBPAdd() { + _curScript->stack[(_parameter - 1) + _curScript->bp] = _curScript->stack[++_curScript->sp-1]; } -void VMContext::c1_addToSP(void) { - _stackPos -= _argument; +void ScriptHelper::c1_addSP() { + _curScript->sp += _parameter; } -void VMContext::c1_subFromSP(void) { - _stackPos += _argument; +void ScriptHelper::c1_subSP() { + _curScript->sp -= _parameter; } -void VMContext::c1_execOpcode(void) { - if (_argument < _numOpcodes) { - OpcodeProc proc = _opcodes[_argument].proc; - (this->*proc)(); - } else { - error("Invalid opcode 0x%X", _argument); - } +void ScriptHelper::c1_execOpcode() { + warning("c1_execOpcode STUB"); + // return 0 zero for now + _curScript->retValue = 0; } -void VMContext::c1_ifNotGoTo(void) { - if (!popStack()) { - _instructionPos = _argument << 1; +void ScriptHelper::c1_ifNotJmp() { + if (_curScript->stack[++_curScript->sp-1] != 0) { + _parameter &= 0x7FFF; + _curScript->ip = _curScript->dataPtr->data + (_parameter << 1); } } -void VMContext::c1_negate(void) { - switch(_argument) { - case 0: - topStack() = !topStack(); +void ScriptHelper::c1_negate() { + int16 value = _curScript->stack[_curScript->sp]; + switch (_parameter) { + case 0: + if (!value) { + _curScript->stack[_curScript->sp] = 0; + } else { + _curScript->stack[_curScript->sp] = 1; + } break; - - case 1: - topStack() = -topStack(); + + case 1: + _curScript->stack[_curScript->sp] = -value; break; - - case 2: - topStack() = ~topStack(); + + case 2: + _curScript->stack[_curScript->sp] = ~value; break; - - default: - debug("unkown negate instruction %d", _argument); - _error = true; + + default: + _continue = false; break; - }; + } } -void VMContext::c1_evaluate(void) { - int32 x, y; - int32 res = false; - - x = popStack(); - y = popStack(); - - switch(_argument) { - case 0: - res = x && y; +void ScriptHelper::c1_eval() { + int16 ret = 0; + bool error = false; + + int16 val1 = _curScript->stack[++_curScript->sp-1]; + int16 val2 = _curScript->stack[++_curScript->sp-1]; + + switch (_parameter) { + case 0: + if (!val2 || !val1) { + ret = 0; + } else { + ret = 1; + } break; - - case 1: - res = x || y; + + case 1: + if (val2 || val1) { + ret = 1; + } else { + ret = 0; + } break; - - case 3: - res = x != y; + + case 2: + if (val1 == val2) { + ret = 1; + } else { + ret = 0; + } break; - - case 4: - res = x < y; + + case 3: + if (val1 != val2) { + ret = 1; + } else { + ret = 0; + } break; - - case 5: - res = x <= y; + + case 4: + if (val1 > val2) { + ret = 1; + } else { + ret = 0; + } break; - - case 6: - res = x > y; + + case 5: + if (val1 >= val2) { + ret = 1; + } else { + ret = 0; + } break; - - case 7: - res = x >= y; + + case 6: + if (val1 < val2) { + ret = 1; + } else { + ret = 0; + } break; - - case 8: - res = x + y; + + case 7: + if (val1 <= val2) { + ret = 1; + } else { + ret = 0; + } break; - - case 9: - res = x - y; + + case 8: + ret = val1 + val2; break; - - case 10: - res = x * y; + + case 9: + ret = val2 - val1; break; - - case 11: - res = x / y; + + case 10: + ret = val1 * val2; break; - - case 12: - res = x >> y; + + case 11: + ret = val2 / val1; break; - - case 13: - res = x << y; + + case 12: + ret = val2 >> val1; break; - - case 14: - res = x & y; + + case 13: + ret = val2 << val1; break; - - case 15: - res = x | y; + + case 14: + ret = val1 & val2; break; - - case 16: - res = x % y; + + case 15: + ret = val1 | val2; break; - - case 17: - res = x ^ y; + + case 16: + ret = val2 % val1; break; - - default: - debug("unknown evaluate command"); + + case 17: + ret = val1 ^ val2; break; - }; - - pushStack(res); + + default: + warning("Unknown evaluate func: %d", _parameter); + error = true; + break; + } + + if (error) { + _curScript->ip = 0; + _continue = false; + } else { + _curScript->stack[--_curScript->sp] = ret; + } } -// opcode procs -void VMContext::o1_unknownOpcode(void) { - _error = true; - - debug("unknown opcode '0x%x'.", _argument); - debug("parameters:\n" - "Param0: %d\nParam1: %d\nParam2: %d\nParam3: %d\nParam4: %d\nParam5: %d\n" - "Param0 as a string: %s\nParam1 as a string: %s\nParam2 as a string: %s\n" - "Param3 as a string: %s\nParam4 as a string: %s\nParam5 as a string: %s\n", - param(0), param(1), param(2), param(3), param(5), param(5), - paramString(0), paramString(1), paramString(2), paramString(3), - paramString(4), paramString(5)); +void ScriptHelper::c1_setRetAndJmp() { + if (_curScript->sp >= 60) { + _continue = false; + _curScript->ip = 0; + } else { + _curScript->retValue = _curScript->stack[++_curScript->sp-1]; + uint16 temp = _curScript->stack[++_curScript->sp-1]; + _curScript->stack[60] = 0; + _curScript->ip = &_curScript->dataPtr->data[temp*2]; + } } -void VMContext::o1_0x68(void) { - debug("o1_0x68 was called with param0: '0x%x'", param(0)); - _error = true; -} } // end of namespace Kyra |