diff --git a/Core/ControlMapper.cpp b/Core/ControlMapper.cpp index 11dfc634a7..a9ac9cc244 100644 --- a/Core/ControlMapper.cpp +++ b/Core/ControlMapper.cpp @@ -202,6 +202,37 @@ float ControlMapper::MapAxisValue(float value, int vkId, const InputMapping &map } } +static bool IsSwappableVKey(uint32_t vkey) { + switch (vkey) { + case CTRL_UP: + case CTRL_LEFT: + case CTRL_DOWN: + case CTRL_RIGHT: + case VIRTKEY_AXIS_X_MIN: + case VIRTKEY_AXIS_X_MAX: + case VIRTKEY_AXIS_Y_MIN: + case VIRTKEY_AXIS_Y_MAX: + return true; + default: + return false; + } +} + +void ControlMapper::SwapMappingIfEnabled(uint32_t *vkey) { + if (swapAxes_) { + switch (*vkey) { + case CTRL_UP: *vkey = VIRTKEY_AXIS_Y_MAX; break; + case VIRTKEY_AXIS_Y_MAX: *vkey = CTRL_UP; break; + case CTRL_DOWN: *vkey = VIRTKEY_AXIS_Y_MIN; break; + case VIRTKEY_AXIS_Y_MIN: *vkey = CTRL_DOWN; break; + case CTRL_LEFT: *vkey = VIRTKEY_AXIS_X_MIN; break; + case VIRTKEY_AXIS_X_MIN: *vkey = CTRL_LEFT; break; + case CTRL_RIGHT: *vkey = VIRTKEY_AXIS_X_MAX; break; + case VIRTKEY_AXIS_X_MAX: *vkey = CTRL_RIGHT; break; + } + } +} + // Can only be called from Key or Axis. bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { // Instead of taking an input key and finding what it outputs, we loop through the OUTPUTS and @@ -230,6 +261,8 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { mappingBit = RotatePSPKeyCode(mappingBit); } + SwapMappingIfEnabled(&mappingBit); + std::vector inputMappings; if (!KeyMap::InputMappingsFromPspButton(mappingBit, &inputMappings, false)) continue; @@ -264,7 +297,11 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { for (int i = 0; i < VIRTKEY_COUNT; i++) { int vkId = i + VIRTKEY_FIRST; std::vector inputMappings; - if (!KeyMap::InputMappingsFromPspButton(vkId, &inputMappings, false)) + + uint32_t idForMapping = vkId; + SwapMappingIfEnabled(&idForMapping); + + if (!KeyMap::InputMappingsFromPspButton(idForMapping, &inputMappings, false)) continue; // If a mapping could consist of a combo, we could trivially check it here. @@ -284,7 +321,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { if (iter != curInput_.end()) { if (mapping.IsAxis()) { threshold = GetDeviceAxisThreshold(iter->first.deviceId); - product *= MapAxisValue(iter->second, vkId, mapping, changedMapping, &touchedByMapping); + product *= MapAxisValue(iter->second, idForMapping, mapping, changedMapping, &touchedByMapping); } else { product *= iter->second; } @@ -386,6 +423,36 @@ bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) { return UpdatePSPState(mapping); } +void ControlMapper::ToggleSwapAxes() { + swapAxes_ = !swapAxes_; + + // To avoid stuck keys, just reset it all. + for (auto &mapping : curInput_) { + mapping.second = 0.0f; + } + + updatePSPButtons_(0, CTRL_LEFT | CTRL_RIGHT | CTRL_UP | CTRL_DOWN); + + for (uint32_t vkey = VIRTKEY_FIRST; vkey < VIRTKEY_LAST; vkey++) { + if (IsSwappableVKey(vkey)) { + if (virtKeyOn_[vkey - VIRTKEY_FIRST]) { + onVKey_(vkey, false); + virtKeyOn_[vkey - VIRTKEY_FIRST] = false; + } + if (virtKeys_[vkey - VIRTKEY_FIRST] > 0.0f) { + onVKeyAnalog_(vkey, 0.0f); + virtKeys_[vkey - VIRTKEY_FIRST] = 0.0f; + } + } + } + + history_[0][0] = 0.0f; + history_[0][1] = 0.0f; + + UpdateAnalogOutput(0); + UpdateAnalogOutput(1); +} + void ControlMapper::Axis(const AxisInput &axis) { std::lock_guard guard(mutex_); if (axis.value >= 0.0f) { diff --git a/Core/ControlMapper.h b/Core/ControlMapper.h index dff36d501e..0e53426613 100644 --- a/Core/ControlMapper.h +++ b/Core/ControlMapper.h @@ -32,11 +32,15 @@ public: // virtual key codes, though not analog mappings. void PSPKey(int deviceId, int pspKeyCode, int flags); + // Toggle swapping DPAD and Analog. Useful on some input devices with few buttons. + void ToggleSwapAxes(); + void GetDebugString(char *buffer, size_t bufSize) const; private: bool UpdatePSPState(const InputMapping &changedMapping); float MapAxisValue(float value, int vkId, const InputMapping &mapping, const InputMapping &changedMapping, bool *oppositeTouched); + void SwapMappingIfEnabled(uint32_t *vkey); void SetPSPAxis(int deviceId, int stick, char axis, float value); void UpdateAnalogOutput(int stick); @@ -57,6 +61,8 @@ private: bool autoRotatingAnalogCW_ = false; bool autoRotatingAnalogCCW_ = false; + bool swapAxes_ = false; + // Protects basically all the state. std::mutex mutex_; diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index bdb50d98b7..a2981aad30 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -43,8 +43,6 @@ std::set g_seenPads; std::map g_padNames; std::set g_seenDeviceIds; -bool g_swapDpadWithLStick = false; - // Utility... void SingleInputMappingFromPspButton(int btn, std::vector *mappings, bool ignoreMouse) { std::vector multiMappings; @@ -484,29 +482,13 @@ std::vector GetMappableKeys() { return temp; } -inline int CheckAxisSwap(int btn) { - if (g_swapDpadWithLStick) { - switch (btn) { - case CTRL_UP: btn = VIRTKEY_AXIS_Y_MAX; break; - case VIRTKEY_AXIS_Y_MAX: btn = CTRL_UP; break; - case CTRL_DOWN: btn = VIRTKEY_AXIS_Y_MIN; break; - case VIRTKEY_AXIS_Y_MIN: btn = CTRL_DOWN; break; - case CTRL_LEFT: btn = VIRTKEY_AXIS_X_MIN; break; - case VIRTKEY_AXIS_X_MIN: btn = CTRL_LEFT; break; - case CTRL_RIGHT: btn = VIRTKEY_AXIS_X_MAX; break; - case VIRTKEY_AXIS_X_MAX: btn = CTRL_RIGHT; break; - } - } - return btn; -} - bool InputMappingToPspButton(const InputMapping &mapping, std::vector *pspButtons) { bool found = false; for (auto iter = g_controllerMap.begin(); iter != g_controllerMap.end(); ++iter) { for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { if (iter2->EqualsSingleMapping(mapping)) { if (pspButtons) - pspButtons->push_back(CheckAxisSwap(iter->first)); + pspButtons->push_back(iter->first); found = true; } } @@ -812,11 +794,6 @@ std::string PadName(int deviceId) { return ""; } -// Swap direction buttons and left analog axis -void SwapAxis() { - g_swapDpadWithLStick = !g_swapDpadWithLStick; -} - bool HasChanged(int &prevGeneration) { if (prevGeneration != g_controllerMapGeneration) { prevGeneration = g_controllerMapGeneration; diff --git a/Core/KeyMap.h b/Core/KeyMap.h index 139cbaab3c..7813ada3ec 100644 --- a/Core/KeyMap.h +++ b/Core/KeyMap.h @@ -199,7 +199,6 @@ namespace KeyMap { void RestoreDefault(); - void SwapAxis(); void UpdateNativeMenuKeys(); void NotifyPadConnected(int deviceId, const std::string &name); diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 913f604b4e..e50d9a887a 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -561,6 +561,7 @@ void EmuScreen::touch(const TouchInput &touch) { void EmuScreen::onVKey(int virtualKeyCode, bool down) { auto sc = GetI18NCategory(I18NCat::SCREEN); + auto mc = GetI18NCategory(I18NCat::MAPPABLECONTROLS); switch (virtualKeyCode) { case VIRTKEY_FASTFORWARD: @@ -647,7 +648,8 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) { case VIRTKEY_AXIS_SWAP: if (down) { - KeyMap::SwapAxis(); + controlMapper_.ToggleSwapAxes(); + osm.Show(mc->T("AxisSwap")); // best string we have. } break;