mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-12 01:25:55 +00:00
Resurrect and refactor the AxisSwap feature. Fixes #17292
This commit is contained in:
parent
eeedc817e2
commit
7594ae8785
@ -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<MultiInputMapping> 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<MultiInputMapping> 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<std::mutex> guard(mutex_);
|
||||
if (axis.value >= 0.0f) {
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -43,8 +43,6 @@ std::set<std::string> g_seenPads;
|
||||
std::map<int, std::string> g_padNames;
|
||||
std::set<int> g_seenDeviceIds;
|
||||
|
||||
bool g_swapDpadWithLStick = false;
|
||||
|
||||
// Utility...
|
||||
void SingleInputMappingFromPspButton(int btn, std::vector<InputMapping> *mappings, bool ignoreMouse) {
|
||||
std::vector<MultiInputMapping> multiMappings;
|
||||
@ -484,29 +482,13 @@ std::vector<KeyMap_IntStrPair> 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<int> *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;
|
||||
|
@ -199,7 +199,6 @@ namespace KeyMap {
|
||||
|
||||
void RestoreDefault();
|
||||
|
||||
void SwapAxis();
|
||||
void UpdateNativeMenuKeys();
|
||||
|
||||
void NotifyPadConnected(int deviceId, const std::string &name);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user