From 91fc2ae4d141e000e26cf6a520ebc8edd9d7381f Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 30 Dec 2024 10:07:37 +0100 Subject: [PATCH 1/7] Use std::forward_list instead of std::vector --- source/ButtonComboManager.cpp | 17 +++++++++-------- source/ButtonComboManager.h | 3 ++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 503457d..b5d3c70 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -12,15 +12,16 @@ #include namespace { - template - bool remove_first_if(std::vector &list, Predicate pred) { - auto it = list.begin(); - while (it != list.end()) { - if (pred(*it)) { - list.erase(it); + template + std::enable_if_t>, bool> + remove_first_if(Container &container, Predicate pred) { + auto it = container.before_begin(); + + for (auto prev = it, current = ++it; current != container.end(); ++prev, ++current) { + if (pred(*current)) { + container.erase_after(prev); return true; } - ++it; } return false; @@ -345,7 +346,7 @@ void ButtonComboManager::AddCombo(std::shared_ptr newComboInf outStatus = CheckComboStatus(*newComboInfo); newComboInfo->setStatus(outStatus); outHandle = newComboInfo->getHandle(); - mCombos.push_back(std::move(newComboInfo)); + mCombos.emplace_front(std::move(newComboInfo)); const auto block = hasActiveComboWithTVButton(); VPADSetTVMenuInvalid(VPAD_CHAN_0, block); diff --git a/source/ButtonComboManager.h b/source/ButtonComboManager.h index 68947d0..a925b4f 100644 --- a/source/ButtonComboManager.h +++ b/source/ButtonComboManager.h @@ -10,6 +10,7 @@ #include #include +#include class ButtonComboManager { @@ -56,7 +57,7 @@ class ButtonComboManager { ButtonComboModule_Error DetectButtonCombo_Blocking(const ButtonComboModule_DetectButtonComboOptions &options, ButtonComboModule_Buttons &outButtonCombo); private: - std::vector> mCombos; + std::forward_list> mCombos; std::vector mVPADButtonBuffer; std::mutex mMutex; }; \ No newline at end of file From aa6c6a42f4da9ce2d9ab8f095c47f1295a9d3ece Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 1 Jan 2025 12:49:42 +0100 Subject: [PATCH 2/7] Fix ButtonComboInfoHold::getComboInfoEx implementation --- source/ButtonComboInfoHold.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ButtonComboInfoHold.cpp b/source/ButtonComboInfoHold.cpp index 29ceef6..2b07684 100644 --- a/source/ButtonComboInfoHold.cpp +++ b/source/ButtonComboInfoHold.cpp @@ -99,5 +99,5 @@ ButtonComboModule_Error ButtonComboInfoHold::setHoldDuration(const uint32_t hold ButtonComboModule_ButtonComboInfoEx ButtonComboInfoHold::getComboInfoEx() const { return {.type = mIsObserver ? BUTTON_COMBO_MODULE_TYPE_HOLD_OBSERVER : BUTTON_COMBO_MODULE_TYPE_HOLD, .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, - .optionalHoldForXFrames = 0}; + .optionalHoldForXFrames = mTargetDurationInMs}; } From 0e101b6e34203d82238d17f8e78729d420a32d27 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 1 Jan 2025 12:53:31 +0100 Subject: [PATCH 3/7] Add additional logging --- source/ButtonComboInfo.cpp | 5 +++++ source/ButtonComboInfoDown.cpp | 8 ++++++++ source/ButtonComboInfoDown.h | 1 + source/ButtonComboInfoHold.cpp | 11 ++++++++++- source/ButtonComboInfoHold.h | 2 ++ source/ButtonComboManager.cpp | 10 ++++++++-- source/export.cpp | 15 ++++++++++++++- source/main.cpp | 5 +++++ 8 files changed, 53 insertions(+), 4 deletions(-) diff --git a/source/ButtonComboInfo.cpp b/source/ButtonComboInfo.cpp index acd71eb..a372023 100644 --- a/source/ButtonComboInfo.cpp +++ b/source/ButtonComboInfo.cpp @@ -42,6 +42,7 @@ bool ButtonComboInfoIF::getMetaOptions(const ButtonComboModule_MetaOptionsOut &o void ButtonComboInfoIF::setMetaOptions(ButtonComboModule_MetaOptions options) { mLabel = options.label; + DEBUG_FUNCTION_LINE("Updated label to: \"%s\", for %08X", mLabel.c_str(), getHandle().handle); } ButtonComboModule_CallbackOptions ButtonComboInfoIF::getCallbackOptions() const { @@ -51,6 +52,7 @@ ButtonComboModule_CallbackOptions ButtonComboInfoIF::getCallbackOptions() const void ButtonComboInfoIF::setCallbackOptions(ButtonComboModule_CallbackOptions options) { mCallback = options.callback; mContext = options.context; + DEBUG_FUNCTION_LINE("Updated callback to: %08X(%08X), for %s %08X", mCallback, mContext, mLabel.c_str(), getHandle().handle); } uint32_t ButtonComboInfoIF::getCombo() const { @@ -58,6 +60,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); } ButtonComboModule_ComboStatus ButtonComboInfoIF::getStatus() const { @@ -66,6 +69,7 @@ ButtonComboModule_ComboStatus ButtonComboInfoIF::getStatus() const { void ButtonComboInfoIF::setStatus(const ButtonComboModule_ComboStatus status) { mStatus = status; + DEBUG_FUNCTION_LINE("Updated status to: %08X, for %s %08X", mStatus, mLabel.c_str(), getHandle().handle); } ButtonComboModule_ControllerTypes ButtonComboInfoIF::getControllerMask() const { @@ -74,6 +78,7 @@ ButtonComboModule_ControllerTypes ButtonComboInfoIF::getControllerMask() const { void ButtonComboInfoIF::setControllerMask(ButtonComboModule_ControllerTypes mask) { mControllerMask = mask; + DEBUG_FUNCTION_LINE("Updated controllerMask to: %08X, for %s %08X", mControllerMask, mLabel.c_str(), getHandle().handle); } bool ButtonComboInfoIF::conflictsWith(const ButtonComboModule_ButtonComboOptions &other) const { diff --git a/source/ButtonComboInfoDown.cpp b/source/ButtonComboInfoDown.cpp index 5755ad2..81b6309 100644 --- a/source/ButtonComboInfoDown.cpp +++ b/source/ButtonComboInfoDown.cpp @@ -9,6 +9,11 @@ ButtonComboInfoDown::ButtonComboInfoDown( const ButtonComboModule_ComboCallback callback, void *context, const bool observer) : ButtonComboInfoIF(std::move(label), controllerMask, combo, callback, context, observer) { + DEBUG_FUNCTION_LINE_INFO("Created ButtonComboInfoDown: \"%s\", combo: %08X, controllerMask: %08X. Observer %d", mLabel.c_str(), mCombo, mControllerMask, observer); +} + +ButtonComboInfoDown::~ButtonComboInfoDown() { + DEBUG_FUNCTION_LINE_INFO("Deleted ButtonComboInfoDown: \"%s\", combo: %08X, controllerMask: %08X. Observer %d", mLabel.c_str(), mCombo, mControllerMask, mIsObserver); } void ButtonComboInfoDown::UpdateInput( @@ -18,6 +23,8 @@ void ButtonComboInfoDown::UpdateInput( return; } + DEBUG_FUNCTION_LINE_VERBOSE("[PRESS DOWN] Check button combo %08X on controller %08X (lastItem im pressedButtons (size %d) is %08X) for %s [%08X]", mCombo, controller, pressedButtons.size(), pressedButtons.back(), mLabel.c_str(), getHandle().handle); + for (const auto &pressedButton : pressedButtons) { const bool prevButtonsIncludedCombo = (mPrevButtonPress & mCombo) == mCombo; // Make sure the combo can't be triggered on releasing const bool buttonsPressedChanged = mPrevButtonPress != pressedButton; // Avoid "holding" the combo @@ -26,6 +33,7 @@ void ButtonComboInfoDown::UpdateInput( if (buttonsPressedChanged && buttonsPressedMatchCombo && !prevButtonsIncludedCombo) { if (mCallback != nullptr) { mCallback(getHandle(), mContext); + DEBUG_FUNCTION_LINE("Calling callback [%08X](%08X) for \"%s\" [handle: %08X], pressed down %08X", mCallback, mContext, mLabel.c_str(), getHandle().handle, mCombo); } else { DEBUG_FUNCTION_LINE_WARN("Callback was null for combo %08X", getHandle()); } diff --git a/source/ButtonComboInfoDown.h b/source/ButtonComboInfoDown.h index 349cd30..0c8e3c6 100644 --- a/source/ButtonComboInfoDown.h +++ b/source/ButtonComboInfoDown.h @@ -16,6 +16,7 @@ class ButtonComboInfoDown final : public ButtonComboInfoIF { ButtonComboModule_ComboCallback callback, void *context, bool observer); + ~ButtonComboInfoDown() override; private: void UpdateInput(ButtonComboModule_ControllerTypes controller, std::span pressedButtons) override; diff --git a/source/ButtonComboInfoHold.cpp b/source/ButtonComboInfoHold.cpp index 2b07684..151a1a9 100644 --- a/source/ButtonComboInfoHold.cpp +++ b/source/ButtonComboInfoHold.cpp @@ -53,9 +53,14 @@ ButtonComboInfoHold::ButtonComboInfoHold(std::string label, context, observer), mTargetDurationInFrames(targetDuration) { + DEBUG_FUNCTION_LINE_INFO("Created ButtonComboInfoDown: \"%s\", combo: %08X, targetDurationInMs: %d ms, controllerMask: %08X", mLabel.c_str(), mCombo, mTargetDurationInMs, mControllerMask); } -void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes controller, std::span pressedButtons) { +ButtonComboInfoHold::~ButtonComboInfoHold() { + DEBUG_FUNCTION_LINE_INFO("Deleted ButtonComboInfoDown: \"%s\", combo: %08X, targetDurationInMs: %d ms, controllerMask: %08X", mLabel.c_str(), mCombo, mTargetDurationInMs, mControllerMask); +} + +void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes controller, const std::span pressedButtons) { if ((mControllerMask & controller) == 0) { return; } @@ -68,6 +73,8 @@ void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes co auto &holdInformation = mHoldInformation[chanIndex]; const auto latestButtonPress = pressedButtons.back(); + DEBUG_FUNCTION_LINE_VERBOSE("[HOLD ] Check button combo %08X on controller %08X (lastItem im pressedButtons (size %d) is %08X) for %s [%08X]", mCombo, controller, pressedButtons.size(), latestButtonPress, mLabel.c_str(), getHandle().handle); + const bool prevButtonsIncludedCombo = (holdInformation.prevButtonCombo & mCombo) == mCombo; // Make sure the combo can't be triggered on releasing const bool buttonsPressedChanged = holdInformation.prevButtonCombo != latestButtonPress; // Avoid "holding" the combo const bool buttonsPressedMatchCombo = latestButtonPress == mCombo; // detect the actual combo @@ -79,6 +86,7 @@ void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes co if (holdInformation.durationInFrames > mTargetDurationInFrames && !holdInformation.callbackTriggered) { if (mCallback != nullptr) { mCallback(getHandle(), mContext); + DEBUG_FUNCTION_LINE("Calling callback [%08X](%08X) for \"%s\" [handle: %08X], hold %08X for %d ms", mCallback, mContext, mLabel.c_str(), getHandle().handle, mCombo, intervalInMs); } else { DEBUG_FUNCTION_LINE_WARN("Callback was null for combo %08X", getHandle()); @@ -93,6 +101,7 @@ void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes co ButtonComboModule_Error ButtonComboInfoHold::setHoldDuration(const uint32_t holdDurationInFrames) { mTargetDurationInFrames = holdDurationInFrames; + DEBUG_FUNCTION_LINE("Setting holdDurationInMs to %d for %s [%08X]", holdDurationInMs, mLabel.c_str(), getHandle().handle); return BUTTON_COMBO_MODULE_ERROR_SUCCESS; } diff --git a/source/ButtonComboInfoHold.h b/source/ButtonComboInfoHold.h index 7c2e7e1..c5707f3 100644 --- a/source/ButtonComboInfoHold.h +++ b/source/ButtonComboInfoHold.h @@ -21,6 +21,8 @@ class ButtonComboInfoHold final : public ButtonComboInfoIF { void *context, bool observer); + ~ButtonComboInfoHold() override; + private: void UpdateInput(ButtonComboModule_ControllerTypes controller, std::span pressedButtons) override; diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index b5d3c70..29a6041 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -416,8 +416,12 @@ void ButtonComboManager::UpdateInputVPAD(const VPADChan chan, const VPADStatus * } void ButtonComboManager::UpdateInputWPAD(const WPADChan chan, WPADStatus *data) { - if (chan < WPAD_CHAN_0 || chan > WPAD_CHAN_6 || !data || data->error || data->extensionType == 0xFF) { - DEBUG_FUNCTION_LINE_ERR("Invalid WPADChan or data state"); + if (chan < WPAD_CHAN_0 || chan > WPAD_CHAN_6) { + DEBUG_FUNCTION_LINE_WARN("Invalid WPADChan %d", chan); + return; + } + if (!data || data->error || data->extensionType == 0xFF) { + DEBUG_FUNCTION_LINE_VERBOSE("Invalid data or state"); return; } const auto controller = convert(chan); @@ -651,10 +655,12 @@ ButtonComboModule_Error ButtonComboManager::DetectButtonCombo_Blocking(const But lastHold = buttonsHold; if (holdFor >= holdAbortTarget && lastHold == abortButton) { + DEBUG_FUNCTION_LINE("Aborted button combo detection"); return BUTTON_COMBO_MODULE_ERROR_ABORTED; } if (holdFor >= holdForTarget) { + DEBUG_FUNCTION_LINE_INFO("Detected button combo %08X", lastHold); outButtonCombo = static_cast(lastHold); break; } diff --git a/source/export.cpp b/source/export.cpp index e16c3b3..24c1e20 100644 --- a/source/export.cpp +++ b/source/export.cpp @@ -2,6 +2,7 @@ #include "globals.h" #include +#include #include @@ -19,6 +20,7 @@ ButtonComboModule_Error ButtonComboModule_AddButtonCombo(const ButtonComboModule ButtonComboModule_Error err = BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; const auto comboInfoMaybe = ButtonComboManager::CreateComboInfo(*options, err); if (!comboInfoMaybe || err != BUTTON_COMBO_MODULE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_WARN("Failed to create combo info for options"); return err; } @@ -37,13 +39,13 @@ ButtonComboModule_Error ButtonComboModule_RemoveButtonCombo(const ButtonComboMod } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } return gButtonComboManager->RemoveCombo(handle); } - ButtonComboModule_Error ButtonComboModule_GetButtonComboStatus(const ButtonComboModule_ComboHandle handle, ButtonComboModule_ComboStatus *outComboStatus) { if (handle == nullptr || outComboStatus == nullptr) { @@ -51,6 +53,7 @@ ButtonComboModule_Error ButtonComboModule_GetButtonComboStatus(const ButtonCombo } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -63,6 +66,7 @@ ButtonComboModule_Error ButtonComboModule_UpdateButtonComboMeta(const ButtonComb return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -75,6 +79,7 @@ ButtonComboModule_Error ButtonComboModule_UpdateButtonComboCallback(const Button return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -89,6 +94,7 @@ ButtonComboModule_Error ButtonComboModule_UpdateControllerMask(const ButtonCombo } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -106,6 +112,7 @@ ButtonComboModule_Error ButtonComboModule_UpdateButtonCombo(const ButtonComboMod } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -122,6 +129,7 @@ ButtonComboModule_Error ButtonComboModule_UpdateHoldDuration(const ButtonComboMo } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -135,6 +143,7 @@ ButtonComboModule_Error ButtonComboModule_GetButtonComboMeta(const ButtonComboMo } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -148,6 +157,7 @@ ButtonComboModule_Error ButtonComboModule_GetButtonComboCallback(const ButtonCom } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -161,6 +171,7 @@ ButtonComboModule_Error ButtonComboModule_GetButtonComboInfoEx(const ButtonCombo } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -173,6 +184,7 @@ ButtonComboModule_Error ButtonComboModule_CheckComboAvailable(const ButtonComboM return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } @@ -187,6 +199,7 @@ ButtonComboModule_Error ButtonComboModule_DetectButtonCombo_Blocking(const Butto } if (!gButtonComboManager) { + DEBUG_FUNCTION_LINE_ERR("gButtonComboManager was nullptr"); return BUTTON_COMBO_MODULE_ERROR_UNKNOWN_ERROR; } diff --git a/source/main.cpp b/source/main.cpp index 73b02e2..3f8a6e2 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -49,7 +49,12 @@ WUMS_DEINITIALIZE() { } WUMS_APPLICATION_STARTS() { + initLogging(); OSReport("Running ButtonComboModule " MODULE_VERSION MODULE_VERSION_EXTRA "\n"); InitDRCAttachCallbacks(); } + +WUMS_APPLICATION_ENDS() { + deinitLogging(); +} From 0544c48e7edaf6b5108c96c08b2d0a425e23a529 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 1 Jan 2025 12:54:26 +0100 Subject: [PATCH 4/7] Fix ButtonComboInfoHold::UpdateInput controller channel check --- source/ButtonComboInfoHold.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/ButtonComboInfoHold.cpp b/source/ButtonComboInfoHold.cpp index 151a1a9..a4fd5f1 100644 --- a/source/ButtonComboInfoHold.cpp +++ b/source/ButtonComboInfoHold.cpp @@ -65,7 +65,7 @@ void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes co return; } const auto chanIndex = controllerTypeToChanIndex(controller); - if (chanIndex < 0 || static_cast(chanIndex) >= pressedButtons.size()) { + if (chanIndex < 0 || static_cast(chanIndex) >= std::size(mHoldInformation)) { DEBUG_FUNCTION_LINE_WARN("ChanIndex is out of bounds %d", chanIndex); return; } From 37c12720c384b01e8827f7151f486a62730b113a Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 1 Jan 2025 12:56:38 +0100 Subject: [PATCH 5/7] Add const where possible --- source/ButtonComboInfo.cpp | 6 +++--- source/ButtonComboInfoDown.cpp | 1 + source/ButtonComboManager.cpp | 7 ++++--- source/ButtonComboManager.h | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/ButtonComboInfo.cpp b/source/ButtonComboInfo.cpp index a372023..ae07cc6 100644 --- a/source/ButtonComboInfo.cpp +++ b/source/ButtonComboInfo.cpp @@ -40,7 +40,7 @@ bool ButtonComboInfoIF::getMetaOptions(const ButtonComboModule_MetaOptionsOut &o return false; } -void ButtonComboInfoIF::setMetaOptions(ButtonComboModule_MetaOptions options) { +void ButtonComboInfoIF::setMetaOptions(const ButtonComboModule_MetaOptions options) { mLabel = options.label; DEBUG_FUNCTION_LINE("Updated label to: \"%s\", for %08X", mLabel.c_str(), getHandle().handle); } @@ -49,7 +49,7 @@ ButtonComboModule_CallbackOptions ButtonComboInfoIF::getCallbackOptions() const return {.callback = mCallback, .context = mContext}; } -void ButtonComboInfoIF::setCallbackOptions(ButtonComboModule_CallbackOptions options) { +void ButtonComboInfoIF::setCallbackOptions(const ButtonComboModule_CallbackOptions options) { mCallback = options.callback; mContext = options.context; DEBUG_FUNCTION_LINE("Updated callback to: %08X(%08X), for %s %08X", mCallback, mContext, mLabel.c_str(), getHandle().handle); @@ -76,7 +76,7 @@ ButtonComboModule_ControllerTypes ButtonComboInfoIF::getControllerMask() const { return mControllerMask; } -void ButtonComboInfoIF::setControllerMask(ButtonComboModule_ControllerTypes mask) { +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); } diff --git a/source/ButtonComboInfoDown.cpp b/source/ButtonComboInfoDown.cpp index 81b6309..046bdb2 100644 --- a/source/ButtonComboInfoDown.cpp +++ b/source/ButtonComboInfoDown.cpp @@ -45,6 +45,7 @@ void ButtonComboInfoDown::UpdateInput( ButtonComboModule_Error ButtonComboInfoDown::setHoldDuration(uint32_t) { return BUTTON_COMBO_MODULE_ERROR_SUCCESS; } + ButtonComboModule_ButtonComboInfoEx ButtonComboInfoDown::getComboInfoEx() const { return {.type = mIsObserver ? BUTTON_COMBO_MODULE_TYPE_PRESS_DOWN_OBSERVER : BUTTON_COMBO_MODULE_TYPE_PRESS_DOWN, .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 29a6041..939a047 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -359,6 +359,7 @@ ButtonComboModule_Error ButtonComboManager::RemoveCombo(ButtonComboModule_ComboH DEBUG_FUNCTION_LINE_WARN("Failed to remove combo by handle %08X", handle); } else { const auto block = hasActiveComboWithTVButton(); + VPADSetTVMenuInvalid(VPAD_CHAN_0, block); VPADSetTVMenuInvalid(VPAD_CHAN_1, block); } @@ -459,7 +460,7 @@ void ButtonComboManager::UpdateInputWPAD(const WPADChan chan, WPADStatus *data) } } -ButtonComboInfoIF *ButtonComboManager::GetComboInfoForHandle(const ButtonComboModule_ComboHandle handle) { +ButtonComboInfoIF *ButtonComboManager::GetComboInfoForHandle(const ButtonComboModule_ComboHandle handle) const { for (const auto &combo : mCombos) { if (combo->getHandle() == handle) { return combo.get(); @@ -559,7 +560,7 @@ ButtonComboModule_Error ButtonComboManager::GetButtonComboMeta(const ButtonCombo ButtonComboModule_Error ButtonComboManager::GetButtonComboCallback(const ButtonComboModule_ComboHandle handle, ButtonComboModule_CallbackOptions &outOptions) { std::lock_guard lock(mMutex); - auto *comboInfo = GetComboInfoForHandle(handle); + const auto *comboInfo = GetComboInfoForHandle(handle); if (!comboInfo) { return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; } @@ -571,7 +572,7 @@ ButtonComboModule_Error ButtonComboManager::GetButtonComboCallback(const ButtonC ButtonComboModule_Error ButtonComboManager::GetButtonComboInfoEx(const ButtonComboModule_ComboHandle handle, ButtonComboModule_ButtonComboInfoEx &outOptions) { std::lock_guard lock(mMutex); - auto *comboInfo = GetComboInfoForHandle(handle); + const auto *comboInfo = GetComboInfoForHandle(handle); if (!comboInfo) { DEBUG_FUNCTION_LINE_ERR("ButtonComboModule_GetButtonComboInfo failed to get manager for handle %08X", handle); return BUTTON_COMBO_MODULE_ERROR_INVALID_ARGUMENT; diff --git a/source/ButtonComboManager.h b/source/ButtonComboManager.h index a925b4f..ecb1591 100644 --- a/source/ButtonComboManager.h +++ b/source/ButtonComboManager.h @@ -19,7 +19,7 @@ class ButtonComboManager { static std::optional> CreateComboInfo(const ButtonComboModule_ComboOptions &options, ButtonComboModule_Error &err); - ButtonComboInfoIF *GetComboInfoForHandle(ButtonComboModule_ComboHandle handle); + ButtonComboInfoIF *GetComboInfoForHandle(ButtonComboModule_ComboHandle handle) const; void UpdateInputVPAD(VPADChan chan, const VPADStatus *buffer, uint32_t bufferSize, const VPADReadError *error); From 39c2e8d43ed5b68e18a94843aa998938dec41e59 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 1 Jan 2025 12:57:08 +0100 Subject: [PATCH 6/7] Avoid additional setControllerMask call --- source/ButtonComboManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 939a047..82e6898 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -505,7 +505,6 @@ ButtonComboModule_Error ButtonComboManager::UpdateControllerMask(const ButtonCom comboInfo->setControllerMask(controllerMask); // check if we have a conflict. - comboInfo->setControllerMask(controllerMask); comboInfo->setStatus(CheckComboStatus(*comboInfo)); outComboStatus = comboInfo->getStatus(); From d67f073124dc58600d2f3a445748f6b069f13732 Mon Sep 17 00:00:00 2001 From: Maschell Date: Wed, 1 Jan 2025 13:00:23 +0100 Subject: [PATCH 7/7] Implement support for latest libbuttoncombo by implementing the hold duration now in ms instead of frames and update the combo callback to include the controller which triggered it --- Dockerfile | 2 +- source/ButtonComboInfoDown.cpp | 10 +++++----- source/ButtonComboInfoHold.cpp | 30 +++++++++++++++++------------- source/ButtonComboInfoHold.h | 10 ++++++---- source/ButtonComboManager.cpp | 5 ++--- 5 files changed, 31 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index 883bd25..8f4059d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM ghcr.io/wiiu-env/devkitppc:20241128 -COPY --from=ghcr.io/wiiu-env/libbuttoncombo:20241226-12d1594 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libbuttoncombo:20241231-a2f949b /artifacts $DEVKITPRO COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20241012 /artifacts $DEVKITPRO COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20240424 /artifacts $DEVKITPRO diff --git a/source/ButtonComboInfoDown.cpp b/source/ButtonComboInfoDown.cpp index 046bdb2..f5826c2 100644 --- a/source/ButtonComboInfoDown.cpp +++ b/source/ButtonComboInfoDown.cpp @@ -32,8 +32,8 @@ void ButtonComboInfoDown::UpdateInput( if (buttonsPressedChanged && buttonsPressedMatchCombo && !prevButtonsIncludedCombo) { if (mCallback != nullptr) { - mCallback(getHandle(), mContext); - DEBUG_FUNCTION_LINE("Calling callback [%08X](%08X) for \"%s\" [handle: %08X], pressed down %08X", mCallback, mContext, mLabel.c_str(), getHandle().handle, mCombo); + DEBUG_FUNCTION_LINE("Calling callback [%08X](controller: %08X, context: %08X) for \"%s\" [handle: %08X], pressed down %08X", mCallback, controller, mContext, mLabel.c_str(), getHandle().handle, mCombo); + mCallback(controller, getHandle(), mContext); } else { DEBUG_FUNCTION_LINE_WARN("Callback was null for combo %08X", getHandle()); } @@ -47,7 +47,7 @@ ButtonComboModule_Error ButtonComboInfoDown::setHoldDuration(uint32_t) { } ButtonComboModule_ButtonComboInfoEx ButtonComboInfoDown::getComboInfoEx() const { - return {.type = mIsObserver ? BUTTON_COMBO_MODULE_TYPE_PRESS_DOWN_OBSERVER : BUTTON_COMBO_MODULE_TYPE_PRESS_DOWN, - .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, - .optionalHoldForXFrames = 0}; + return {.type = mIsObserver ? BUTTON_COMBO_MODULE_TYPE_PRESS_DOWN_OBSERVER : BUTTON_COMBO_MODULE_TYPE_PRESS_DOWN, + .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, + .optionalHoldForXMs = 0}; } diff --git a/source/ButtonComboInfoHold.cpp b/source/ButtonComboInfoHold.cpp index a4fd5f1..df6b6e2 100644 --- a/source/ButtonComboInfoHold.cpp +++ b/source/ButtonComboInfoHold.cpp @@ -43,7 +43,7 @@ namespace { ButtonComboInfoHold::ButtonComboInfoHold(std::string label, const ButtonComboModule_ControllerTypes controllerMask, const ButtonComboModule_Buttons combo, - const uint32_t targetDuration, + const uint32_t targetDurationInMs, const ButtonComboModule_ComboCallback callback, void *context, const bool observer) : ButtonComboInfoIF(std::move(label), @@ -52,7 +52,7 @@ ButtonComboInfoHold::ButtonComboInfoHold(std::string label, callback, context, observer), - mTargetDurationInFrames(targetDuration) { + mTargetDurationInMs(targetDurationInMs) { DEBUG_FUNCTION_LINE_INFO("Created ButtonComboInfoDown: \"%s\", combo: %08X, targetDurationInMs: %d ms, controllerMask: %08X", mLabel.c_str(), mCombo, mTargetDurationInMs, mControllerMask); } @@ -81,12 +81,16 @@ void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes co holdInformation.prevButtonCombo = latestButtonPress; - if (!(buttonsPressedChanged && prevButtonsIncludedCombo) && (holdInformation.durationInFrames > 0 || buttonsPressedChanged) && buttonsPressedMatchCombo) { - holdInformation.durationInFrames++; - if (holdInformation.durationInFrames > mTargetDurationInFrames && !holdInformation.callbackTriggered) { + if (!(buttonsPressedChanged && prevButtonsIncludedCombo) && (holdInformation.holdStartedAt > 0 || buttonsPressedChanged) && buttonsPressedMatchCombo) { + if (holdInformation.holdStartedAt == 0) { + holdInformation.holdStartedAt = OSGetTime(); + } + const auto intervalInMs = static_cast(OSTicksToMilliseconds(OSGetTime() - holdInformation.holdStartedAt)); + + if (intervalInMs > mTargetDurationInMs && !holdInformation.callbackTriggered) { if (mCallback != nullptr) { - mCallback(getHandle(), mContext); - DEBUG_FUNCTION_LINE("Calling callback [%08X](%08X) for \"%s\" [handle: %08X], hold %08X for %d ms", mCallback, mContext, mLabel.c_str(), getHandle().handle, mCombo, intervalInMs); + DEBUG_FUNCTION_LINE("Calling callback [%08X](controller: %08X context: %08X) for \"%s\" [handle: %08X], hold %08X for %d ms", mCallback, controller, mContext, mLabel.c_str(), getHandle().handle, mCombo, intervalInMs); + mCallback(controller, getHandle(), mContext); } else { DEBUG_FUNCTION_LINE_WARN("Callback was null for combo %08X", getHandle()); @@ -95,18 +99,18 @@ void ButtonComboInfoHold::UpdateInput(const ButtonComboModule_ControllerTypes co } } else { holdInformation.callbackTriggered = false; - holdInformation.durationInFrames = 0; + holdInformation.holdStartedAt = 0; } } -ButtonComboModule_Error ButtonComboInfoHold::setHoldDuration(const uint32_t holdDurationInFrames) { - mTargetDurationInFrames = holdDurationInFrames; +ButtonComboModule_Error ButtonComboInfoHold::setHoldDuration(const uint32_t holdDurationInMs) { DEBUG_FUNCTION_LINE("Setting holdDurationInMs to %d for %s [%08X]", holdDurationInMs, mLabel.c_str(), getHandle().handle); + mTargetDurationInMs = holdDurationInMs; return BUTTON_COMBO_MODULE_ERROR_SUCCESS; } ButtonComboModule_ButtonComboInfoEx ButtonComboInfoHold::getComboInfoEx() const { - return {.type = mIsObserver ? BUTTON_COMBO_MODULE_TYPE_HOLD_OBSERVER : BUTTON_COMBO_MODULE_TYPE_HOLD, - .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, - .optionalHoldForXFrames = mTargetDurationInMs}; + return {.type = mIsObserver ? BUTTON_COMBO_MODULE_TYPE_HOLD_OBSERVER : BUTTON_COMBO_MODULE_TYPE_HOLD, + .basicCombo = {.controllerMask = mControllerMask, .combo = mCombo}, + .optionalHoldForXMs = mTargetDurationInMs}; } diff --git a/source/ButtonComboInfoHold.h b/source/ButtonComboInfoHold.h index c5707f3..c262555 100644 --- a/source/ButtonComboInfoHold.h +++ b/source/ButtonComboInfoHold.h @@ -7,6 +7,7 @@ #include #include +#include #include class ButtonComboInfoHold final : public ButtonComboInfoIF { @@ -16,7 +17,7 @@ class ButtonComboInfoHold final : public ButtonComboInfoIF { ButtonComboInfoHold(std::string label, ButtonComboModule_ControllerTypes controllerMask, ButtonComboModule_Buttons combo, - uint32_t targetDuration, + uint32_t targetDurationInMs, ButtonComboModule_ComboCallback callback, void *context, bool observer); @@ -26,16 +27,17 @@ class ButtonComboInfoHold final : public ButtonComboInfoIF { private: void UpdateInput(ButtonComboModule_ControllerTypes controller, std::span pressedButtons) override; - ButtonComboModule_Error setHoldDuration(uint32_t holdDurationInFrames) override; + ButtonComboModule_Error setHoldDuration(uint32_t holdDurationInMs) override; [[nodiscard]] ButtonComboModule_ButtonComboInfoEx getComboInfoEx() const override; +private: typedef struct { - uint32_t durationInFrames; + OSTime holdStartedAt; uint32_t prevButtonCombo; bool callbackTriggered; } HoldInformation; - uint32_t mTargetDurationInFrames = {}; + uint32_t mTargetDurationInMs = {}; HoldInformation mHoldInformation[9] = {}; // one for each controller }; diff --git a/source/ButtonComboManager.cpp b/source/ButtonComboManager.cpp index 82e6898..ab96dd0 100644 --- a/source/ButtonComboManager.cpp +++ b/source/ButtonComboManager.cpp @@ -284,8 +284,7 @@ std::optional> ButtonComboManager::CreateComb observer = true; __attribute__((fallthrough)); case BUTTON_COMBO_MODULE_TYPE_HOLD: { - - if (options.buttonComboOptions.optionalHoldForXFrames == 0) { + if (options.buttonComboOptions.optionalHoldForXMs == 0) { err = BUTTON_COMBO_MODULE_ERROR_DURATION_MISSING; return std::nullopt; } @@ -293,7 +292,7 @@ std::optional> ButtonComboManager::CreateComb return std::make_shared(options.metaOptions.label, options.buttonComboOptions.basicCombo.controllerMask, options.buttonComboOptions.basicCombo.combo, - options.buttonComboOptions.optionalHoldForXFrames, + options.buttonComboOptions.optionalHoldForXMs, options.callbackOptions.callback, options.callbackOptions.context, observer);