From b3abc17d1ed261e1bbb717eb005d9d1187fd6c65 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 5 Jan 2025 17:46:17 +0100 Subject: [PATCH 1/3] Fix ButtonComboDetection for WPAD controllers --- source/ButtonComboManager.cpp | 5 +---- source/ButtonComboManager.h | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 914dd60..658e467 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -608,8 +608,7 @@ ButtonComboModule_ComboStatus ButtonComboManager::CheckComboAvailable(const Butt ButtonComboModule_Error ButtonComboManager::DetectButtonCombo_Blocking(const ButtonComboModule_DetectButtonComboOptions &options, ButtonComboModule_Buttons &outButtonCombo) { - std::lock_guard lock(mMutex); - + std::lock_guard lock(mDetectButtonsMutex); if (options.controllerMask == BUTTON_COMBO_MODULE_CONTROLLER_NONE) { DEBUG_FUNCTION_LINE_WARN("Failed to detect button combo: Controller Mask was empty."); return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; @@ -670,7 +669,6 @@ ButtonComboModule_Error ButtonComboManager::DetectButtonCombo_Blocking(const But uint32_t convertedButtons = 0; kpad_data = {}; if (KPADReadEx(static_cast(i), &kpad_data, 1, &kpad_error) > 0) { - DEBUG_FUNCTION_LINE_ERR("KPAD chan %d success %d %d", i, kpad_error, kpad_data.extensionType); if (kpad_error == KPAD_ERROR_OK && kpad_data.extensionType != 0xFF) { if (kpad_data.extensionType == WPAD_EXT_CORE || kpad_data.extensionType == WPAD_EXT_NUNCHUK) { convertedButtons = remapWiiMoteButtons(kpad_data.hold); @@ -727,6 +725,5 @@ ButtonComboModule_Error ButtonComboManager::DetectButtonCombo_Blocking(const But KPADShutdown(); } - return result; } diff --git a/source/ButtonComboManager.h b/source/ButtonComboManager.h index 69dcc1c..0f37abc 100644 --- a/source/ButtonComboManager.h +++ b/source/ButtonComboManager.h @@ -59,4 +59,5 @@ class ButtonComboManager { std::forward_list> mCombos; std::vector mVPADButtonBuffer; std::mutex mMutex; + std::mutex mDetectButtonsMutex; }; \ No newline at end of file From 68c2ed4cfa83389b044b39ee4348a99e6f23252f Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 5 Jan 2025 17:47:37 +0100 Subject: [PATCH 2/3] Do not check for button combos while the button combo detection is active --- source/ButtonComboManager.cpp | 14 ++++++++++++++ source/ButtonComboManager.h | 1 + 2 files changed, 15 insertions(+) diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 658e467..f25c23c 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -404,6 +404,11 @@ void ButtonComboManager::UpdateInputVPAD(const VPADChan chan, const VPADStatus * return; } + // Do not check for combos while the combo detection is active + if (mInButtonComboDetection) { + return; + } + { std::lock_guard lock(mMutex); const auto controller = convert(chan); @@ -440,6 +445,12 @@ void ButtonComboManager::UpdateInputWPAD(const WPADChan chan, WPADStatus *data) DEBUG_FUNCTION_LINE_VERBOSE("Invalid data or state"); return; } + + // Do not check for combos while the combo detection is active + if (mInButtonComboDetection) { + return; + } + const auto controller = convert(chan); uint32_t pressedButtons = {}; switch (data->extensionType) { @@ -619,6 +630,8 @@ ButtonComboModule_Error ButtonComboManager::DetectButtonCombo_Blocking(const But return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; } + mInButtonComboDetection = true; + bool doShutdownKPAD = false; bool doDisableProController = false; KPADStatus status; @@ -724,6 +737,7 @@ ButtonComboModule_Error ButtonComboManager::DetectButtonCombo_Blocking(const But if (doShutdownKPAD) { KPADShutdown(); } + mInButtonComboDetection = true; return result; } diff --git a/source/ButtonComboManager.h b/source/ButtonComboManager.h index 0f37abc..afead3b 100644 --- a/source/ButtonComboManager.h +++ b/source/ButtonComboManager.h @@ -60,4 +60,5 @@ class ButtonComboManager { std::vector mVPADButtonBuffer; std::mutex mMutex; std::mutex mDetectButtonsMutex; + bool mInButtonComboDetection = false; }; \ No newline at end of file From 26fafe671bd7b6d3c55613be410c21a1e4baa7cf Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 5 Jan 2025 17:48:06 +0100 Subject: [PATCH 3/3] Reset the prevInput after a button combo or controller mask has been updated --- source/ButtonComboInfo.cpp | 2 ++ source/ButtonComboInfo.h | 2 ++ source/ButtonComboInfoDown.cpp | 7 +++++++ source/ButtonComboInfoDown.h | 3 +++ source/ButtonComboInfoHold.cpp | 7 +++++++ source/ButtonComboInfoHold.h | 2 ++ 6 files changed, 23 insertions(+) diff --git a/source/ButtonComboInfo.cpp b/source/ButtonComboInfo.cpp index 5ae3632..52a83f1 100644 --- a/source/ButtonComboInfo.cpp +++ b/source/ButtonComboInfo.cpp @@ -61,6 +61,7 @@ uint32_t ButtonComboInfoIF::getCombo() const { void ButtonComboInfoIF::setCombo(const ButtonComboModule_Buttons combo) { mCombo = combo; DEBUG_FUNCTION_LINE("Updated combo to: %08X, for %s %08X", mCombo, mLabel.c_str(), getHandle().handle); + resetPrevInput(); } ButtonComboModule_ComboStatus ButtonComboInfoIF::getStatus() const { @@ -79,6 +80,7 @@ ButtonComboModule_ControllerTypes ButtonComboInfoIF::getControllerMask() const { void ButtonComboInfoIF::setControllerMask(const ButtonComboModule_ControllerTypes mask) { mControllerMask = mask; DEBUG_FUNCTION_LINE("Updated controllerMask to: %08X, for %s %08X", mControllerMask, mLabel.c_str(), getHandle().handle); + resetPrevInput(); } bool ButtonComboInfoIF::conflictsWith(const ButtonComboModule_ButtonComboOptions &other) const { diff --git a/source/ButtonComboInfo.h b/source/ButtonComboInfo.h index 70e8bfb..192e9a9 100644 --- a/source/ButtonComboInfo.h +++ b/source/ButtonComboInfo.h @@ -46,6 +46,8 @@ class ButtonComboInfoIF { [[nodiscard]] virtual ButtonComboModule_ButtonComboInfoEx getComboInfoEx() const = 0; + virtual void resetPrevInput() = 0; + protected: static int32_t ControllerTypeToChanIndex(ButtonComboModule_ControllerTypes type); diff --git a/source/ButtonComboInfoDown.cpp b/source/ButtonComboInfoDown.cpp index 2f26e13..07c729c 100644 --- a/source/ButtonComboInfoDown.cpp +++ b/source/ButtonComboInfoDown.cpp @@ -58,3 +58,10 @@ ButtonComboModule_ButtonComboInfoEx ButtonComboInfoDown::getComboInfoEx() const .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, .optionalHoldForXMs = 0}; } + +void ButtonComboInfoDown::resetPrevInput() { + for (uint32_t i = 0; i < std::size(mHoldInformation); ++i) { + mHoldInformation[i] = {}; + mHoldInformation[i].prevButtonCombo = 0xFFFFFFFF; + } +} diff --git a/source/ButtonComboInfoDown.h b/source/ButtonComboInfoDown.h index 4521227..b7f2b4e 100644 --- a/source/ButtonComboInfoDown.h +++ b/source/ButtonComboInfoDown.h @@ -29,5 +29,8 @@ class ButtonComboInfoDown final : public ButtonComboInfoIF { [[nodiscard]] ButtonComboModule_ButtonComboInfoEx getComboInfoEx() const override; + void resetPrevInput() override; + +private: HoldInformation mHoldInformation[9] = {}; // one for each controller }; \ No newline at end of file diff --git a/source/ButtonComboInfoHold.cpp b/source/ButtonComboInfoHold.cpp index 26e1f68..696cfb2 100644 --- a/source/ButtonComboInfoHold.cpp +++ b/source/ButtonComboInfoHold.cpp @@ -76,3 +76,10 @@ ButtonComboModule_ButtonComboInfoEx ButtonComboInfoHold::getComboInfoEx() const .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, .optionalHoldForXMs = mTargetDurationInMs}; } + +void ButtonComboInfoHold::resetPrevInput() { + for (uint32_t i = 0; i < std::size(mHoldInformation); ++i) { + mHoldInformation[i] = {}; + mHoldInformation[i].prevButtonCombo = 0xFFFFFFFF; + } +} diff --git a/source/ButtonComboInfoHold.h b/source/ButtonComboInfoHold.h index c262555..3c7bdbb 100644 --- a/source/ButtonComboInfoHold.h +++ b/source/ButtonComboInfoHold.h @@ -31,6 +31,8 @@ class ButtonComboInfoHold final : public ButtonComboInfoIF { [[nodiscard]] ButtonComboModule_ButtonComboInfoEx getComboInfoEx() const override; + void resetPrevInput() override; + private: typedef struct { OSTime holdStartedAt;