Browse Source

Further improve simulated mouse interaction

pull/5453/head
staphen 3 years ago committed by Anders Jenbo
parent
commit
6a565d3755
  1. 52
      Source/controls/controller_motion.cpp
  2. 19
      Source/controls/game_controls.cpp
  3. 9
      Source/controls/plrctrls.cpp
  4. 3
      Source/controls/plrctrls.h
  5. 85
      Source/options.cpp
  6. 6
      Source/options.h

52
Source/controls/controller_motion.cpp

@ -78,47 +78,40 @@ void SetSimulatingMouseWithPadmapper(bool value)
}
}
// SELECT + D-Pad to simulate right stick movement.
bool SimulateRightStickWithDpad(ControllerButtonEvent ctrlEvent)
void SimulateRightStickWithPadmapper(ControllerButtonEvent ctrlEvent)
{
if (IsAnyOf(ctrlEvent.button, ControllerButton_NONE, ControllerButton_IGNORE))
return false;
return;
if (!ctrlEvent.up && ctrlEvent.button == SuppressedButton)
return;
ControllerButtonCombo upCombo = sgOptions.Padmapper.ButtonComboForAction("MouseUp");
ControllerButtonCombo downCombo = sgOptions.Padmapper.ButtonComboForAction("MouseDown");
ControllerButtonCombo leftCombo = sgOptions.Padmapper.ButtonComboForAction("MouseLeft");
ControllerButtonCombo rightCombo = sgOptions.Padmapper.ButtonComboForAction("MouseRight");
if (IsNoneOf(ctrlEvent.button, upCombo.button, downCombo.button, leftCombo.button, rightCombo.button)) {
string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent);
bool upTriggered = actionName == "MouseUp";
bool downTriggered = actionName == "MouseDown";
bool leftTriggered = actionName == "MouseLeft";
bool rightTriggered = actionName == "MouseRight";
if (!upTriggered && !downTriggered && !leftTriggered && !rightTriggered) {
if (rightStickX == 0 && rightStickY == 0)
SetSimulatingMouseWithPadmapper(false);
return false;
return;
}
bool upActive = (upTriggered && !ctrlEvent.up) || (!upTriggered && sgOptions.Padmapper.IsActive("MouseUp"));
bool downActive = (downTriggered && !ctrlEvent.up) || (!downTriggered && sgOptions.Padmapper.IsActive("MouseDown"));
bool leftActive = (leftTriggered && !ctrlEvent.up) || (!leftTriggered && sgOptions.Padmapper.IsActive("MouseLeft"));
bool rightActive = (rightTriggered && !ctrlEvent.up) || (!rightTriggered && sgOptions.Padmapper.IsActive("MouseRight"));
rightStickX = 0;
rightStickY = 0;
// Cannot use PadmapperOptions::IsActive() because this function
// is invoked before PadmapperOptions::ButtonPressed()
if (IsControllerButtonComboPressed(upCombo))
if (upActive)
rightStickY += 1.F;
if (IsControllerButtonComboPressed(downCombo))
if (downActive)
rightStickY -= 1.F;
if (IsControllerButtonComboPressed(leftCombo))
if (leftActive)
rightStickX -= 1.F;
if (IsControllerButtonComboPressed(rightCombo))
if (rightActive)
rightStickX += 1.F;
if (rightStickX == 0 && rightStickY == 0) {
// In this case, PadmapperOptions::IsActive() can be used to anticipate PadmapperOptions::ButtonReleased()
bool upReleased = ctrlEvent.up && ctrlEvent.button == upCombo.button && sgOptions.Padmapper.IsActive("MouseUp");
bool downReleased = ctrlEvent.up && ctrlEvent.button == downCombo.button && sgOptions.Padmapper.IsActive("MouseDown");
bool leftReleased = ctrlEvent.up && ctrlEvent.button == leftCombo.button && sgOptions.Padmapper.IsActive("MouseLeft");
bool rightReleased = ctrlEvent.up && ctrlEvent.button == rightCombo.button && sgOptions.Padmapper.IsActive("MouseRight");
return upReleased || downReleased || leftReleased || rightReleased;
}
SetSimulatingMouseWithPadmapper(true);
return true;
}
} // namespace
@ -174,7 +167,8 @@ bool ProcessControllerMotion(const SDL_Event &event, ControllerButtonEvent ctrlE
return true;
}
#endif
return SimulateRightStickWithDpad(ctrlEvent);
SimulateRightStickWithPadmapper(ctrlEvent);
return false;
}
AxisDirection GetLeftStickOrDpadDirection(bool usePadmapper)
@ -194,7 +188,7 @@ AxisDirection GetLeftStickOrDpadDirection(bool usePadmapper)
isDownPressed |= sgOptions.Padmapper.IsActive("MoveDown");
isLeftPressed |= sgOptions.Padmapper.IsActive("MoveLeft");
isRightPressed |= sgOptions.Padmapper.IsActive("MoveRight");
} else {
} else if (!SimulatingMouseWithPadmapper) {
isUpPressed |= IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_UP);
isDownPressed |= IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_DOWN);
isLeftPressed |= IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_LEFT);

