aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232015-12-01 13:10:28 +0100
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commitd16ebff3901b3731ec48d6dfda6b91acbdb11ff5 (patch)
tree4a1fad92cb102f55c56fa703230b4da4f0a48abf
parentf692e0acfbe1e0a2266502348da7576a0c4f89a1 (diff)
downloadscummvm-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.cpp74
-rw-r--r--engines/illusions/duckman/duckman_specialcode.h7
-rw-r--r--engines/illusions/duckman/illusions_duckman.cpp27
-rw-r--r--engines/illusions/duckman/illusions_duckman.h1
-rw-r--r--engines/illusions/duckman/menusystem_duckman.cpp2
-rw-r--r--engines/illusions/duckman/scriptopcodes_duckman.cpp11
-rw-r--r--engines/illusions/menusystem.cpp30
-rw-r--r--engines/illusions/scriptopcodes.cpp2
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);
}