From 69200d197ba8120fa7e765f3354ca53fbf0f2ce1 Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Sun, 18 Aug 2024 17:39:10 +0200 Subject: [PATCH 1/2] Add axis specific last win SOCD cleaning (#1) * Add axis specific last win SOCD cleaning * Fix formatting --- headers/addons/dualdirectional.h | 4 +- headers/addons/slider_socd.h | 2 + proto/enums.proto | 214 +++++++++--------- src/addons/dualdirectional.cpp | 16 +- src/addons/slider_socd.cpp | 18 +- src/config_utils.cpp | 12 + src/display/ui/screens/ButtonLayoutScreen.cpp | 20 +- src/gamepad.cpp | 12 + src/gamepad/GamepadState.cpp | 4 +- www/src/Addons/PCF8575.tsx | 2 +- www/src/Addons/ReactiveLED.tsx | 2 +- www/src/Addons/SOCD.tsx | 6 +- www/src/Addons/Tilt.tsx | 4 +- www/src/Data/Addons.ts | 2 + www/src/Data/Pins.ts | 2 + www/src/Locales/de-DE/PinMapping.jsx | 2 + www/src/Locales/de-DE/SettingsPage.jsx | 4 + www/src/Locales/en/AddonsConfig.jsx | 2 + www/src/Locales/en/PinMapping.jsx | 2 + www/src/Locales/en/SettingsPage.jsx | 4 + www/src/Locales/ja-JP/AddonsConfig.jsx | 2 + www/src/Locales/ja-JP/PinMapping.jsx | 2 + www/src/Locales/ja-JP/SettingsPage.jsx | 4 + www/src/Locales/pt-BR/SettingsPage.jsx | 4 + www/src/Locales/zh-CN/AddonsConfig.jsx | 2 + www/src/Locales/zh-CN/PinMapping.jsx | 2 + www/src/Locales/zh-CN/SettingsPage.jsx | 4 + www/src/Pages/SettingsPage.jsx | 4 + 28 files changed, 220 insertions(+), 138 deletions(-) diff --git a/headers/addons/dualdirectional.h b/headers/addons/dualdirectional.h index a0d889fc0..de01f1655 100644 --- a/headers/addons/dualdirectional.h +++ b/headers/addons/dualdirectional.h @@ -30,14 +30,14 @@ class DualDirectionalInput : public GPAddon { uint8_t filterToFourWayModeDDI(uint8_t dpad); void SOCDDualClean(SOCDMode); uint8_t SOCDCombine(SOCDMode, uint8_t); - uint8_t SOCDGamepadClean(uint8_t, bool isLastWin); + uint8_t SOCDGamepadClean(uint8_t, bool isYLastWin, bool isXLastWin); void OverrideGamepad(Gamepad *, DpadMode, uint8_t); const SOCDMode getSOCDMode(const GamepadOptions&); uint8_t dualState; // Dual Directional State DpadDirection lastGPUD; // Gamepad Last Up-Down DpadDirection lastGPLR; // Gamepad Last Left-Right DpadDirection lastDualUD; // Dual Last Up-Down - DpadDirection lastDualLR; // Gamepad Last Left-Right + DpadDirection lastDualLR; // Dual Last Left-Right DpadMode dpadMode; GamepadButtonMapping *mapDpadUp; GamepadButtonMapping *mapDpadDown; diff --git a/headers/addons/slider_socd.h b/headers/addons/slider_socd.h index 02d5d8bca..44f9aa1eb 100644 --- a/headers/addons/slider_socd.h +++ b/headers/addons/slider_socd.h @@ -41,6 +41,8 @@ class SliderSOCDInput : public GPAddon { Mask_t secondInputModeMask = 0; Mask_t firstInputModeMask = 0; Mask_t bypassModeMask = 0; + Mask_t yAxisSecondInputModeMask = 0; + Mask_t xAxisSecondInputModeMask = 0; }; #endif // _SliderSOCD_H_ diff --git a/proto/enums.proto b/proto/enums.proto index d1eeb06bb..ae0a07754 100644 --- a/proto/enums.proto +++ b/proto/enums.proto @@ -173,11 +173,13 @@ enum SOCDMode { option (nanopb_enumopt).long_names = false; - SOCD_MODE_UP_PRIORITY = 0; // U+D=U, L+R=N - SOCD_MODE_NEUTRAL = 1; // U+D=N, L+R=N - SOCD_MODE_SECOND_INPUT_PRIORITY = 2; // U>D=D, L>R=R (Last Input Priority, aka Last Win) - SOCD_MODE_FIRST_INPUT_PRIORITY = 3; // U>D=U, L>R=L (First Input Priority, aka First Win) - SOCD_MODE_BYPASS = 4; // U+D=UD, L+R=LR (No cleaning applied) + SOCD_MODE_UP_PRIORITY = 0; // U+D=U, L+R=N + SOCD_MODE_NEUTRAL = 1; // U+D=N, L+R=N + SOCD_MODE_SECOND_INPUT_PRIORITY = 2; // U>D=D, L>R=R (Last Input Priority, aka Last Win) + SOCD_MODE_FIRST_INPUT_PRIORITY = 3; // U>D=U, L>R=L (First Input Priority, aka First Win) + SOCD_MODE_BYPASS = 4; // U+D=UD, L+R=LR (No cleaning applied) + SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY = 5; // U>D=D, L+R=N (Last Input Priority on Y-Axis, Neutral on X-Axis) + SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY = 6; // U+D=N, L>R=R (Last Input Priority on X-Axis, Neutral on Y-Axis) } enum GpioAction @@ -186,63 +188,65 @@ enum GpioAction // the lowest value is the default, which should be NONE; // reserving some numbers in case we need more not-mapped type values - NONE = -10; - RESERVED = -5; - ASSIGNED_TO_ADDON = 0; - BUTTON_PRESS_UP = 1; - BUTTON_PRESS_DOWN = 2; - BUTTON_PRESS_LEFT = 3; - BUTTON_PRESS_RIGHT = 4; - BUTTON_PRESS_B1 = 5; - BUTTON_PRESS_B2 = 6; - BUTTON_PRESS_B3 = 7; - BUTTON_PRESS_B4 = 8; - BUTTON_PRESS_L1 = 9; - BUTTON_PRESS_R1 = 10; - BUTTON_PRESS_L2 = 11; - BUTTON_PRESS_R2 = 12; - BUTTON_PRESS_S1 = 13; - BUTTON_PRESS_S2 = 14; - BUTTON_PRESS_A1 = 15; - BUTTON_PRESS_A2 = 16; - BUTTON_PRESS_L3 = 17; - BUTTON_PRESS_R3 = 18; - BUTTON_PRESS_FN = 19; - BUTTON_PRESS_DDI_UP = 20; - BUTTON_PRESS_DDI_DOWN = 21; - BUTTON_PRESS_DDI_LEFT = 22; - BUTTON_PRESS_DDI_RIGHT = 23; - SUSTAIN_DP_MODE_DP = 24; - SUSTAIN_DP_MODE_LS = 25; - SUSTAIN_DP_MODE_RS = 26; - SUSTAIN_SOCD_MODE_UP_PRIO = 27; - SUSTAIN_SOCD_MODE_NEUTRAL = 28; - SUSTAIN_SOCD_MODE_SECOND_WIN = 29; - SUSTAIN_SOCD_MODE_FIRST_WIN = 30; - SUSTAIN_SOCD_MODE_BYPASS = 31; - BUTTON_PRESS_TURBO = 32; - BUTTON_PRESS_MACRO = 33; - BUTTON_PRESS_MACRO_1 = 34; - BUTTON_PRESS_MACRO_2 = 35; - BUTTON_PRESS_MACRO_3 = 36; - BUTTON_PRESS_MACRO_4 = 37; - BUTTON_PRESS_MACRO_5 = 38; - BUTTON_PRESS_MACRO_6 = 39; - CUSTOM_BUTTON_COMBO = 40; - BUTTON_PRESS_A3 = 41; - BUTTON_PRESS_A4 = 42; - BUTTON_PRESS_E1 = 43; - BUTTON_PRESS_E2 = 44; - BUTTON_PRESS_E3 = 45; - BUTTON_PRESS_E4 = 46; - BUTTON_PRESS_E5 = 47; - BUTTON_PRESS_E6 = 48; - BUTTON_PRESS_E7 = 49; - BUTTON_PRESS_E8 = 50; - BUTTON_PRESS_E9 = 51; - BUTTON_PRESS_E10 = 52; - BUTTON_PRESS_E11 = 53; - BUTTON_PRESS_E12 = 54; + NONE = -10; + RESERVED = -5; + ASSIGNED_TO_ADDON = 0; + BUTTON_PRESS_UP = 1; + BUTTON_PRESS_DOWN = 2; + BUTTON_PRESS_LEFT = 3; + BUTTON_PRESS_RIGHT = 4; + BUTTON_PRESS_B1 = 5; + BUTTON_PRESS_B2 = 6; + BUTTON_PRESS_B3 = 7; + BUTTON_PRESS_B4 = 8; + BUTTON_PRESS_L1 = 9; + BUTTON_PRESS_R1 = 10; + BUTTON_PRESS_L2 = 11; + BUTTON_PRESS_R2 = 12; + BUTTON_PRESS_S1 = 13; + BUTTON_PRESS_S2 = 14; + BUTTON_PRESS_A1 = 15; + BUTTON_PRESS_A2 = 16; + BUTTON_PRESS_L3 = 17; + BUTTON_PRESS_R3 = 18; + BUTTON_PRESS_FN = 19; + BUTTON_PRESS_DDI_UP = 20; + BUTTON_PRESS_DDI_DOWN = 21; + BUTTON_PRESS_DDI_LEFT = 22; + BUTTON_PRESS_DDI_RIGHT = 23; + SUSTAIN_DP_MODE_DP = 24; + SUSTAIN_DP_MODE_LS = 25; + SUSTAIN_DP_MODE_RS = 26; + SUSTAIN_SOCD_MODE_UP_PRIO = 27; + SUSTAIN_SOCD_MODE_NEUTRAL = 28; + SUSTAIN_SOCD_MODE_SECOND_WIN = 29; + SUSTAIN_SOCD_MODE_FIRST_WIN = 30; + SUSTAIN_SOCD_MODE_BYPASS = 31; + BUTTON_PRESS_TURBO = 32; + BUTTON_PRESS_MACRO = 33; + BUTTON_PRESS_MACRO_1 = 34; + BUTTON_PRESS_MACRO_2 = 35; + BUTTON_PRESS_MACRO_3 = 36; + BUTTON_PRESS_MACRO_4 = 37; + BUTTON_PRESS_MACRO_5 = 38; + BUTTON_PRESS_MACRO_6 = 39; + CUSTOM_BUTTON_COMBO = 40; + BUTTON_PRESS_A3 = 41; + BUTTON_PRESS_A4 = 42; + BUTTON_PRESS_E1 = 43; + BUTTON_PRESS_E2 = 44; + BUTTON_PRESS_E3 = 45; + BUTTON_PRESS_E4 = 46; + BUTTON_PRESS_E5 = 47; + BUTTON_PRESS_E6 = 48; + BUTTON_PRESS_E7 = 49; + BUTTON_PRESS_E8 = 50; + BUTTON_PRESS_E9 = 51; + BUTTON_PRESS_E10 = 52; + BUTTON_PRESS_E11 = 53; + BUTTON_PRESS_E12 = 54; + SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN = 55; + SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN = 56; } enum GpioDirection @@ -257,48 +261,50 @@ enum GamepadHotkey { option (nanopb_enumopt).long_names = false; - HOTKEY_NONE = 0; - HOTKEY_DPAD_DIGITAL = 1; - HOTKEY_DPAD_LEFT_ANALOG = 2; - HOTKEY_DPAD_RIGHT_ANALOG = 3; - HOTKEY_HOME_BUTTON = 4; - HOTKEY_CAPTURE_BUTTON = 5; - HOTKEY_SOCD_UP_PRIORITY = 6; - HOTKEY_SOCD_NEUTRAL = 7; - HOTKEY_SOCD_LAST_INPUT = 8; - HOTKEY_INVERT_X_AXIS = 9; - HOTKEY_INVERT_Y_AXIS = 10; - HOTKEY_SOCD_FIRST_INPUT = 11; - HOTKEY_SOCD_BYPASS = 12; - HOTKEY_TOGGLE_4_WAY_MODE = 13; - HOTKEY_TOGGLE_DDI_4_WAY_MODE = 14; - HOTKEY_LOAD_PROFILE_1 = 15; - HOTKEY_LOAD_PROFILE_2 = 16; - HOTKEY_LOAD_PROFILE_3 = 17; - HOTKEY_LOAD_PROFILE_4 = 18; - HOTKEY_L3_BUTTON = 19; - HOTKEY_R3_BUTTON = 20; - HOTKEY_TOUCHPAD_BUTTON = 21; - HOTKEY_REBOOT_DEFAULT = 22; - HOTKEY_B1_BUTTON = 23; - HOTKEY_B2_BUTTON = 24; - HOTKEY_B3_BUTTON = 25; - HOTKEY_B4_BUTTON = 26; - HOTKEY_L1_BUTTON = 27; - HOTKEY_R1_BUTTON = 28; - HOTKEY_L2_BUTTON = 29; - HOTKEY_R2_BUTTON = 30; - HOTKEY_S1_BUTTON = 31; - HOTKEY_S2_BUTTON = 32; - HOTKEY_A1_BUTTON = 33; - HOTKEY_A2_BUTTON = 34; - HOTKEY_NEXT_PROFILE = 35; - HOTKEY_A3_BUTTON = 36; - HOTKEY_A4_BUTTON = 37; - HOTKEY_DPAD_UP = 38; - HOTKEY_DPAD_DOWN = 39; - HOTKEY_DPAD_LEFT = 40; - HOTKEY_DPAD_RIGHT = 41; + HOTKEY_NONE = 0; + HOTKEY_DPAD_DIGITAL = 1; + HOTKEY_DPAD_LEFT_ANALOG = 2; + HOTKEY_DPAD_RIGHT_ANALOG = 3; + HOTKEY_HOME_BUTTON = 4; + HOTKEY_CAPTURE_BUTTON = 5; + HOTKEY_SOCD_UP_PRIORITY = 6; + HOTKEY_SOCD_NEUTRAL = 7; + HOTKEY_SOCD_LAST_INPUT = 8; + HOTKEY_INVERT_X_AXIS = 9; + HOTKEY_INVERT_Y_AXIS = 10; + HOTKEY_SOCD_FIRST_INPUT = 11; + HOTKEY_SOCD_BYPASS = 12; + HOTKEY_TOGGLE_4_WAY_MODE = 13; + HOTKEY_TOGGLE_DDI_4_WAY_MODE = 14; + HOTKEY_LOAD_PROFILE_1 = 15; + HOTKEY_LOAD_PROFILE_2 = 16; + HOTKEY_LOAD_PROFILE_3 = 17; + HOTKEY_LOAD_PROFILE_4 = 18; + HOTKEY_L3_BUTTON = 19; + HOTKEY_R3_BUTTON = 20; + HOTKEY_TOUCHPAD_BUTTON = 21; + HOTKEY_REBOOT_DEFAULT = 22; + HOTKEY_B1_BUTTON = 23; + HOTKEY_B2_BUTTON = 24; + HOTKEY_B3_BUTTON = 25; + HOTKEY_B4_BUTTON = 26; + HOTKEY_L1_BUTTON = 27; + HOTKEY_R1_BUTTON = 28; + HOTKEY_L2_BUTTON = 29; + HOTKEY_R2_BUTTON = 30; + HOTKEY_S1_BUTTON = 31; + HOTKEY_S2_BUTTON = 32; + HOTKEY_A1_BUTTON = 33; + HOTKEY_A2_BUTTON = 34; + HOTKEY_NEXT_PROFILE = 35; + HOTKEY_A3_BUTTON = 36; + HOTKEY_A4_BUTTON = 37; + HOTKEY_DPAD_UP = 38; + HOTKEY_DPAD_DOWN = 39; + HOTKEY_DPAD_LEFT = 40; + HOTKEY_DPAD_RIGHT = 41; + HOTKEY_SOCD_Y_AXIS_LAST_INPUT = 42; + HOTKEY_SOCD_X_AXIS_LAST_INPUT = 43; } // This has to be kept in sync with LEDFormat in NeoPico.hpp diff --git a/src/addons/dualdirectional.cpp b/src/addons/dualdirectional.cpp index 280c80d9d..91d14fdc1 100644 --- a/src/addons/dualdirectional.cpp +++ b/src/addons/dualdirectional.cpp @@ -140,7 +140,9 @@ void DualDirectionalInput::process() dualOut = SOCDCombine(socdMode, gamepadDpad); } else if ( socdMode != SOCD_MODE_BYPASS ) { // else if not bypass, what's left is first/last input wins SOCD, which need a complicated re-clean - dualOut = SOCDGamepadClean(dualOut | gamepadDpad, socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY); + dualOut = SOCDGamepadClean(dualOut | gamepadDpad, + socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY, + socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY); } else { // this is bypass SOCD, just OR them together dualOut |= gamepadDpad; @@ -176,11 +178,11 @@ void DualDirectionalInput::OverrideGamepad(Gamepad * gamepad, DpadMode mode, uin } } -uint8_t DualDirectionalInput::SOCDGamepadClean(uint8_t gamepadState, bool isLastWin) { +uint8_t DualDirectionalInput::SOCDGamepadClean(uint8_t gamepadState, bool isYLastWin, bool isXLastWin) { // Gamepad SOCD Last-Win OR First-Win Clean switch (gamepadState & (GAMEPAD_MASK_UP | GAMEPAD_MASK_DOWN)) { case (GAMEPAD_MASK_UP | GAMEPAD_MASK_DOWN): // If last state was Up or Down, exclude it from our gamepad - if (isLastWin) gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_UP : GAMEPAD_MASK_DOWN; + if (isYLastWin) gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_UP : GAMEPAD_MASK_DOWN; else gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_DOWN : GAMEPAD_MASK_UP; break; case GAMEPAD_MASK_UP: @@ -198,7 +200,7 @@ uint8_t DualDirectionalInput::SOCDGamepadClean(uint8_t gamepadState, bool isLast switch (gamepadState & (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT)) { case (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT): if (lastGPLR != DIRECTION_NONE) - if (isLastWin) gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; + if (isXLastWin) gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; else gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_RIGHT : GAMEPAD_MASK_LEFT; else lastGPLR = DIRECTION_NONE; @@ -258,7 +260,7 @@ void DualDirectionalInput::SOCDDualClean(SOCDMode socdMode) { if ( socdMode == SOCD_MODE_UP_PRIORITY ) { dualState ^= GAMEPAD_MASK_DOWN; // Remove Down lastDualUD = DIRECTION_UP; // We're in UP mode - } else if ( socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY && lastDualUD != DIRECTION_NONE ) { + } else if ( (socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY) && lastDualUD != DIRECTION_NONE ) { dualState ^= (lastDualUD == DIRECTION_UP) ? GAMEPAD_MASK_UP : GAMEPAD_MASK_DOWN; } else if ( socdMode == SOCD_MODE_FIRST_INPUT_PRIORITY && lastDualUD != DIRECTION_NONE ) { dualState ^= (lastDualUD == DIRECTION_UP) ? GAMEPAD_MASK_DOWN : GAMEPAD_MASK_UP; @@ -282,9 +284,9 @@ void DualDirectionalInput::SOCDDualClean(SOCDMode socdMode) { if ( socdMode == SOCD_MODE_UP_PRIORITY || socdMode == SOCD_MODE_NEUTRAL ) { dualState ^= (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT); // Remove L + R to Neutral lastDualLR = DIRECTION_NONE; - } else if ( socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_FIRST_INPUT_PRIORITY ) { + } else if ( socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_FIRST_INPUT_PRIORITY ) { if (lastDualLR != DIRECTION_NONE) - if (socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY) dualState ^= (lastDualLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; // Last Win + if (socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY) dualState ^= (lastDualLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; // Last Win else dualState ^= (lastDualLR == DIRECTION_LEFT) ? GAMEPAD_MASK_RIGHT : GAMEPAD_MASK_LEFT; // First Win else lastDualLR = DIRECTION_NONE; diff --git a/src/addons/slider_socd.cpp b/src/addons/slider_socd.cpp index bbfa5c6ec..b04776e4e 100644 --- a/src/addons/slider_socd.cpp +++ b/src/addons/slider_socd.cpp @@ -6,8 +6,6 @@ #include "GamepadEnums.h" -#define SOCD_MODE_MASK (SOCD_MODE_UP_PRIORITY & SOCD_MODE_SECOND_INPUT_PRIORITY & SOCD_MODE_FIRST_INPUT_PRIORITY & SOCD_MODE_NEUTRAL) - bool SliderSOCDInput::available() { const SOCDSliderOptions& options = Storage::getInstance().getAddonOptions().socdSliderOptions; return options.enabled; @@ -19,11 +17,13 @@ void SliderSOCDInput::setup() for (Pin_t pin = 0; pin < (Pin_t)NUM_BANK0_GPIOS; pin++) { switch (pinMappings[pin].action) { - case SUSTAIN_SOCD_MODE_UP_PRIO: upPrioModeMask |= 1 << pin; break; - case SUSTAIN_SOCD_MODE_NEUTRAL: neutralModeMask |= 1 << pin; break; - case SUSTAIN_SOCD_MODE_SECOND_WIN: secondInputModeMask |= 1 << pin; break; - case SUSTAIN_SOCD_MODE_FIRST_WIN: firstInputModeMask |= 1 << pin; break; - case SUSTAIN_SOCD_MODE_BYPASS: bypassModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_UP_PRIO: upPrioModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_NEUTRAL: neutralModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_SECOND_WIN: secondInputModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_FIRST_WIN: firstInputModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_BYPASS: bypassModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN: yAxisSecondInputModeMask |= 1 << pin; break; + case SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN: xAxisSecondInputModeMask |= 1 << pin; break; default: break; } } @@ -37,6 +37,8 @@ SOCDMode SliderSOCDInput::read() { else if (values & secondInputModeMask) return SOCDMode::SOCD_MODE_SECOND_INPUT_PRIORITY; else if (values & firstInputModeMask) return SOCDMode::SOCD_MODE_FIRST_INPUT_PRIORITY; else if (values & bypassModeMask) return SOCDMode::SOCD_MODE_BYPASS; + else if (values & yAxisSecondInputModeMask) return SOCDMode::SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY; + else if (values & xAxisSecondInputModeMask) return SOCDMode::SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY; return options.modeDefault; } @@ -50,6 +52,8 @@ void SliderSOCDInput::reinit() secondInputModeMask = 0; firstInputModeMask = 0; bypassModeMask = 0; + yAxisSecondInputModeMask = 0; + xAxisSecondInputModeMask = 0; this->setup(); } diff --git a/src/config_utils.cpp b/src/config_utils.cpp index 21844b3ed..b95731fe1 100644 --- a/src/config_utils.cpp +++ b/src/config_utils.cpp @@ -976,6 +976,12 @@ void gpioMappingsMigrationCore(Config& config) case SOCDMode::SOCD_MODE_BYPASS: { actions[socdSliderOptions.deprecatedPinOne] = GpioAction::SUSTAIN_SOCD_MODE_BYPASS; break; } + case SOCDMode::SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY: { + actions[socdSliderOptions.deprecatedPinOne] = GpioAction::SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN; break; + } + case SOCDMode::SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY: { + actions[socdSliderOptions.deprecatedPinOne] = GpioAction::SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN; break; + } default: break; } socdSliderOptions.deprecatedPinOne = -1; @@ -998,6 +1004,12 @@ void gpioMappingsMigrationCore(Config& config) case SOCDMode::SOCD_MODE_BYPASS: { actions[socdSliderOptions.deprecatedPinTwo] = GpioAction::SUSTAIN_SOCD_MODE_BYPASS; break; } + case SOCDMode::SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY: { + actions[socdSliderOptions.deprecatedPinTwo] = GpioAction::SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN; break; + } + case SOCDMode::SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY: { + actions[socdSliderOptions.deprecatedPinTwo] = GpioAction::SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN; break; + } default: break; } socdSliderOptions.deprecatedPinTwo = -1; diff --git a/src/display/ui/screens/ButtonLayoutScreen.cpp b/src/display/ui/screens/ButtonLayoutScreen.cpp index 3e716cf3e..5bb5820e8 100644 --- a/src/display/ui/screens/ButtonLayoutScreen.cpp +++ b/src/display/ui/screens/ButtonLayoutScreen.cpp @@ -13,7 +13,7 @@ void ButtonLayoutScreen::init() { profileDelayStart = getMillis(); gamepad = Storage::getInstance().GetGamepad(); inputMode = DriverManager::getInstance().getInputMode(); - + footer = ""; historyString = ""; inputHistory.clear(); @@ -40,7 +40,7 @@ void ButtonLayoutScreen::init() { prevRightOptions = Storage::getInstance().getDisplayOptions().buttonLayoutCustomOptions.paramsRight; // we cannot look at macro options enabled, pull the pins - + // macro display now uses our pin functions, so we need to check if pins are enabled... macroEnabled = false; // Macro Button initialized by void Gamepad::setup() @@ -72,7 +72,7 @@ void ButtonLayoutScreen::shutdown() { int8_t ButtonLayoutScreen::update() { bool configMode = Storage::getInstance().GetConfigMode(); uint8_t profileNumber = getGamepad()->getOptions().profileNumber; - + // Check if we've updated button layouts while in config mode if (configMode) { uint8_t layoutLeft = Storage::getInstance().getDisplayOptions().buttonLayout; @@ -186,11 +186,13 @@ void ButtonLayoutScreen::generateHeader() { switch (Gamepad::resolveSOCDMode(gamepad->getOptions())) { - case SOCD_MODE_NEUTRAL: statusBar += " SOCD-N"; break; - case SOCD_MODE_UP_PRIORITY: statusBar += " SOCD-U"; break; - case SOCD_MODE_SECOND_INPUT_PRIORITY: statusBar += " SOCD-L"; break; - case SOCD_MODE_FIRST_INPUT_PRIORITY: statusBar += " SOCD-F"; break; - case SOCD_MODE_BYPASS: statusBar += " SOCD-X"; break; + case SOCD_MODE_NEUTRAL: statusBar += " SOCD-N"; break; + case SOCD_MODE_UP_PRIORITY: statusBar += " SOCD-U"; break; + case SOCD_MODE_SECOND_INPUT_PRIORITY: statusBar += " SOCD-L"; break; + case SOCD_MODE_FIRST_INPUT_PRIORITY: statusBar += " SOCD-F"; break; + case SOCD_MODE_BYPASS: statusBar += " SOCD-O"; break; + case SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY: statusBar += " SOCD-Y"; break; + case SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY: statusBar += " SOCD-X"; break; } if (macroEnabled) statusBar += " M"; @@ -372,7 +374,7 @@ bool ButtonLayoutScreen::compareCustomLayouts() bool leftChanged = ((leftOptions.layout != prevLeftOptions.layout) || (leftOptions.common.startX != prevLeftOptions.common.startX) || (leftOptions.common.startY != prevLeftOptions.common.startY) || (leftOptions.common.buttonPadding != prevLeftOptions.common.buttonPadding) || (leftOptions.common.buttonRadius != prevLeftOptions.common.buttonRadius)); bool rightChanged = ((rightOptions.layout != prevRightOptions.layout) || (rightOptions.common.startX != prevRightOptions.common.startX) || (rightOptions.common.startY != prevRightOptions.common.startY) || (rightOptions.common.buttonPadding != prevRightOptions.common.buttonPadding) || (rightOptions.common.buttonRadius != prevRightOptions.common.buttonRadius)); - + return (leftChanged || rightChanged); } diff --git a/src/gamepad.cpp b/src/gamepad.cpp index 65bf4cc2c..a8830f20d 100644 --- a/src/gamepad.cpp +++ b/src/gamepad.cpp @@ -478,6 +478,18 @@ void Gamepad::processHotkeyAction(GamepadHotkey action) { reqSave = true; } break; + case HOTKEY_SOCD_Y_AXIS_LAST_INPUT: + if (action != lastAction) { + options.socdMode = SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY; + reqSave = true; + } + break; + case HOTKEY_SOCD_X_AXIS_LAST_INPUT: + if (action != lastAction) { + options.socdMode = SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY; + reqSave = true; + } + break; case HOTKEY_REBOOT_DEFAULT: System::reboot(System::BootMode::DEFAULT); break; diff --git a/src/gamepad/GamepadState.cpp b/src/gamepad/GamepadState.cpp index dea46bb5e..cb0194c5d 100644 --- a/src/gamepad/GamepadState.cpp +++ b/src/gamepad/GamepadState.cpp @@ -115,7 +115,7 @@ uint8_t runSOCDCleaner(SOCDMode mode, uint8_t dpad) newDpad |= GAMEPAD_MASK_UP; lastUD = DIRECTION_UP; } - else if (mode == SOCD_MODE_SECOND_INPUT_PRIORITY && lastUD != DIRECTION_NONE) + else if ((mode == SOCD_MODE_SECOND_INPUT_PRIORITY || mode == SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY) && lastUD != DIRECTION_NONE) newDpad |= (lastUD == DIRECTION_UP) ? GAMEPAD_MASK_DOWN : GAMEPAD_MASK_UP; else if (mode == SOCD_MODE_FIRST_INPUT_PRIORITY && lastUD != DIRECTION_NONE) newDpad |= (lastUD == DIRECTION_UP) ? GAMEPAD_MASK_UP : GAMEPAD_MASK_DOWN; @@ -141,7 +141,7 @@ uint8_t runSOCDCleaner(SOCDMode mode, uint8_t dpad) switch (dpad & (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT)) { case (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT): - if (mode == SOCD_MODE_SECOND_INPUT_PRIORITY && lastLR != DIRECTION_NONE) + if ((mode == SOCD_MODE_SECOND_INPUT_PRIORITY || mode == SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY) && lastLR != DIRECTION_NONE) newDpad |= (lastLR == DIRECTION_LEFT) ? GAMEPAD_MASK_RIGHT : GAMEPAD_MASK_LEFT; else if (mode == SOCD_MODE_FIRST_INPUT_PRIORITY && lastLR != DIRECTION_NONE) newDpad |= (lastLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; diff --git a/www/src/Addons/PCF8575.tsx b/www/src/Addons/PCF8575.tsx index 42a755adf..32317d3ae 100644 --- a/www/src/Addons/PCF8575.tsx +++ b/www/src/Addons/PCF8575.tsx @@ -36,7 +36,7 @@ import { // currently using only the gamepad values here const NON_SELECTABLE_BUTTON_ACTIONS = [ -5, 0, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, + 37, 38, 39, 55, 56, ]; type PinCell = [ diff --git a/www/src/Addons/ReactiveLED.tsx b/www/src/Addons/ReactiveLED.tsx index 7f2225f22..540d4457e 100644 --- a/www/src/Addons/ReactiveLED.tsx +++ b/www/src/Addons/ReactiveLED.tsx @@ -22,7 +22,7 @@ import { getButtonLabels } from '../Data/Buttons'; const NON_SELECTABLE_BUTTON_ACTIONS = [ -5, 0, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40 + 37, 38, 39, 40, 55, 56, ]; const REACTIVE_LED_MODES = [ diff --git a/www/src/Addons/SOCD.tsx b/www/src/Addons/SOCD.tsx index 5579b9dd1..3bd6e4423 100644 --- a/www/src/Addons/SOCD.tsx +++ b/www/src/Addons/SOCD.tsx @@ -51,9 +51,9 @@ const SOCD = ({ values, errors, handleChange, handleCheckbox }) => { isInvalid={errors.sliderSOCDModeDefault} onChange={handleChange} > - {SOCD_MODES.map((o, i) => ( - ))} diff --git a/www/src/Addons/Tilt.tsx b/www/src/Addons/Tilt.tsx index 8ba014967..bb6ca36e6 100644 --- a/www/src/Addons/Tilt.tsx +++ b/www/src/Addons/Tilt.tsx @@ -7,7 +7,7 @@ import Section from '../Components/Section'; import FormSelect from '../Components/FormSelect'; import FormControl from '../Components/FormControl'; -import { SOCD_MODES, TILT_SOCD_MODES } from '../Data/Addons'; +import { TILT_SOCD_MODES } from '../Data/Addons'; export const tiltScheme = { TiltInputEnabled: yup.number().required().label('Tilt Input Enabled'), @@ -86,7 +86,7 @@ export const tiltScheme = { tiltSOCDMode: yup .number() .label('Tilt SOCE Mode') - .validateSelectionWhenValue('TiltInputEnabled', SOCD_MODES), + .validateSelectionWhenValue('TiltInputEnabled', TILT_SOCD_MODES), }; export const tiltState = { diff --git a/www/src/Data/Addons.ts b/www/src/Data/Addons.ts index 90ce0d5e5..f5cbbba77 100644 --- a/www/src/Data/Addons.ts +++ b/www/src/Data/Addons.ts @@ -28,5 +28,7 @@ export const SOCD_MODES = [ { label: 'Neutral', value: 1 }, { label: 'Last Win', value: 2 }, { label: 'First Win', value: 3 }, + { label: 'Y-Axis Last Win', value: 5 }, + { label: 'X-Axis Last Win', value: 6 }, { label: 'SOCD Cleaning Off', value: 4 }, ]; diff --git a/www/src/Data/Pins.ts b/www/src/Data/Pins.ts index cc46abe6e..f2f9ff326 100644 --- a/www/src/Data/Pins.ts +++ b/www/src/Data/Pins.ts @@ -33,6 +33,8 @@ export const BUTTON_ACTIONS = { SUSTAIN_SOCD_MODE_NEUTRAL: 28, SUSTAIN_SOCD_MODE_SECOND_WIN: 29, SUSTAIN_SOCD_MODE_FIRST_WIN: 30, + SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN: 55, + SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN: 56, SUSTAIN_SOCD_MODE_BYPASS: 31, BUTTON_PRESS_TURBO: 32, BUTTON_PRESS_MACRO: 33, diff --git a/www/src/Locales/de-DE/PinMapping.jsx b/www/src/Locales/de-DE/PinMapping.jsx index 1fcf44a25..e25383401 100644 --- a/www/src/Locales/de-DE/PinMapping.jsx +++ b/www/src/Locales/de-DE/PinMapping.jsx @@ -45,6 +45,8 @@ export default { SUSTAIN_SOCD_MODE_NEUTRAL: 'Neutrale SOCD Säuberung', SUSTAIN_SOCD_MODE_SECOND_WIN: 'Letzter Gewinnt SOCD Säuberung', SUSTAIN_SOCD_MODE_FIRST_WIN: 'Erster Gewinnt SOCD Säuberung', + SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN: 'Y-Achse Letzter Gewinnt SOCD Säuberung', + SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN: 'X-Achse Letzter Gewinnt SOCD Säuberung', SUSTAIN_SOCD_MODE_BYPASS: 'SOCD Säuberung Aus', BUTTON_PRESS_TURBO: 'Turbo', BUTTON_PRESS_MACRO: 'Makro', diff --git a/www/src/Locales/de-DE/SettingsPage.jsx b/www/src/Locales/de-DE/SettingsPage.jsx index 682d733b0..29fffe827 100644 --- a/www/src/Locales/de-DE/SettingsPage.jsx +++ b/www/src/Locales/de-DE/SettingsPage.jsx @@ -29,6 +29,8 @@ export default { neutral: 'Neutral', 'last-win': 'Letzter Gewinnt', 'first-win': 'Erster Gewinnt', + 'y-axis-last-win': 'Y-Achse Letzter Gewinnt', + 'x-axis-last-win': 'X-Achse Letzter Gewinnt', off: 'Aus', }, 'profile-number-label': 'Profil Nummer', @@ -49,6 +51,8 @@ export default { 'socd-neutral': 'SOCD Neutral', 'socd-last-win': 'SOCD Letzter Gewinnt', 'socd-first-win': 'SOCD Erster Gewinnt', + 'socd-y-axis-last-win': 'SOCD Y-Achse Letzter Gewinnt', + 'socd-x-axis-last-win': 'SOCD X-Achse Letzter Gewinnt', 'socd-off': 'SOCD Cleaning Aus', 'invert-x': 'X-Achse invertieren', 'invert-y': 'Y-Achse invertieren', diff --git a/www/src/Locales/en/AddonsConfig.jsx b/www/src/Locales/en/AddonsConfig.jsx index f10e5315b..2d76d01fb 100644 --- a/www/src/Locales/en/AddonsConfig.jsx +++ b/www/src/Locales/en/AddonsConfig.jsx @@ -150,6 +150,8 @@ export default { 'socd-slider-mode-1': 'Neutral', 'socd-slider-mode-2': 'Last Win', 'socd-slider-mode-3': 'First Win', + 'socd-slider-mode-5': 'Y-Axis Last Win', + 'socd-slider-mode-6': 'X-Axis Last Win', 'socd-slider-mode-4': 'SOCD Cleaning Off', 'tilt-socd-mode-0': 'Up Priority', 'tilt-socd-mode-1': 'Neutral', diff --git a/www/src/Locales/en/PinMapping.jsx b/www/src/Locales/en/PinMapping.jsx index bd85b1f9b..ff7a22a34 100644 --- a/www/src/Locales/en/PinMapping.jsx +++ b/www/src/Locales/en/PinMapping.jsx @@ -57,6 +57,8 @@ export default { SUSTAIN_SOCD_MODE_NEUTRAL: 'Neutral SOCD Cleaning', SUSTAIN_SOCD_MODE_SECOND_WIN: 'Last Win SOCD Cleaning', SUSTAIN_SOCD_MODE_FIRST_WIN: 'First Win SOCD Cleaning', + SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN: 'Y-Axis Last Win SOCD Cleaning', + SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN: 'X-Axis Last Win SOCD Cleaning', SUSTAIN_SOCD_MODE_BYPASS: 'SOCD Cleaning Off', BUTTON_PRESS_TURBO: 'Turbo', BUTTON_PRESS_MACRO: 'Macro Button', diff --git a/www/src/Locales/en/SettingsPage.jsx b/www/src/Locales/en/SettingsPage.jsx index 2360e56db..0cf9a6df7 100644 --- a/www/src/Locales/en/SettingsPage.jsx +++ b/www/src/Locales/en/SettingsPage.jsx @@ -53,6 +53,8 @@ export default { neutral: 'Neutral', 'last-win': 'Last Win', 'first-win': 'First Win', + 'y-axis-last-win': 'Y-Axis Last Win', + 'x-axis-last-win': 'X-Axis Last Win', off: 'Off', }, 'profile-number-label': 'Profile Number', @@ -87,6 +89,8 @@ export default { 'socd-neutral': 'SOCD Neutral', 'socd-last-win': 'SOCD Last Win', 'socd-first-win': 'SOCD First Win', + 'socd-y-axis-last-win': 'SOCD Y-Axis Last Win', + 'socd-x-axis-last-win': 'SOCD X-Axis Last Win', 'socd-off': 'SOCD Cleaning Off', 'invert-x': 'Invert X Axis', 'invert-y': 'Invert Y Axis', diff --git a/www/src/Locales/ja-JP/AddonsConfig.jsx b/www/src/Locales/ja-JP/AddonsConfig.jsx index a26b36f45..9290ed143 100644 --- a/www/src/Locales/ja-JP/AddonsConfig.jsx +++ b/www/src/Locales/ja-JP/AddonsConfig.jsx @@ -151,6 +151,8 @@ export default { 'socd-slider-mode-1': 'ニュートラル', 'socd-slider-mode-2': '後入力優先', 'socd-slider-mode-3': '先入力優先', + 'socd-slider-mode-5': 'TODO need translation', + 'socd-slider-mode-6': 'TODO need translation', 'socd-slider-mode-4': 'SOCDクリーナ無効', 'tilt-socd-mode-0': '上優先', 'tilt-socd-mode-1': 'ニュートラル', diff --git a/www/src/Locales/ja-JP/PinMapping.jsx b/www/src/Locales/ja-JP/PinMapping.jsx index ccf802472..6c0714f6f 100644 --- a/www/src/Locales/ja-JP/PinMapping.jsx +++ b/www/src/Locales/ja-JP/PinMapping.jsx @@ -37,6 +37,8 @@ export default { SUSTAIN_SOCD_MODE_NEUTRAL: 'ニュートラルモード(SOCDクリーナ)', SUSTAIN_SOCD_MODE_SECOND_WIN: '後入力優先モード(SOCDクリーナ)', SUSTAIN_SOCD_MODE_FIRST_WIN: '先入力優先モード(SOCDクリーナ)', + SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN: 'TODO need translation', + SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN: 'TODO need translation', SUSTAIN_SOCD_MODE_BYPASS: 'SOCDクリーナ無効', BUTTON_PRESS_TURBO: '連射機能', BUTTON_PRESS_MACRO: 'マクロボタン', diff --git a/www/src/Locales/ja-JP/SettingsPage.jsx b/www/src/Locales/ja-JP/SettingsPage.jsx index fdf0bf9ca..bda623037 100644 --- a/www/src/Locales/ja-JP/SettingsPage.jsx +++ b/www/src/Locales/ja-JP/SettingsPage.jsx @@ -45,6 +45,8 @@ export default { neutral: 'ニュートラル', 'last-win': '後入力優先', 'first-win': '先入力優先', + 'y-axis-last-win': 'TODO need translation', + 'x-axis-last-win': 'TODO need translation', off: '無効', }, 'profile-number-label': 'プロファイル番号', @@ -79,6 +81,8 @@ export default { 'socd-neutral': 'SOCD ニュートラル', 'socd-last-win': 'SOCD 後入力優先', 'socd-first-win': 'SOCD 先入力優先', + 'socd-y-axis-last-win': 'TODO need translation', + 'socd-x-axis-last-win': 'TODO need translation', 'socd-off': 'SOCD クリーナ無効', 'invert-x': '上下入力反転', 'invert-y': '左右入力反転', diff --git a/www/src/Locales/pt-BR/SettingsPage.jsx b/www/src/Locales/pt-BR/SettingsPage.jsx index 91f7ea60f..0b9d6b48b 100644 --- a/www/src/Locales/pt-BR/SettingsPage.jsx +++ b/www/src/Locales/pt-BR/SettingsPage.jsx @@ -28,6 +28,8 @@ export default { neutral: 'Neutra', 'last-win': 'Última Vitória', 'first-win': 'Primeira Vitória', + 'y-axis-last-win': 'TODO need translation', + 'x-axis-last-win': 'TODO need translation', off: 'Desativado', }, 'profile-number-label': 'Número de Perfil', @@ -47,6 +49,8 @@ export default { 'socd-neutral': 'SOCD Neutra', 'socd-last-win': 'SOCD Último Input Vence', 'socd-first-win': 'SOCD Primeiro Input Vence', + 'socd-y-axis-last-win': 'TODO need translation', + 'socd-x-axis-last-win': 'TODO need translation', 'socd-off': 'Desativar Limpeza SOCD', 'invert-x': 'Inverter Eixo X', 'invert-y': 'Inverter Eixo Y', diff --git a/www/src/Locales/zh-CN/AddonsConfig.jsx b/www/src/Locales/zh-CN/AddonsConfig.jsx index 380d07805..0091f13f2 100644 --- a/www/src/Locales/zh-CN/AddonsConfig.jsx +++ b/www/src/Locales/zh-CN/AddonsConfig.jsx @@ -145,6 +145,8 @@ export default { 'socd-slider-mode-1': '回中', 'socd-slider-mode-2': '后输入优先', 'socd-slider-mode-3': '先输入优先', + 'socd-slider-mode-5': 'TODO need translation', + 'socd-slider-mode-6': 'TODO need translation', 'socd-slider-mode-4': 'SOCD 覆盖关闭', 'tilt-socd-mode-0': '上优先', 'tilt-socd-mode-1': '回中', diff --git a/www/src/Locales/zh-CN/PinMapping.jsx b/www/src/Locales/zh-CN/PinMapping.jsx index 05348a101..7df02d358 100644 --- a/www/src/Locales/zh-CN/PinMapping.jsx +++ b/www/src/Locales/zh-CN/PinMapping.jsx @@ -56,6 +56,8 @@ export default { SUSTAIN_SOCD_MODE_NEUTRAL: '回中 SOCD 覆盖', SUSTAIN_SOCD_MODE_SECOND_WIN: '后输入优先 SOCD 覆盖', SUSTAIN_SOCD_MODE_FIRST_WIN: '先输入优先 SOCD 覆盖', + SUSTAIN_SOCD_MODE_Y_AXIS_SECOND_WIN: 'TODO need translation', + SUSTAIN_SOCD_MODE_X_AXIS_SECOND_WIN: 'TODO need translation', SUSTAIN_SOCD_MODE_BYPASS: '关闭 SOCD 覆盖', BUTTON_PRESS_TURBO: '连发', BUTTON_PRESS_MACRO: '宏按钮', diff --git a/www/src/Locales/zh-CN/SettingsPage.jsx b/www/src/Locales/zh-CN/SettingsPage.jsx index 3e0effcd8..6fd55c64f 100644 --- a/www/src/Locales/zh-CN/SettingsPage.jsx +++ b/www/src/Locales/zh-CN/SettingsPage.jsx @@ -53,6 +53,8 @@ export default { neutral: '回中', 'last-win': '后输入优先', 'first-win': '先输入优先', + 'y-axis-last-win': 'TODO need translation', + 'x-axis-last-win': 'TODO need translation', off: '关闭', }, 'profile-number-label': '档案编号', @@ -86,6 +88,8 @@ export default { 'socd-neutral': 'SOCD 回中模式', 'socd-last-win': 'SOCD 后输入优先', 'socd-first-win': 'SOCD 先输入优先', + 'socd-y-axis-last-win': 'TODO need translation', + 'socd-x-axis-last-win': 'TODO need translation', 'socd-off': 'SOCD 关闭', 'invert-x': '反转 X 轴', 'invert-y': '反转 Y 轴', diff --git a/www/src/Pages/SettingsPage.jsx b/www/src/Pages/SettingsPage.jsx index d29c1e323..098f0c8b6 100644 --- a/www/src/Pages/SettingsPage.jsx +++ b/www/src/Pages/SettingsPage.jsx @@ -211,6 +211,8 @@ const SOCD_MODES = [ { labelKey: 'socd-cleaning-mode-options.neutral', value: 1 }, { labelKey: 'socd-cleaning-mode-options.last-win', value: 2 }, { labelKey: 'socd-cleaning-mode-options.first-win', value: 3 }, + { labelKey: 'socd-cleaning-mode-options.y-axis-last-win', value: 5 }, + { labelKey: 'socd-cleaning-mode-options.x-axis-last-win', value: 6 }, { labelKey: 'socd-cleaning-mode-options.off', value: 4 }, ]; @@ -237,6 +239,8 @@ const HOTKEY_ACTIONS = [ { labelKey: 'hotkey-actions.socd-neutral', value: 7 }, { labelKey: 'hotkey-actions.socd-last-win', value: 8 }, { labelKey: 'hotkey-actions.socd-first-win', value: 11 }, + { labelKey: 'hotkey-actions.socd-y-axis-last-win', value: 42 }, + { labelKey: 'hotkey-actions.socd-x-axis-last-win', value: 43 }, { labelKey: 'hotkey-actions.socd-off', value: 12 }, { labelKey: 'hotkey-actions.invert-x', value: 9 }, { labelKey: 'hotkey-actions.invert-y', value: 10 }, From 14523463fea3ffa6b2855cd1d8447ee3132898c2 Mon Sep 17 00:00:00 2001 From: Philipp Meier Date: Sun, 18 Aug 2024 19:11:42 +0200 Subject: [PATCH 2/2] Fix dualdirectional (#2) --- headers/addons/dualdirectional.h | 2 +- src/addons/dualdirectional.cpp | 27 +++++++++++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/headers/addons/dualdirectional.h b/headers/addons/dualdirectional.h index de01f1655..c86db23eb 100644 --- a/headers/addons/dualdirectional.h +++ b/headers/addons/dualdirectional.h @@ -30,7 +30,7 @@ class DualDirectionalInput : public GPAddon { uint8_t filterToFourWayModeDDI(uint8_t dpad); void SOCDDualClean(SOCDMode); uint8_t SOCDCombine(SOCDMode, uint8_t); - uint8_t SOCDGamepadClean(uint8_t, bool isYLastWin, bool isXLastWin); + uint8_t SOCDGamepadClean(SOCDMode mode, uint8_t gamepadState); void OverrideGamepad(Gamepad *, DpadMode, uint8_t); const SOCDMode getSOCDMode(const GamepadOptions&); uint8_t dualState; // Dual Directional State diff --git a/src/addons/dualdirectional.cpp b/src/addons/dualdirectional.cpp index 91d14fdc1..f5f674d02 100644 --- a/src/addons/dualdirectional.cpp +++ b/src/addons/dualdirectional.cpp @@ -140,9 +140,7 @@ void DualDirectionalInput::process() dualOut = SOCDCombine(socdMode, gamepadDpad); } else if ( socdMode != SOCD_MODE_BYPASS ) { // else if not bypass, what's left is first/last input wins SOCD, which need a complicated re-clean - dualOut = SOCDGamepadClean(dualOut | gamepadDpad, - socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY, - socdMode == SOCD_MODE_SECOND_INPUT_PRIORITY || socdMode == SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY); + dualOut = SOCDGamepadClean(socdMode, dualOut | gamepadDpad); } else { // this is bypass SOCD, just OR them together dualOut |= gamepadDpad; @@ -178,12 +176,16 @@ void DualDirectionalInput::OverrideGamepad(Gamepad * gamepad, DpadMode mode, uin } } -uint8_t DualDirectionalInput::SOCDGamepadClean(uint8_t gamepadState, bool isYLastWin, bool isXLastWin) { +uint8_t DualDirectionalInput::SOCDGamepadClean(SOCDMode mode, uint8_t gamepadState) { // Gamepad SOCD Last-Win OR First-Win Clean switch (gamepadState & (GAMEPAD_MASK_UP | GAMEPAD_MASK_DOWN)) { case (GAMEPAD_MASK_UP | GAMEPAD_MASK_DOWN): // If last state was Up or Down, exclude it from our gamepad - if (isYLastWin) gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_UP : GAMEPAD_MASK_DOWN; - else gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_DOWN : GAMEPAD_MASK_UP; + if (mode == SOCD_MODE_SECOND_INPUT_PRIORITY || mode == SOCD_MODE_Y_AXIS_SECOND_INPUT_PRIORITY) + gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_UP : GAMEPAD_MASK_DOWN; + else if (mode == SOCD_MODE_FIRST_INPUT_PRIORITY) + gamepadState ^= (lastGPUD == DIRECTION_UP) ? GAMEPAD_MASK_DOWN : GAMEPAD_MASK_UP; + else + gamepadState ^= (GAMEPAD_MASK_UP | GAMEPAD_MASK_DOWN); break; case GAMEPAD_MASK_UP: gamepadState |= GAMEPAD_MASK_UP; @@ -199,11 +201,12 @@ uint8_t DualDirectionalInput::SOCDGamepadClean(uint8_t gamepadState, bool isYLas } switch (gamepadState & (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT)) { case (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT): - if (lastGPLR != DIRECTION_NONE) - if (isXLastWin) gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; - else gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_RIGHT : GAMEPAD_MASK_LEFT; - else - lastGPLR = DIRECTION_NONE; + if (mode == SOCD_MODE_SECOND_INPUT_PRIORITY || mode == SOCD_MODE_X_AXIS_SECOND_INPUT_PRIORITY) + gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_LEFT : GAMEPAD_MASK_RIGHT; + else if (mode == SOCD_MODE_FIRST_INPUT_PRIORITY) + gamepadState ^= (lastGPLR == DIRECTION_LEFT) ? GAMEPAD_MASK_RIGHT : GAMEPAD_MASK_LEFT; + else + gamepadState ^= (GAMEPAD_MASK_LEFT | GAMEPAD_MASK_RIGHT); break; case GAMEPAD_MASK_LEFT: gamepadState |= GAMEPAD_MASK_LEFT; @@ -249,7 +252,7 @@ uint8_t DualDirectionalInput::SOCDCombine(SOCDMode mode, uint8_t gamepadState) { return outState; } -void DualDirectionalInput::SOCDDualClean(SOCDMode socdMode) { +void DualDirectionalInput::SOCDDualClean(SOCDMode socdMode) { if (socdMode == SOCD_MODE_BYPASS) { return; }