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; diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 914dd60..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) { @@ -608,8 +619,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; @@ -620,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; @@ -670,7 +682,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); @@ -726,7 +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 69dcc1c..afead3b 100644 --- a/source/ButtonComboManager.h +++ b/source/ButtonComboManager.h @@ -59,4 +59,6 @@ class ButtonComboManager { std::forward_list> mCombos; std::vector mVPADButtonBuffer; std::mutex mMutex; + std::mutex mDetectButtonsMutex; + bool mInButtonComboDetection = false; }; \ No newline at end of file