diff options
Diffstat (limited to 'engines/illusions/scriptopcodes.cpp')
| -rw-r--r-- | engines/illusions/scriptopcodes.cpp | 125 |
1 files changed, 116 insertions, 9 deletions
diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index 8abfa8b63b..abfda679c7 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -23,6 +23,7 @@ #include "illusions/illusions.h" #include "illusions/scriptopcodes.h" #include "illusions/actor.h" +#include "illusions/camera.h" #include "illusions/dictionary.h" #include "illusions/input.h" #include "illusions/screen.h" @@ -69,7 +70,7 @@ ScriptOpcodes::~ScriptOpcodes() { void ScriptOpcodes::execOpcode(ScriptThread *scriptThread, OpCall &opCall) { if (!_opcodes[opCall._op]) error("ScriptOpcodes::execOpcode() Unimplemented opcode %d", opCall._op); - debug("\nexecOpcode([%08X] %d) %s", opCall._callerThreadId, opCall._op, _opcodeNames[opCall._op].c_str()); + debug(0, "\nexecOpcode([%08X] %d) %s", opCall._callerThreadId, opCall._op, _opcodeNames[opCall._op].c_str()); (*_opcodes[opCall._op])(scriptThread, opCall); } @@ -96,18 +97,27 @@ void ScriptOpcodes::initOpcodes() { OPCODE(17, opUnloadResource); OPCODE(20, opEnterScene); OPCODE(25, opChangeScene); + OPCODE(26, opStartModalScene); OPCODE(30, opEnterCloseUpScene); OPCODE(31, opExitCloseUpScene); + OPCODE(32, opPanCenterObject); + OPCODE(35, opPanToNamedPoint); + OPCODE(37, opPanStop); OPCODE(39, opSetDisplay); OPCODE(42, opIncBlockCounter); OPCODE(45, opSetProperty); - OPCODE(46, opPlaceActor); + OPCODE(46, opPlaceActor); + OPCODE(47, opFaceActor); + OPCODE(48, opFaceActorToObject); OPCODE(49, opStartSequenceActor); + OPCODE(51, opStartMoveActor); + OPCODE(53, opSetActorToNamedPoint); OPCODE(56, opStartTalkThread); OPCODE(57, opAppearActor); OPCODE(58, opDisappearActor); OPCODE(60, opActivateObject); OPCODE(61, opDeactivateObject); + OPCODE(62, opSetDefaultSequence); OPCODE(63, opSetSelectSfx); OPCODE(64, opSetMoveSfx); OPCODE(65, opSetDenySfx); @@ -126,7 +136,9 @@ void ScriptOpcodes::initOpcodes() { OPCODE(87, opDeactivateButton); OPCODE(88, opActivateButton); OPCODE(103, opJumpIf); - OPCODE(107, opBoolNot); + OPCODE(107, opNot); + OPCODE(108, opAnd); + OPCODE(109, opOr); OPCODE(110, opGetProperty); OPCODE(111, opCompareBlockCounter); OPCODE(126, opDebug126); @@ -156,8 +168,8 @@ void ScriptOpcodes::freeOpcodes() { // Convenience macros #define ARG_SKIP(x) opCall.skip(x); -#define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name); -#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %08X)", name); +#define ARG_INT16(name) int16 name = opCall.readSint16(); debug(0, "ARG_INT16(" #name " = %d)", name); +#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug(0, "ARG_UINT32(" #name " = %08X)", name); void ScriptOpcodes::opSuspend(ScriptThread *scriptThread, OpCall &opCall) { opCall._result = kTSSuspend; @@ -218,7 +230,7 @@ void ScriptOpcodes::opLoadResource(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(resourceId); // NOTE Skipped checking for stalled resources - uint32 sceneId = _vm->_scriptMan->_activeScenes.getCurrentScene(); + uint32 sceneId = _vm->getCurrentScene(); _vm->_resSys->loadResource(resourceId, sceneId, opCall._threadId); } @@ -248,7 +260,7 @@ void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) { ARG_UINT32(threadId); // NOTE Skipped checking for stalled resources _vm->_input->discardButtons(0xFFFF); - _vm->_scriptMan->_prevSceneId = _vm->_scriptMan->_activeScenes.getCurrentScene(); + _vm->_scriptMan->_prevSceneId = _vm->getCurrentScene(); _vm->_scriptMan->exitScene(opCall._callerThreadId); _vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId); // TODO _vm->_gameStates->writeStates(_vm->_scriptMan->_prevSceneId, sceneId, threadId); @@ -256,6 +268,20 @@ void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) { scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10); } +void ScriptOpcodes::opStartModalScene(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->enterPause(opCall._callerThreadId); + // TODO _vm->_talkItems->pauseByTag(_vm->getCurrentScene()); + _vm->_scriptMan->enterScene(sceneId, opCall._callerThreadId); + _vm->_scriptMan->startScriptThread(threadId, 0, + scriptThread->_value8, scriptThread->_valueC, scriptThread->_value10); + opCall._result = kTSSuspend; +} + void ScriptOpcodes::opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(sceneId); @@ -271,6 +297,23 @@ void ScriptOpcodes::opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCal opCall._result = kTSYield; } +void ScriptOpcodes::opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall) { + ARG_INT16(speed); + ARG_UINT32(objectId); + _vm->_camera->panCenterObject(objectId, speed); +} + +void ScriptOpcodes::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) { + ARG_INT16(speed); + ARG_UINT32(namedPointId); + Common::Point pos = _vm->getNamedPointPosition(namedPointId); + _vm->_camera->panToPoint(pos, speed, opCall._callerThreadId); +} + +void ScriptOpcodes::opPanStop(ScriptThread *scriptThread, OpCall &opCall) { + _vm->_camera->stopPan(); +} + void ScriptOpcodes::opSetDisplay(ScriptThread *scriptThread, OpCall &opCall) { ARG_INT16(flag); _vm->_screen->setDisplayOn(flag != 0); @@ -299,16 +342,59 @@ void ScriptOpcodes::opPlaceActor(ScriptThread *scriptThread, OpCall &opCall) { _vm->_controls->placeActor(actorTypeId, pos, sequenceId, objectId, opCall._threadId); } +void ScriptOpcodes::opFaceActor(ScriptThread *scriptThread, OpCall &opCall) { + ARG_INT16(facing); + ARG_UINT32(objectId); + Control *control = _vm->_dict->getObjectControl(objectId); + control->faceActor(facing); +} + +void ScriptOpcodes::opFaceActorToObject(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(objectId1); + ARG_UINT32(objectId2); + Control *control1 = _vm->_dict->getObjectControl(objectId1); + Control *control2 = _vm->_dict->getObjectControl(objectId2); + Common::Point pos1 = control1->getActorPosition(); + Common::Point pos2 = control2->getActorPosition(); + uint facing; + if (_vm->calcPointDirection(pos1, pos2, facing)) + control1->faceActor(facing); +} + void ScriptOpcodes::opStartSequenceActor(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(objectId); ARG_UINT32(sequenceId); // NOTE Skipped checking for stalled sequence, not sure if needed Control *control = _vm->_dict->getObjectControl(objectId); - debug("control: %p", (void*)control); control->startSequenceActor(sequenceId, 2, opCall._threadId); } +void ScriptOpcodes::opStartMoveActor(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(objectId); + ARG_UINT32(sequenceId); + ARG_UINT32(namedPointId); + // NOTE Skipped checking for stalled sequence, not sure if needed + Control *control = _vm->_dict->getObjectControl(objectId); + Common::Point pos = _vm->getNamedPointPosition(namedPointId); + // TODO _control->startMoveActor(sequenceId, pos, opCall._callerThreadId, opCall._threadId); + + //DEBUG Resume calling thread, later done by the walking + _vm->notifyThreadId(opCall._threadId); +} + +void ScriptOpcodes::opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(objectId); + ARG_UINT32(namedPointId); + Control *control = _vm->_dict->getObjectControl(objectId); + Common::Point pos = _vm->getNamedPointPosition(namedPointId); + control->stopActor(); + control->setActorPosition(pos); +} + void ScriptOpcodes::opStartTalkThread(ScriptThread *scriptThread, OpCall &opCall) { ARG_INT16(duration); ARG_UINT32(objectId); @@ -358,6 +444,15 @@ void ScriptOpcodes::opDeactivateObject(ScriptThread *scriptThread, OpCall &opCal control->deactivateObject(); } +void ScriptOpcodes::opSetDefaultSequence(ScriptThread *scriptThread, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(objectId); + ARG_UINT32(defaultSequenceId); + ARG_UINT32(sequenceId); + Control *control = _vm->_dict->getObjectControl(objectId); + control->_actor->_defaultSequences.set(sequenceId, defaultSequenceId); +} + void ScriptOpcodes::opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(soundEffectId); @@ -482,11 +577,23 @@ void ScriptOpcodes::opJumpIf(ScriptThread *scriptThread, OpCall &opCall) { opCall._deltaOfs += jumpOffs; } -void ScriptOpcodes::opBoolNot(ScriptThread *scriptThread, OpCall &opCall) { +void ScriptOpcodes::opNot(ScriptThread *scriptThread, OpCall &opCall) { int16 value = _vm->_scriptMan->_stack.pop(); _vm->_scriptMan->_stack.push(value != 0 ? 0 : 1); } +void ScriptOpcodes::opAnd(ScriptThread *scriptThread, OpCall &opCall) { + int16 value1 = _vm->_scriptMan->_stack.pop(); + int16 value2 = _vm->_scriptMan->_stack.pop(); + _vm->_scriptMan->_stack.push(value1 & value2); +} + +void ScriptOpcodes::opOr(ScriptThread *scriptThread, OpCall &opCall) { + int16 value1 = _vm->_scriptMan->_stack.pop(); + int16 value2 = _vm->_scriptMan->_stack.pop(); + _vm->_scriptMan->_stack.push(value1 | value2); +} + void ScriptOpcodes::opGetProperty(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); ARG_UINT32(propertyId) |
