Skip to content

Commit

Permalink
Resurrect and refactor the AxisSwap feature. Fixes hrydgard#17292
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Apr 20, 2023
1 parent eeedc81 commit 7594ae8
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 28 deletions.
71 changes: 69 additions & 2 deletions Core/ControlMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down
6 changes: 6 additions & 0 deletions Core/ControlMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@ class ControlMapper {
// 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);
Expand All @@ -57,6 +61,8 @@ class ControlMapper {
bool autoRotatingAnalogCW_ = false;
bool autoRotatingAnalogCCW_ = false;

bool swapAxes_ = false;

// Protects basically all the state.
std::mutex mutex_;

Expand Down
25 changes: 1 addition & 24 deletions Core/KeyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion Core/KeyMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ namespace KeyMap {

void RestoreDefault();

void SwapAxis();
void UpdateNativeMenuKeys();

void NotifyPadConnected(int deviceId, const std::string &name);
Expand Down
4 changes: 3 additions & 1 deletion UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 7594ae8

Please sign in to comment.