19
Source/controls/game_controls.cpp

@ -332,14 +332,12 @@ bool SkipsMovie(ControllerButtonEvent ctrlEvent)
bool IsSimulatedMouseClickBinding(ControllerButtonEvent ctrlEvent)
{
ControllerButtonCombo leftMouseClickBinding1 = sgOptions.Padmapper.ButtonComboForAction("LeftMouseClick1");
ControllerButtonCombo leftMouseClickBinding2 = sgOptions.Padmapper.ButtonComboForAction("LeftMouseClick2");
ControllerButtonCombo rightMouseClickBinding1 = sgOptions.Padmapper.ButtonComboForAction("RightMouseClick1");
ControllerButtonCombo rightMouseClickBinding2 = sgOptions.Padmapper.ButtonComboForAction("RightMouseClick2");
return (ctrlEvent.button == leftMouseClickBinding1.button && IsControllerButtonComboPressed(leftMouseClickBinding1))
|| (ctrlEvent.button == leftMouseClickBinding2.button && IsControllerButtonComboPressed(leftMouseClickBinding2))
|| (ctrlEvent.button == rightMouseClickBinding1.button && IsControllerButtonComboPressed(rightMouseClickBinding1))
|| (ctrlEvent.button == rightMouseClickBinding2.button && IsControllerButtonComboPressed(rightMouseClickBinding2));
if (IsAnyOf(ctrlEvent.button, ControllerButton_NONE, ControllerButton_IGNORE))
return false;
if (!ctrlEvent.up && ctrlEvent.button == SuppressedButton)
return false;
string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent);
return IsAnyOf(actionName, "LeftMouseClick1", "LeftMouseClick2", "RightMouseClick1", "RightMouseClick2");
}
AxisDirection GetMoveDirection()
@ -365,8 +363,11 @@ bool HandleControllerButtonEvent(const SDL_Event &event, GameAction &action)
if (isGamepadMotion) {
return true;
}
if (IsAnyOf(ctrlEvent.button, ControllerButton_NONE, ControllerButton_IGNORE)) {
return false;
}
if (ctrlEvent.button != ControllerButton_NONE && ctrlEvent.button == SuppressedButton) {
if (ctrlEvent.button == SuppressedButton) {
if (!ctrlEvent.up)
return true;
SuppressedButton = ControllerButton_NONE;

9
Source/controls/plrctrls.cpp

@ -1481,7 +1481,7 @@ float rightStickLastMove = 0;
bool ContinueSimulatedMouseEvent(const SDL_Event &event, const ControllerButtonEvent &gamepadEvent)
{
if (IsAutomapActive())
if (AutomapActive)
return false;
#if !defined(USE_SDL1) && !defined(JOY_AXIS_RIGHTX) && !defined(JOY_AXIS_RIGHTY)
@ -1691,11 +1691,6 @@ void ProcessGameAction(const GameAction &action)
}
}
bool IsAutomapActive()
{
return AutomapActive && leveltype != DTYPE_TOWN;
}
void HandleRightStickMotion()
{
static RightStickAccumulator acc;
@ -1705,7 +1700,7 @@ void HandleRightStickMotion()
return;
}
if (IsAutomapActive()) { // move map
if (AutomapActive) { // move map
int dx = 0;
int dy = 0;
acc.Pool(&dx, &dy, 32);

3
Source/controls/plrctrls.h

@ -67,9 +67,6 @@ bool IsPointAndClick();
void DetectInputMethod(const SDL_Event &event, const ControllerButtonEvent &gamepadEvent);
void ProcessGameAction(const GameAction &action);
// Whether the automap is being displayed.
bool IsAutomapActive();
void UseBeltItem(int type);
// Talk to towners, click on inv items, attack, etc.

85
Source/options.cpp

@ -1597,39 +1597,13 @@ void PadmapperOptions::CommitActions()
void PadmapperOptions::ButtonPressed(ControllerButton button)
{
// To give preference to button combinations,
// first pass ignores mappings where no modifier is bound
for (Action &action : actions) {
ControllerButtonCombo combo = action.boundInput;
if (combo.modifier == ControllerButton_NONE)
continue;
if (button != combo.button)
continue;
if (!IsControllerButtonPressed(combo.modifier))
continue;
if (action.enable && !action.enable())
continue;
if (action.actionPressed)
action.actionPressed();
SuppressedButton = combo.modifier;
buttonToReleaseAction.insert_or_assign(combo.button, action);
return;
}
for (Action &action : actions) {
ControllerButtonCombo combo = action.boundInput;
if (combo.modifier != ControllerButton_NONE)
continue;
if (button != combo.button)
continue;
if (action.enable && !action.enable())
continue;
if (action.actionPressed)
action.actionPressed();
SuppressedButton = combo.modifier;
buttonToReleaseAction.insert_or_assign(combo.button, action);
const Action *action = FindAction(button);
if (action == nullptr)
return;
}
if (action->actionPressed)
action->actionPressed();
SuppressedButton = action->boundInput.modifier;
buttonToReleaseAction.insert_or_assign(button, *action);
}
void PadmapperOptions::ButtonReleased(ControllerButton button, bool invokeAction)
@ -1663,6 +1637,22 @@ bool PadmapperOptions::IsActive(string_view actionName) const
return false;
}
string_view PadmapperOptions::ActionNameTriggeredByButtonEvent(ControllerButtonEvent ctrlEvent) const
{
if (!gbRunGame)
return "";
if (!ctrlEvent.up) {
const Action *pressAction = FindAction(ctrlEvent.button);
return pressAction != nullptr ? pressAction->key : "";
}
auto it = buttonToReleaseAction.find(ctrlEvent.button);
if (it == buttonToReleaseAction.end())
return "";
const Action &releaseAction = it->second.get();
return releaseAction.key;
}
string_view PadmapperOptions::InputNameForAction(string_view actionName) const
{
for (const Action &action : actions) {
@ -1683,6 +1673,37 @@ ControllerButtonCombo PadmapperOptions::ButtonComboForAction(string_view actionN
return ControllerButton_NONE;
}
const PadmapperOptions::Action *PadmapperOptions::FindAction(ControllerButton button) const
{
// To give preference to button combinations,
// first pass ignores mappings where no modifier is bound
for (const Action &action : actions) {
ControllerButtonCombo combo = action.boundInput;
if (combo.modifier == ControllerButton_NONE)
continue;
if (button != combo.button)
continue;
if (!IsControllerButtonPressed(combo.modifier))
continue;
if (action.enable && !action.enable())
continue;
return &action;
}
for (const Action &action : actions) {
ControllerButtonCombo combo = action.boundInput;
if (combo.modifier != ControllerButton_NONE)
continue;
if (button != combo.button)
continue;
if (action.enable && !action.enable())
continue;
return &action;
}
return nullptr;
}
namespace {
constexpr char ResamplerSpeex[] = "Speex";
constexpr char ResamplerSDL[] = "SDL";

6
Source/options.h

@ -7,6 +7,7 @@
#include <SDL_version.h>
#include "controls/controller.h"
#include "controls/controller_buttons.h"
#include "engine/sound_defs.hpp"
#include "miniwin/misc_msg.h"
@ -739,15 +740,18 @@ struct PadmapperOptions : OptionCategoryBase {
void ButtonPressed(ControllerButton button);
void ButtonReleased(ControllerButton button, bool invokeAction = true);
bool IsActive(string_view actionName) const;
string_view ActionNameTriggeredByButtonEvent(ControllerButtonEvent ctrlEvent) const;
string_view InputNameForAction(string_view actionName) const;
ControllerButtonCombo ButtonComboForAction(string_view actionName) const;
private:
std::forward_list<Action> actions;
std::unordered_map<ControllerButton, std::reference_wrapper<Action>> buttonToReleaseAction;
std::unordered_map<ControllerButton, std::reference_wrapper<const Action>> buttonToReleaseAction;
std::unordered_map<ControllerButton, std::string> buttonToButtonName;
std::unordered_map<std::string, ControllerButton> buttonNameToButton;
bool committed = false;
const Action *FindAction(ControllerButton button) const;
};
struct Options {

Loading…
Cancel
Save