diff --git a/engines/myst3/script.cpp b/engines/myst3/script.cpp index e34ec31ab22..79522f701d9 100644 --- a/engines/myst3/script.cpp +++ b/engines/myst3/script.cpp @@ -1886,54 +1886,77 @@ void Script::runScriptWhileDragging(Context &c, const Opcode &cmd) { _vm->_cursor->changeCursor(2); - bool mousePressed = true; + bool dragWithDirectionKeys = _vm->_state->hasVarDragWithDirectionKeys() + && _vm->_state->getDragWithDirectionKeys(); + + bool dragging = true; do { - mousePressed = _vm->getEventManager()->getButtonState() & Common::EventManager::LBUTTON; - _vm->_state->setDragEnded(!mousePressed); + dragging = _vm->getEventManager()->getButtonState() & Common::EventManager::LBUTTON; + dragging |= _vm->_state->hasVarGamePadActionPressed() && _vm->_state->getGamePadActionPressed(); + _vm->_state->setDragEnded(!dragging); _vm->processInput(true); _vm->drawFrame(); - // Distance between the mouse and the lever - Common::Point mouse = _vm->_cursor->getPosition(); - int16 distanceX = mouse.x - leverWidth / 2 - _vm->_state->getVar(cmd.args[0]); - int16 distanceY = mouse.y - leverHeight / 2 - _vm->_state->getVar(cmd.args[1]) - topOffset; - float distance = sqrt((float) distanceX * distanceX + distanceY * distanceY); + if (!dragWithDirectionKeys) { + // Distance between the mouse and the lever + Common::Point mouse = _vm->_cursor->getPosition(); + int16 distanceX = mouse.x - leverWidth / 2 - _vm->_state->getVar(cmd.args[0]); + int16 distanceY = mouse.y - leverHeight / 2 - _vm->_state->getVar(cmd.args[1]) - topOffset; + float distance = sqrt((float) distanceX * distanceX + distanceY * distanceY); - uint16 bestPosition = lastLeverPosition; - if (distance > maxDistance) { - _vm->_state->setDragLeverPositionChanged(false); - } else { - // Find the lever position where the distance between the lever - // and the mouse is minimal, by trying every possible position. - float minDistance = 1000; - for (uint i = 0; i < maxLeverPosition; i++) { - _vm->_state->setDragPositionFound(false); + uint16 bestPosition = lastLeverPosition; + if (distance > maxDistance) { + _vm->_state->setDragLeverPositionChanged(false); + } else { + // Find the lever position where the distance between the lever + // and the mouse is minimal, by trying every possible position. + float minDistance = 1000; + for (uint i = 0; i < maxLeverPosition; i++) { + _vm->_state->setDragPositionFound(false); - _vm->_state->setVar(cmd.args[4], i); - _vm->runScriptsFromNode(script); + _vm->_state->setVar(cmd.args[4], i); + _vm->runScriptsFromNode(script); - mouse = _vm->_cursor->getPosition(); - distanceX = mouse.x - leverWidth / 2 - _vm->_state->getVar(cmd.args[0]); - distanceY = mouse.y - leverHeight / 2 - _vm->_state->getVar(cmd.args[1]) - topOffset; - distance = sqrt((float) distanceX * distanceX + distanceY * distanceY); + mouse = _vm->_cursor->getPosition(); + distanceX = mouse.x - leverWidth / 2 - _vm->_state->getVar(cmd.args[0]); + distanceY = mouse.y - leverHeight / 2 - _vm->_state->getVar(cmd.args[1]) - topOffset; + distance = sqrt((float) distanceX * distanceX + distanceY * distanceY); - if (distance < minDistance) { - minDistance = distance; - bestPosition = i; + if (distance < minDistance) { + minDistance = distance; + bestPosition = i; + } } + _vm->_state->setDragLeverPositionChanged(bestPosition != lastLeverPosition); } - _vm->_state->setDragLeverPositionChanged(bestPosition != lastLeverPosition); - } - // Set the lever position to the best position - _vm->_state->setDragPositionFound(true); - _vm->_state->setVar(cmd.args[4], bestPosition); + // Set the lever position to the best position + _vm->_state->setDragPositionFound(true); + _vm->_state->setVar(cmd.args[4], bestPosition); + } else { + uint16 previousPosition = _vm->_state->getVar(cmd.args[4]); + uint16 position = previousPosition; + + if (_vm->_state->getGamePadLeftPressed()) { + position--; + } else if (_vm->_state->getGamePadRightPressed()) { + position++; + } + + position = CLIP(position, 0, maxLeverPosition); + _vm->_state->setVar(cmd.args[4], position); + _vm->_state->setDragLeverPositionChanged(position != previousPosition); + } _vm->runScriptsFromNode(script); _vm->processInput(true); _vm->drawFrame(); - } while (mousePressed); + } while (dragging); + + if (dragWithDirectionKeys) { + _vm->_state->setDragWithDirectionKeys(false); + } } void Script::chooseNextNode(Context &c, const Opcode &cmd) { diff --git a/engines/myst3/state.cpp b/engines/myst3/state.cpp index 8bce4fe96fa..ecfeeeb5be4 100644 --- a/engines/myst3/state.cpp +++ b/engines/myst3/state.cpp @@ -373,6 +373,7 @@ GameState::GameState(Myst3Engine *vm): VAR(1434, GamePadRightPressed, false) VAR(1435, GamePadCancelPressed, false) + VAR(1437, DragWithDirectionKeys, false) VAR(1438, MenuAttractCountDown, false) VAR(1439, ShieldEffectActive, false) diff --git a/engines/myst3/state.h b/engines/myst3/state.h index a2378c2d841..37006d198cb 100644 --- a/engines/myst3/state.h +++ b/engines/myst3/state.h @@ -297,6 +297,7 @@ public: DECLARE_VAR(GamePadRightPressed) DECLARE_VAR(GamePadCancelPressed) + DECLARE_VAR(DragWithDirectionKeys) DECLARE_VAR(MenuSavesAvailable) DECLARE_VAR(MenuSelectedSave) DECLARE_VAR(MenuAttractCountDown)