diff options
author | johndoe123 | 2015-12-01 13:10:28 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 |
commit | d16ebff3901b3731ec48d6dfda6b91acbdb11ff5 (patch) | |
tree | 4a1fad92cb102f55c56fa703230b4da4f0a48abf | |
parent | f692e0acfbe1e0a2266502348da7576a0c4f89a1 (diff) | |
download | scummvm-rg350-d16ebff3901b3731ec48d6dfda6b91acbdb11ff5.tar.gz scummvm-rg350-d16ebff3901b3731ec48d6dfda6b91acbdb11ff5.tar.bz2 scummvm-rg350-d16ebff3901b3731ec48d6dfda6b91acbdb11ff5.zip |
ILLUSIONS: DUCKMAN: Implement special opcode 160012 and related code
-rw-r--r-- | engines/illusions/duckman/duckman_specialcode.cpp | 74 | ||||
-rw-r--r-- | engines/illusions/duckman/duckman_specialcode.h | 7 | ||||
-rw-r--r-- | engines/illusions/duckman/illusions_duckman.cpp | 27 | ||||
-rw-r--r-- | engines/illusions/duckman/illusions_duckman.h | 1 | ||||
-rw-r--r-- | engines/illusions/duckman/menusystem_duckman.cpp | 2 | ||||
-rw-r--r-- | engines/illusions/duckman/scriptopcodes_duckman.cpp | 11 | ||||
-rw-r--r-- | engines/illusions/menusystem.cpp | 30 | ||||
-rw-r--r-- | engines/illusions/scriptopcodes.cpp | 2 |
8 files changed, 128 insertions, 26 deletions
diff --git a/engines/illusions/duckman/duckman_specialcode.cpp b/engines/illusions/duckman/duckman_specialcode.cpp index 4cb20fc4b0..b23cc44966 100644 --- a/engines/illusions/duckman/duckman_specialcode.cpp +++ b/engines/illusions/duckman/duckman_specialcode.cpp @@ -63,7 +63,10 @@ void DuckmanSpecialCode::init() { SPECIAL(0x0016000A, spcAddPropertyTimer); SPECIAL(0x0016000B, spcSetPropertyTimer); SPECIAL(0x0016000C, spcRemovePropertyTimer); + SPECIAL(0x0016000E, spcInitTeleporterPosition); + SPECIAL(0x0016000F, spcUpdateTeleporterPosition); SPECIAL(0x00160010, spcCenterNewspaper); + SPECIAL(0x00160012, spcStopScreenShaker); SPECIAL(0x00160014, spcUpdateObject272Sequence); SPECIAL(0x0016001C, spcSetCursorInventoryMode); SPECIAL(0x0016001D, spcCenterCurrentScreenText); @@ -152,6 +155,64 @@ void DuckmanSpecialCode::spcRemovePropertyTimer(OpCall &opCall) { _vm->notifyThreadId(opCall._threadId); } +void DuckmanSpecialCode::spcInitTeleporterPosition(OpCall &opCall) { + _teleporterPosition.x = 4; + _teleporterPosition.y = 3; + updateTeleporterProperties(); + _vm->_scriptResource->_properties.set(0x000E007A, false); + _vm->notifyThreadId(opCall._threadId); +} + +void DuckmanSpecialCode::spcUpdateTeleporterPosition(OpCall &opCall) { + // TODO + ARG_BYTE(direction); + int16 deltaX = 0; + int16 deltaY = 0; + uint32 sequenceId = 0; + + Control *control = _vm->getObjectControl(0x400C0); + switch (direction) { + case 1: + if (_teleporterPosition.y > 1) { + deltaY = -1; + sequenceId = 0x60386; + } + break; + case 4: + if (_teleporterPosition.x < 4) { + deltaX = 1; + sequenceId = 0x60387; + } + break; + case 0x10: + if (_teleporterPosition.y < 3) { + deltaY = 1; + sequenceId = 0x60385; + } + break; + case 0x40: + if (_teleporterPosition.x > 1) { + deltaX = -1; + sequenceId = 0x60388; + } + break; + default: + break; + } + + if (sequenceId) { + control->startSequenceActor(sequenceId, 2, opCall._threadId); + _teleporterPosition.x += deltaX; + _teleporterPosition.y += deltaY; + updateTeleporterProperties(); + _vm->_scriptResource->_properties.set(0x000E007A, false); + } else { + _vm->notifyThreadId(opCall._threadId); + } + + _vm->notifyThreadId(opCall._threadId); +} + void DuckmanSpecialCode::spcCenterNewspaper(OpCall &opCall) { Control *control = _vm->getObjectControl(0x40017); control->_flags |= 8; @@ -160,6 +221,11 @@ void DuckmanSpecialCode::spcCenterNewspaper(OpCall &opCall) { _vm->notifyThreadId(opCall._threadId); } +void DuckmanSpecialCode::spcStopScreenShaker(OpCall &opCall) { + _vm->stopScreenShaker(); + _vm->notifyThreadId(opCall._threadId); +} + void DuckmanSpecialCode::spcUpdateObject272Sequence(OpCall &opCall) { byte flags = 0; uint32 sequenceId; @@ -229,4 +295,12 @@ void DuckmanSpecialCode::spcSetTextDuration(OpCall &opCall) { _vm->notifyThreadId(opCall._threadId); } +void DuckmanSpecialCode::updateTeleporterProperties() { + _vm->_scriptResource->_properties.set(0x000E0074, _teleporterPosition.x == 4 && _teleporterPosition.y == 2); + _vm->_scriptResource->_properties.set(0x000E0075, _teleporterPosition.x == 4 && _teleporterPosition.y == 3); + _vm->_scriptResource->_properties.set(0x000E0076, _teleporterPosition.x == 3 && _teleporterPosition.y == 3); + _vm->_scriptResource->_properties.set(0x000E0077, _teleporterPosition.x == 2 && _teleporterPosition.y == 2); + _vm->_scriptResource->_properties.set(0x000E0078, _teleporterPosition.x == 1 && _teleporterPosition.y == 1); +} + } // End of namespace Illusions diff --git a/engines/illusions/duckman/duckman_specialcode.h b/engines/illusions/duckman/duckman_specialcode.h index c4dfc3698c..2d05da4dbc 100644 --- a/engines/illusions/duckman/duckman_specialcode.h +++ b/engines/illusions/duckman/duckman_specialcode.h @@ -51,6 +51,8 @@ public: uint _chinesePuzzleIndex; byte _chinesePuzzleAnswers[3]; + Common::Point _teleporterPosition; + PropertyTimers *_propertyTimers; DuckmanInventory *_inventory; @@ -66,13 +68,18 @@ public: void spcAddPropertyTimer(OpCall &opCall); void spcSetPropertyTimer(OpCall &opCall); void spcRemovePropertyTimer(OpCall &opCall); + void spcInitTeleporterPosition(OpCall &opCall); + void spcUpdateTeleporterPosition(OpCall &opCall); void spcCenterNewspaper(OpCall &opCall); + void spcStopScreenShaker(OpCall &opCall); void spcUpdateObject272Sequence(OpCall &opCall); void spcSetCursorInventoryMode(OpCall &opCall); void spcCenterCurrentScreenText(OpCall &opCall); void spcSetDefaultTextCoords(OpCall &opCall); void spcSetTextDuration(OpCall &opCall); + void updateTeleporterProperties(); + }; } // End of namespace Illusions diff --git a/engines/illusions/duckman/illusions_duckman.cpp b/engines/illusions/duckman/illusions_duckman.cpp index f760441495..e4c11bc355 100644 --- a/engines/illusions/duckman/illusions_duckman.cpp +++ b/engines/illusions/duckman/illusions_duckman.cpp @@ -167,6 +167,11 @@ Common::Error IllusionsEngine_Duckman::run() { _scriptResource->_properties.set(0x000E0024, true); #endif +#if 1 + // DEBUG Enterprise + _scriptResource->_blockCounters.set(238, 1); +#endif + while (!shouldQuit()) { runUpdateFunctions(); _system->updateScreen(); @@ -261,12 +266,6 @@ int IllusionsEngine_Duckman::updateScript(uint flags) { if (_screen->isDisplayOn() && !_screen->isFaderActive() && _pauseCtr == 0) { if (_input->pollEvent(kEventAbort)) { startScriptThread(0x00020342, 0); - //testMenu(this);//TODO DEBUG - - //BaseMenu *me = _menuSystem->getMenuById(kDuckmanPauseMenu); - //_menuSystem->openMenu(me); - //_menuSystem->runMenu(0x180002); - } else if (_input->pollEvent(kEventF1)) { startScriptThread(0x0002033F, 0); } @@ -289,6 +288,10 @@ void IllusionsEngine_Duckman::startScreenShaker(uint pointsCount, uint32 duratio (this, &IllusionsEngine_Duckman::updateScreenShaker)); } +void IllusionsEngine_Duckman::stopScreenShaker() { + _screenShaker->_finished = true; +} + int IllusionsEngine_Duckman::updateScreenShaker(uint flags) { if (_pauseCtr > 0 || getCurrentScene() == 0x10038) { _screenShaker->_nextTime = getCurrentTime(); @@ -846,7 +849,8 @@ bool IllusionsEngine_Duckman::findTriggerCause(uint32 sceneId, uint32 verbId, ui void IllusionsEngine_Duckman::reset() { _scriptResource->_blockCounters.clear(); _scriptResource->_properties.clear(); - // TODO script_sub_417FF0(1, 0); + setTextDuration(1, 0); + // TODO resetCursor(); } uint32 IllusionsEngine_Duckman::getObjectActorTypeId(uint32 objectId) { @@ -887,6 +891,8 @@ void IllusionsEngine_Duckman::updateGameState2() { Control *overlappedControl; _cursor._control->_actor->_position = cursorPos; + + debug("IllusionsEngine_Duckman::updateGameState2() #1"); foundOverlapped = _controls->getOverlappedObject(_cursor._control, convMousePos, &overlappedControl, 0); @@ -907,6 +913,7 @@ void IllusionsEngine_Duckman::updateGameState2() { startCursorSequence(); } + debug("IllusionsEngine_Duckman::updateGameState2() #2"); if (trackCursorIndex >= 0) { if (_cursor._actorIndex != 10 && _cursor._actorIndex != 11 && _cursor._actorIndex != 12 && _cursor._actorIndex != 13 && _cursor._actorIndex != 3) _cursor._savedActorIndex = _cursor._actorIndex; @@ -919,6 +926,7 @@ void IllusionsEngine_Duckman::updateGameState2() { foundOverlapped = false; } + debug("IllusionsEngine_Duckman::updateGameState2() #3"); if (foundOverlapped) { if (_cursor._currOverlappedControl != overlappedControl) { int cursorValue2 = 0; @@ -944,7 +952,9 @@ void IllusionsEngine_Duckman::updateGameState2() { _cursor._currOverlappedControl = 0; } + debug("IllusionsEngine_Duckman::updateGameState2() #4"); if (_input->pollEvent(kEventLeftClick)) { + debug("IllusionsEngine_Duckman::updateGameState2() #5"); if (_cursor._currOverlappedControl) { runTriggerCause(_cursor._actorIndex, _cursor._objectId, _cursor._currOverlappedControl->_objectId); } else { @@ -956,6 +966,7 @@ void IllusionsEngine_Duckman::updateGameState2() { runTriggerCause(_cursor._actorIndex, _cursor._objectId, 0x40003); } } else if (_input->pollEvent(kEventRightClick)) { + debug("IllusionsEngine_Duckman::updateGameState2() #6"); if (_cursor._actorIndex != 3 && _cursor._actorIndex != 10 && _cursor._actorIndex != 11 && _cursor._actorIndex != 12 && _cursor._actorIndex != 13) { int newActorIndex = getCursorActorIndex(); if (newActorIndex != _cursor._actorIndex) { @@ -968,12 +979,14 @@ void IllusionsEngine_Duckman::updateGameState2() { } } } else if (_input->pollEvent(kEventInventory)) { + debug("IllusionsEngine_Duckman::updateGameState2() #7"); if (_cursor._field14[0] == 1) { runTriggerCause(1, 0, _scriptResource->getMainActorObjectId()); } else if (_cursor._field14[1] == 1) { runTriggerCause(2, 0, _scriptResource->getMainActorObjectId()); } } + debug("IllusionsEngine_Duckman::updateGameState2() #XXX"); } diff --git a/engines/illusions/duckman/illusions_duckman.h b/engines/illusions/duckman/illusions_duckman.h index 129069aaa0..87520d3a6a 100644 --- a/engines/illusions/duckman/illusions_duckman.h +++ b/engines/illusions/duckman/illusions_duckman.h @@ -108,6 +108,7 @@ public: int updateScript(uint flags); void startScreenShaker(uint pointsCount, uint32 duration, const ScreenShakerPoint *points, uint32 threadId); + void stopScreenShaker(); int updateScreenShaker(uint flags); void startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId); diff --git a/engines/illusions/duckman/menusystem_duckman.cpp b/engines/illusions/duckman/menusystem_duckman.cpp index 96d350ab4b..666005d952 100644 --- a/engines/illusions/duckman/menusystem_duckman.cpp +++ b/engines/illusions/duckman/menusystem_duckman.cpp @@ -40,6 +40,8 @@ DuckmanMenuSystem::~DuckmanMenuSystem() { void DuckmanMenuSystem::runMenu(MenuChoiceOffsets menuChoiceOffsets, int16 *menuChoiceOffset, uint32 menuId, uint32 duration, uint timeOutMenuChoiceIndex, uint32 menuCallerThreadId) { + + debug("DuckmanMenuSystem::runMenu(%08X)", menuId); setTimeOutDuration(duration, timeOutMenuChoiceIndex); setMenuCallerThreadId(menuCallerThreadId); diff --git a/engines/illusions/duckman/scriptopcodes_duckman.cpp b/engines/illusions/duckman/scriptopcodes_duckman.cpp index ffd1645559..382a128fe9 100644 --- a/engines/illusions/duckman/scriptopcodes_duckman.cpp +++ b/engines/illusions/duckman/scriptopcodes_duckman.cpp @@ -204,7 +204,8 @@ void ScriptOpcodes_Duckman::opStartTimerThread(ScriptThread *scriptThread, OpCal duration += _vm->getRandom(maxDuration); //duration = 1;//DEBUG Speeds up things -duration = 5; +//duration = 5; +debug("duration: %d", duration); if (isAbortable) _vm->startAbortableTimerThread(duration, opCall._threadId); @@ -258,7 +259,7 @@ void ScriptOpcodes_Duckman::opUnloadResourcesBySceneId(ScriptThread *scriptThrea //static uint dsceneId = 0, dthreadId = 0; //static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac -static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front +//static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front //static uint dsceneId = 0x0001000E, dthreadId = 0x0002007C; //static uint dsceneId = 0x00010012, dthreadId = 0x0002009D;//Paramount //static uint dsceneId = 0x00010020, dthreadId = 0x00020112;//Xmas @@ -273,6 +274,7 @@ static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front //static uint dsceneId = 0x0001005B, dthreadId = 0x00020341; //static uint dsceneId = 0x00010010, dthreadId = 0x0002008A; //static uint dsceneId = 0x10002, dthreadId = 0x20001;//Debug menu, not supported +static uint dsceneId = 0x10044, dthreadId = 0x000202B8; // Starship Enterprise void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) { ARG_SKIP(2); @@ -283,13 +285,13 @@ void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &op debug(1, "changeScene(%08X, %08X)", sceneId, threadId); //DEBUG - /* +#if 1 if (dsceneId) { sceneId = dsceneId; threadId = dthreadId; dsceneId = 0; } - */ +#endif if (_vm->_scriptResource->_properties.get(31)) { _vm->changeScene(0x10002, 0x20001, opCall._callerThreadId); @@ -645,6 +647,7 @@ void ScriptOpcodes_Duckman::opDisplayMenu(ScriptThread *scriptThread, OpCall &op ARG_UINT32(menuId); ARG_UINT32(timeOutMenuChoiceIndex); + debug("menuId: %08X", menuId); debug("timeOutMenuChoiceIndex: %d", timeOutMenuChoiceIndex); MenuChoiceOffsets menuChoiceOffsets; diff --git a/engines/illusions/menusystem.cpp b/engines/illusions/menusystem.cpp index f26a461223..01b92208d8 100644 --- a/engines/illusions/menusystem.cpp +++ b/engines/illusions/menusystem.cpp @@ -105,6 +105,8 @@ void BaseMenuSystem::playSoundEffect14() { } void BaseMenuSystem::selectMenuChoiceIndex(uint choiceIndex) { + debug("choiceIndex: %d", choiceIndex); + debug("_menuChoiceOffset: %p", (void*)_menuChoiceOffset); if (choiceIndex > 0 && _menuChoiceOffset) { *_menuChoiceOffset = _menuChoiceOffsets[choiceIndex - 1]; debug(0, "*_menuChoiceOffset: %04X", *_menuChoiceOffset); @@ -211,7 +213,7 @@ bool BaseMenuSystem::calcMenuItemIndexAtPoint(Common::Point pt, uint &menuItemIn } void BaseMenuSystem::setMousePos(Common::Point &mousePos) { - _vm->_input->setCursorPosition(mousePos); + //TODO Strange behavior _vm->_input->setCursorPosition(mousePos); Control *mouseCursor = _vm->getObjectControl(0x40004); mouseCursor->_actor->_position = mousePos; } @@ -372,6 +374,7 @@ void BaseMenuSystem::closeMenu() { } void BaseMenuSystem::handleClick(uint menuItemIndex, const Common::Point &mousePos) { + debug("BaseMenuSystem::handleClick() menuItemIndex: %d", menuItemIndex); if (menuItemIndex == 0) { playSoundEffect14(); @@ -439,15 +442,17 @@ void BaseMenuSystem::update(Control *cursorControl) { uint newHoveredMenuItemIndex; bool resetTimeOut = false; - if (calcMenuItemIndexAtPoint(mousePos, newHoveredMenuItemIndex) && newHoveredMenuItemIndex != _hoveredMenuItemIndex) { - if (_hoveredMenuItemIndex == 0) - initActor318(); - _hoveredMenuItemIndex = newHoveredMenuItemIndex; - _hoveredMenuItemIndex2 = newHoveredMenuItemIndex; - setMenuCursorNum(2); - updateActor318(); - resetTimeOut = true; - } else if (_hoveredMenuItemIndex == 0) { + if (calcMenuItemIndexAtPoint(mousePos, newHoveredMenuItemIndex)) { + if (newHoveredMenuItemIndex != _hoveredMenuItemIndex) { + if (_hoveredMenuItemIndex == 0) + initActor318(); + _hoveredMenuItemIndex = newHoveredMenuItemIndex; + _hoveredMenuItemIndex2 = newHoveredMenuItemIndex; + setMenuCursorNum(2); + updateActor318(); + resetTimeOut = true; + } + } else if (_hoveredMenuItemIndex != 0) { setMenuCursorNum(1); hideActor318(); _hoveredMenuItemIndex = 0; @@ -511,12 +516,9 @@ void BaseMenuSystem::updateTimeOut(bool resetTimeOut) { _timeOutStartTime = getCurrentTime(); _timeOutEndTime = _timeOutDuration + _timeOutStartTime; } else if (isTimerExpired(_timeOutStartTime, _timeOutEndTime)) { + debug("timeout reached"); _isTimeOutEnabled = false; selectMenuChoiceIndex(_timeOutMenuChoiceIndex); - // TODO *_menuChoiceOffset = *((_WORD *)&_menuCallerThreadId + _timeOutMenuChoiceIndex + 1); - //_vm->_threads->notifyId(_menuCallerThreadId); - //_menuCallerThreadId = 0; - //closeMenu(); } } diff --git a/engines/illusions/scriptopcodes.cpp b/engines/illusions/scriptopcodes.cpp index 38fdbec3ce..7d515a8109 100644 --- a/engines/illusions/scriptopcodes.cpp +++ b/engines/illusions/scriptopcodes.cpp @@ -62,7 +62,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); } |