diff options
Diffstat (limited to 'engines/illusions/scriptopcodes.cpp')
-rw-r--r-- | engines/illusions/scriptopcodes.cpp | 132 |
1 files changed, 122 insertions, 10 deletions
diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index 72c455ad08..a40429b5b0 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -66,9 +66,9 @@ ScriptOpcodes::~ScriptOpcodes() { } void ScriptOpcodes::execOpcode(ScriptThread *scriptThread, OpCall &opCall) { + debug("\nexecOpcode([%08X] %d)", opCall._callerThreadId, opCall._op); if (!_opcodes[opCall._op]) error("ScriptOpcodes::execOpcode() Unimplemented opcode %d", opCall._op); - debug("\nexecOpcode(%d)", opCall._op); (*_opcodes[opCall._op])(scriptThread, opCall); } @@ -90,6 +90,7 @@ void ScriptOpcodes::initOpcodes() { OPCODE(14, opSetThreadSceneId); OPCODE(16, opLoadResource); OPCODE(20, opEnterScene); + OPCODE(25, opChangeScene); OPCODE(39, opSetDisplay); OPCODE(42, opIncBlockCounter); OPCODE(45, opSetProperty); @@ -97,19 +98,27 @@ void ScriptOpcodes::initOpcodes() { OPCODE(49, opStartSequenceActor); OPCODE(57, opAppearActor); OPCODE(58, opDisappearActor); + OPCODE(61, opDeactivateObject); OPCODE(63, opSetSelectSfx); OPCODE(64, opSetMoveSfx); OPCODE(65, opSetDenySfx); OPCODE(66, opSetAdjustUpSfx); OPCODE(67, opSetAdjustDnSfx); OPCODE(75, opStartMusic); + OPCODE(80, opAddMenuChoice); + OPCODE(81, opDisplayMenu); + OPCODE(82, opSwitchMenuChoice); + OPCODE(84, opResetGame); OPCODE(87, opDeactivateButton); OPCODE(88, opActivateButton); OPCODE(103, opJumpIf); + OPCODE(110, opGetProperty); + OPCODE(111, opCompareBlockCounter); OPCODE(126, opDebug126); OPCODE(144, opPlayVideo); OPCODE(148, opLoadSpecialCodeModule); OPCODE(150, opRunSpecialCode); + OPCODE(161, opSetActorUsePan); OPCODE(175, opSetSceneIdThreadId); OPCODE(176, opStackPush0); OPCODE(177, opSetFontId); @@ -198,25 +207,39 @@ void ScriptOpcodes::opEnterScene(ScriptThread *scriptThread, OpCall &opCall) { _vm->_scriptMan->_activeScenes.getActiveSceneInfo(scenesCount - 1, &currSceneId, 0); // TODO krnfileDump(currSceneId); } - if (!_vm->_scriptMan->enterScene(sceneId, opCall._threadId)) + if (!_vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId)) opCall._result = kTSTerminate; } +void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(sceneId); + ARG_UINT32(threadId); + // NOTE Skipped checking for stalled resources + _vm->_input->discardButtons(0xFFFF); + _vm->_scriptMan->_prevSceneId = _vm->_scriptMan->_activeScenes.getCurrentScene(); + _vm->_scriptMan->exitScene(opCall._callerThreadId); + _vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId); + // TODO _vm->_gameStates->writeStates(_vm->_scriptMan->_prevSceneId, sceneId, threadId); + _vm->_scriptMan->startAnonScriptThread(threadId, 0, + scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10); +} + void ScriptOpcodes::opSetDisplay(ScriptThread *scriptThread, OpCall &opCall) { ARG_INT16(flag); _vm->_screen->setDisplayOn(flag != 0); } void ScriptOpcodes::opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall) { - ARG_INT16(index) - byte value = _vm->_scriptMan->_scriptResource->_blockCounters.get(index + 1); + ARG_INT16(index); + byte value = _vm->_scriptMan->_scriptResource->_blockCounters.get(index) + 1; if (value <= 63) - _vm->_scriptMan->_scriptResource->_blockCounters.set(index + 1, value); + _vm->_scriptMan->_scriptResource->_blockCounters.set(index, value); } void ScriptOpcodes::opSetProperty(ScriptThread *scriptThread, OpCall &opCall) { - ARG_INT16(value) - ARG_INT16(propertyId) + ARG_INT16(value); + ARG_UINT32(propertyId); // TODO _vm->_scriptMan->_scriptResource->_properties.set(propertyId, value); } @@ -259,6 +282,14 @@ void ScriptOpcodes::opDisappearActor(ScriptThread *scriptThread, OpCall &opCall) control->disappearActor(); } +void ScriptOpcodes::opDeactivateObject(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(objectId); + Control *control = _vm->_dict->getObjectControl(objectId); + if (control) + control->deactivateObject(); +} + void ScriptOpcodes::opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(soundEffectId); @@ -290,13 +321,51 @@ void ScriptOpcodes::opSetAdjustDnSfx(ScriptThread *scriptThread, OpCall &opCall) } void ScriptOpcodes::opStartMusic(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); - ARG_INT16(volume) - ARG_INT16(pan) + ARG_INT16(volume); + ARG_INT16(pan); ARG_UINT32(musicId); ARG_UINT32(type); // TODO _vm->playMusic(musicId, type, volume, pan); } +void ScriptOpcodes::opAddMenuChoice(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_INT16(jumpOffs); + ARG_INT16(endMarker); + _vm->_scriptMan->_stack.push(endMarker); + _vm->_scriptMan->_stack.push(jumpOffs); +} + +void ScriptOpcodes::opDisplayMenu(ScriptThread *scriptThread, OpCall &opCall) { + ARG_INT16(unk1); + ARG_UINT32(menuId); + ARG_UINT32(unk2); + // TODO _vm->_shellMgr->displayMenu(_vm->_scriptMan->_stack.topPtr(), &_vm->_scriptMan->_menuChoiceOfs, menuId, unk1, unk2, opCall._callerThreadId); + // Remove menu choices from the stack + do { + _vm->_scriptMan->_stack.pop(); + } while (_vm->_scriptMan->_stack.pop() == 0); + + //DEBUG Resume calling thread, later done by the video player + _vm->notifyThreadId(opCall._callerThreadId); + +} + +void ScriptOpcodes::opSwitchMenuChoice(ScriptThread *scriptThread, OpCall &opCall) { +_vm->_scriptMan->_menuChoiceOfs = 88; // DEBUG Chose "Start game" + + opCall._deltaOfs += _vm->_scriptMan->_menuChoiceOfs; +debug("deltaOfs = %08X", opCall._deltaOfs); +} + +void ScriptOpcodes::opResetGame(ScriptThread *scriptThread, OpCall &opCall) { + _vm->_scriptMan->_threads->terminateThreads(opCall._callerThreadId); + _vm->_scriptMan->reset(); + _vm->_input->activateButton(0xFFFF); + // TODO _vm->stopMusic(); + // TODO _vm->_gameStates->clear(); +} + void ScriptOpcodes::opDeactivateButton(ScriptThread *scriptThread, OpCall &opCall) { ARG_INT16(button) _vm->_input->deactivateButton(button); @@ -314,6 +383,42 @@ void ScriptOpcodes::opJumpIf(ScriptThread *scriptThread, OpCall &opCall) { opCall._deltaOfs += jumpOffs; } +void ScriptOpcodes::opGetProperty(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(propertyId) + int16 value = 0;// TODO _vm->_scriptMan->_scriptResource->_properties.get(propertyId); + _vm->_scriptMan->_stack.push(value); +} + +void ScriptOpcodes::opCompareBlockCounter(ScriptThread *scriptThread, OpCall &opCall) { + ARG_INT16(index); + ARG_INT16(compareOp); + ARG_INT16(rvalue); + int16 lvalue = _vm->_scriptMan->_scriptResource->_blockCounters.get(index); + bool compareResult = false; + switch (compareOp) { + case 1: + compareResult = lvalue == rvalue; + break; + case 2: + compareResult = lvalue != rvalue; + break; + case 3: + compareResult = lvalue < rvalue; + break; + case 4: + compareResult = lvalue > rvalue; + break; + case 5: + compareResult = lvalue >= rvalue; + break; + case 6: + compareResult = lvalue <= rvalue; + break; + } + _vm->_scriptMan->_stack.push(compareResult ? 1 : 0); +} + void ScriptOpcodes::opDebug126(ScriptThread *scriptThread, OpCall &opCall) { // NOTE Prints some debug text debug("[DBG] %s", (char*)opCall._code); @@ -345,10 +450,17 @@ void ScriptOpcodes::opRunSpecialCode(ScriptThread *scriptThread, OpCall &opCall) _vm->_scriptMan->_callerThreadId = 0; //DEBUG Resume calling thread, later done by the special code - _vm->notifyThreadId(opCall._threadId); + _vm->notifyThreadId(opCall._callerThreadId); } +void ScriptOpcodes::opSetActorUsePan(ScriptThread *scriptThread, OpCall &opCall) { + ARG_INT16(usePan) + ARG_UINT32(objectId); + Control *control = _vm->_dict->getObjectControl(objectId); + control->setActorUsePan(usePan); +} + void ScriptOpcodes::opSetSceneIdThreadId(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(sceneId); |