From 890285d8d8bcf59cb5d0b807b16ce5c20d6a545a Mon Sep 17 00:00:00 2001 From: Adam Jorgensen Date: Tue, 26 Jul 2022 13:11:45 -0400 Subject: [PATCH] #34: Implemented SOCD cleaning and introduced third Guide button mode --- XBOFS.win.qt/WinUsbDeviceWidget.ui | 5 ++ XBOFS.win/include/XBOFS.win/WinUsbDevice.h | 1 + XBOFS.win/include/XBOFS.win/constants.h | 59 +++++++++++++++++++++- XBOFS.win/src/WinUsbDevice.cpp | 28 ++++++++-- 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/XBOFS.win.qt/WinUsbDeviceWidget.ui b/XBOFS.win.qt/WinUsbDeviceWidget.ui index 1c055ac..266f95e 100644 --- a/XBOFS.win.qt/WinUsbDeviceWidget.ui +++ b/XBOFS.win.qt/WinUsbDeviceWidget.ui @@ -295,6 +295,11 @@ Press Guide button to Switch between Bindings and Alternate Bindings + + + Normal (Disables access to Alternate Bindings) + + diff --git a/XBOFS.win/include/XBOFS.win/WinUsbDevice.h b/XBOFS.win/include/XBOFS.win/WinUsbDevice.h index d680d23..32621b3 100644 --- a/XBOFS.win/include/XBOFS.win/WinUsbDevice.h +++ b/XBOFS.win/include/XBOFS.win/WinUsbDevice.h @@ -93,6 +93,7 @@ namespace XBOFSWin { int bindings[2][15][2][7] = {}; bool buttons[15] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; GUIDE_BUTTON_MODE guideButtonMode; + SOCD_CLEANING_CONFIGURATION socdCleaningConfiguration[2]; bool deviceHandlesOpen = false; UCHAR XBO_ARCADE_STICK_INIT[5] = { 0x05, 0x20, 0x00, 0x01, 0x00 }; diff --git a/XBOFS.win/include/XBOFS.win/constants.h b/XBOFS.win/include/XBOFS.win/constants.h index 52e5753..36b3a42 100644 --- a/XBOFS.win/include/XBOFS.win/constants.h +++ b/XBOFS.win/include/XBOFS.win/constants.h @@ -20,6 +20,9 @@ namespace XBOFSWin { const QString THUMB_LY = QString::number(4); const QString THUMB_RX = QString::number(5); const QString THUMB_RY = QString::number(6); + const QString SOCD_CLEANING_ENABLED = "socdCleaningEnabled"; + const QString SOCD_CLEAN_UP_DOWN_TO = "socdCleanUpDownTo"; + const QString SOCD_CLEAN_LEFT_RIGHT_TO = "socdCleanLeftRightTo"; } enum class XBO_ARCADE_STICK_BUTTONS { @@ -42,7 +45,8 @@ namespace XBOFSWin { enum class GUIDE_BUTTON_MODE { HOLD, - TOGGLE + TOGGLE, + NORMAL }; /* @@ -267,4 +271,57 @@ namespace XBOFSWin { WCHAR bString[126]; }; + /* + * SOCD constants + */ + enum class SOCD_CLEANING_UP_DOWN_OPTIONS { + NEUTRAL, + UP, + DOWN + }; + + enum class SOCD_CLEANING_LEFT_RIGHT_OPTIONS { + NEUTRAL, + LEFT, + RIGHT + }; + + const int SOCD_UP_DOWN_MASK = XUSB_GAMEPAD_DPAD_UP | XUSB_GAMEPAD_DPAD_DOWN; + const int SOCD_LEFT_RIGHT_MASK = XUSB_GAMEPAD_DPAD_LEFT | XUSB_GAMEPAD_DPAD_RIGHT; + const int SOCD_ALL_BUTTONS_MASK = + XUSB_GAMEPAD_DPAD_UP | XUSB_GAMEPAD_DPAD_DOWN | XUSB_GAMEPAD_DPAD_LEFT | XUSB_GAMEPAD_DPAD_RIGHT | + XUSB_GAMEPAD_START | XUSB_GAMEPAD_BACK | XUSB_GAMEPAD_LEFT_THUMB | XUSB_GAMEPAD_RIGHT_THUMB | + XUSB_GAMEPAD_LEFT_SHOULDER | XUSB_GAMEPAD_RIGHT_SHOULDER | XUSB_GAMEPAD_GUIDE | + XUSB_GAMEPAD_A | XUSB_GAMEPAD_B | XUSB_GAMEPAD_X | XUSB_GAMEPAD_Y; + const int SOCD_NEGATE_UP_DOWN = SOCD_ALL_BUTTONS_MASK ^ (XUSB_GAMEPAD_DPAD_UP | XUSB_GAMEPAD_DPAD_DOWN); + const int SOCD_NEGATE_UP = SOCD_ALL_BUTTONS_MASK ^ XUSB_GAMEPAD_DPAD_UP; + const int SOCD_NEGATE_DOWN = SOCD_ALL_BUTTONS_MASK ^ XUSB_GAMEPAD_DPAD_DOWN; + const int SOCD_NEGATE_LEFT_RIGHT = SOCD_ALL_BUTTONS_MASK ^ (XUSB_GAMEPAD_DPAD_LEFT | XUSB_GAMEPAD_DPAD_RIGHT); + const int SOCD_NEGATE_LEFT = SOCD_ALL_BUTTONS_MASK ^ XUSB_GAMEPAD_DPAD_LEFT; + const int SOCD_NEGATE_RIGHT = SOCD_ALL_BUTTONS_MASK ^ XUSB_GAMEPAD_DPAD_RIGHT; + + const std::map socdCleaningUpDownOptionsMapping { + {SOCD_CLEANING_UP_DOWN_OPTIONS::NEUTRAL, SOCD_NEGATE_UP_DOWN}, + {SOCD_CLEANING_UP_DOWN_OPTIONS::UP, SOCD_NEGATE_DOWN}, + {SOCD_CLEANING_UP_DOWN_OPTIONS::DOWN, SOCD_NEGATE_UP} + }; + + const std::map socdCleaningLeftRightOptionsMapping{ + {SOCD_CLEANING_LEFT_RIGHT_OPTIONS::NEUTRAL, SOCD_NEGATE_LEFT_RIGHT}, + {SOCD_CLEANING_LEFT_RIGHT_OPTIONS::LEFT, SOCD_NEGATE_RIGHT}, + {SOCD_CLEANING_LEFT_RIGHT_OPTIONS::RIGHT, SOCD_NEGATE_LEFT} + }; + + struct SOCD_CLEANING_CONFIGURATION { + std::map upDownMasks { + {0, SOCD_ALL_BUTTONS_MASK}, + {XUSB_GAMEPAD_DPAD_UP, SOCD_ALL_BUTTONS_MASK}, + {XUSB_GAMEPAD_DPAD_DOWN, SOCD_ALL_BUTTONS_MASK} + }; + std::map leftRightMasks { + {0, SOCD_ALL_BUTTONS_MASK}, + {XUSB_GAMEPAD_DPAD_LEFT, SOCD_ALL_BUTTONS_MASK}, + {XUSB_GAMEPAD_DPAD_RIGHT, SOCD_ALL_BUTTONS_MASK} + }; + }; } diff --git a/XBOFS.win/src/WinUsbDevice.cpp b/XBOFS.win/src/WinUsbDevice.cpp index 2ec3719..8144e92 100644 --- a/XBOFS.win/src/WinUsbDevice.cpp +++ b/XBOFS.win/src/WinUsbDevice.cpp @@ -41,12 +41,27 @@ void WinUsbDevice::refreshSettings() { bindingSelector = 0; debugEnabled = settings.value(settings::DEBUG_ENABLED, false).toBool(); activeProfile = settings.value(settings::ACTIVE_PROFILE, "").toString(); - guideButtonMode = (GUIDE_BUTTON_MODE)settings.value(QString("%1/%2").arg(activeProfile, settings::GUIDE_BUTTON_MODE), 0).toInt(); + guideButtonMode = static_cast(settings.value(QString("%1/%2").arg(activeProfile, settings::GUIDE_BUTTON_MODE), 0).toInt()); // Configure control bindings logger->info(bindingEnabled ? "Binding Enabled" : "Binding Disabled"); for (int bindingsSelector = 0; bindingsSelector < 2; bindingsSelector++) { + // Configure SOCD cleaning + auto bindingsSelectorQString = QString::number(bindingsSelector); + auto key = QString("%1/%2").arg(activeProfile, bindingsSelectorQString); + auto socdCleaningEnabled = settings.value(QString("%1/%2").arg(key, settings::SOCD_CLEANING_ENABLED), false).toBool(); + auto socdCleanUpDownTo = settings.value(QString("%1/%2").arg(key, settings::SOCD_CLEAN_UP_DOWN_TO), static_cast(SOCD_CLEANING_UP_DOWN_OPTIONS::NEUTRAL)).toInt(); + auto socdCleanLeftRightTo = settings.value(QString("%1/%2").arg(key, settings::SOCD_CLEAN_LEFT_RIGHT_TO), static_cast(SOCD_CLEANING_LEFT_RIGHT_OPTIONS::NEUTRAL)).toInt(); + socdCleaningConfiguration[bindingsSelector].upDownMasks.insert_or_assign( + XUSB_GAMEPAD_DPAD_UP | XUSB_GAMEPAD_DPAD_DOWN, + socdCleaningEnabled ? socdCleaningUpDownOptionsMapping.at(static_cast(socdCleanUpDownTo)) : SOCD_ALL_BUTTONS_MASK + ); + socdCleaningConfiguration[bindingsSelector].leftRightMasks.insert_or_assign( + XUSB_GAMEPAD_DPAD_LEFT | XUSB_GAMEPAD_DPAD_RIGHT, + socdCleaningEnabled ? socdCleaningLeftRightOptionsMapping.at(static_cast(socdCleanLeftRightTo)) : SOCD_ALL_BUTTONS_MASK + ); + // Configure Bindings for (int xboArcadeStickButtonSelector = 0; xboArcadeStickButtonSelector < 15; xboArcadeStickButtonSelector++) { - auto key = QString("%1/%2/%3").arg(activeProfile, QString::number(bindingsSelector), QString::number(xboArcadeStickButtonSelector)); + auto key = QString("%1/%2/%3").arg(activeProfile, bindingsSelectorQString, QString::number(xboArcadeStickButtonSelector)); auto bindEnabled = settings.value(QString("%1/%2").arg(key, settings::BIND_ENABLED), false).toBool(); for (int outputValueSelector = 0; outputValueSelector < 7; outputValueSelector++) { auto value = bindingEnabled && bindEnabled @@ -242,7 +257,7 @@ PACKET_TYPES WinUsbDevice::processInputFromXBOArcadeStick() { return PACKET_TYPES::HEARTBEAT; case 0x07: // Guide button guideButtonState = dataPacket.data[4] & 0x01; - if (!bindingEnabled) { + if (!bindingEnabled || guideButtonMode == GUIDE_BUTTON_MODE::NORMAL) { buttons[(int)XBO_ARCADE_STICK_BUTTONS::GUIDE] = guideButtonState; } else { @@ -310,6 +325,13 @@ XUSB_REPORT WinUsbDevice::prepareInputForVigEmController() { controllerData.sThumbRX |= rxValue; controllerData.sThumbRY |= ryValue; } + // SOCD cleaning + auto upDownCheck = SOCD_UP_DOWN_MASK & controllerData.wButtons; + auto upDownMask = socdCleaningConfiguration[bindingSelector].upDownMasks.at(upDownCheck); + controllerData.wButtons &= upDownMask; + auto leftRightCheck = SOCD_LEFT_RIGHT_MASK & controllerData.wButtons; + auto leftRightMask = socdCleaningConfiguration[bindingSelector].leftRightMasks.at(leftRightCheck); + controllerData.wButtons &= leftRightMask; return controllerData; }