From b4742530525b3c97820af056814c6a7820cb4f32 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Sun, 16 Feb 2025 11:44:40 -0300 Subject: [PATCH 1/6] First attempt at special handling for TV button. --- source/function_patches.cpp | 28 ++++++++++++++++++++-- source/globals.cpp | 5 +++- source/globals.h | 7 +++++- source/main.cpp | 48 +++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/source/function_patches.cpp b/source/function_patches.cpp index d890c72..93d96a2 100644 --- a/source/function_patches.cpp +++ b/source/function_patches.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include @@ -18,6 +20,25 @@ DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buf if (error) { *error = real_error; } + + if (gTVPressed[chan]) { + uint64_t elapsed = OSGetSystemTime() - gTVPressed[chan]; + if (elapsed > OSMillisecondsToTicks(100) && gTVMenuBlocked[chan]) { + OSReport("TV menu unblocked\n"); + VPADSetTVMenuInvalid(chan, false); + gTVMenuBlocked[chan] = false; + } + if (elapsed > OSMillisecondsToTicks(1000) && !VPADGetTVMenuStatus(chan)) { + bool block = gButtonComboManager->hasActiveComboWithTVButton(); + OSReport("TV timeout reached, setting TV Menu block to %s\n", + block ? "blocked" : "unblocked"); + VPADSetTVMenuInvalid(chan, block); + gTVMenuBlocked[chan] = block; + gTVPressed[chan] = 0; + OSMemoryBarrier(); + } + } + return result; } @@ -37,11 +58,14 @@ struct WUT_PACKED CCRCDCCallbackData { DECL_FUNCTION(void, __VPADBASEAttachCallback, CCRCDCCallbackData *data, void *context) { real___VPADBASEAttachCallback(data, context); - if (data && data->attached) { - if (gButtonComboManager) { + if (data) { + if (data->attached && gButtonComboManager) { const bool block = gButtonComboManager->hasActiveComboWithTVButton(); VPADSetTVMenuInvalid(data->chan, block); + gTVMenuBlocked[data->chan] = block; } + gTVPressed[data->chan] = 0; + OSMemoryBarrier(); } } diff --git a/source/globals.cpp b/source/globals.cpp index 0faee48..acbcc62 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -1,4 +1,7 @@ #include "globals.h" #include "ButtonComboManager.h" -std::unique_ptr gButtonComboManager = {}; \ No newline at end of file +std::unique_ptr gButtonComboManager = {}; + +OSTime gTVPressed[2]; +bool gTVMenuBlocked[2] = {true, true}; diff --git a/source/globals.h b/source/globals.h index d94388d..ca23253 100644 --- a/source/globals.h +++ b/source/globals.h @@ -1,5 +1,10 @@ #include +#include + class ButtonComboManager; -extern std::unique_ptr gButtonComboManager; \ No newline at end of file +extern std::unique_ptr gButtonComboManager; + +extern OSTime gTVPressed[2]; +extern bool gTVMenuBlocked[2]; diff --git a/source/main.cpp b/source/main.cpp index 74123f6..f00cc7c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -4,9 +4,14 @@ #include "logger.h" #include "version.h" +#include +#include +#include + #include #include +#include #include @@ -16,6 +21,14 @@ WUMS_DEPENDS_ON(homebrew_functionpatcher); #define MODULE_VERSION "v0.1.0" +extern ButtonComboModule_Error ButtonComboModule_AddButtonCombo(const ButtonComboModule_ComboOptions *options, + ButtonComboModule_ComboHandle *outHandle, + ButtonComboModule_ComboStatus *outStatus); + +extern ButtonComboModule_Error ButtonComboModule_RemoveButtonCombo(const ButtonComboModule_ComboHandle handle); + +static ButtonComboModule_ComboHandle sTVButtonHandle; + WUMS_INITIALIZE() { initLogging(); @@ -34,10 +47,45 @@ WUMS_INITIALIZE() { gButtonComboManager = std::make_unique(); + // register observer combo on the TV button + { + ButtonComboModule_ComboOptions opt = {}; + opt.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION; + opt.metaOptions.label = "TV remote overlay combo"; + opt.callbackOptions.callback = [](ButtonComboModule_ControllerTypes triggeredBy, + ButtonComboModule_ComboHandle, + void *) + { + VPADChan chan; + switch (triggeredBy) { + case BUTTON_COMBO_MODULE_CONTROLLER_VPAD_0: + chan = VPAD_CHAN_0; + break; + case BUTTON_COMBO_MODULE_CONTROLLER_VPAD_1: + chan = VPAD_CHAN_1; + break; + default: + return; + } + OSReport("TV pressed\n"); + gTVPressed[chan] = OSGetSystemTime(); + OSMemoryBarrier(); + }; + opt.callbackOptions.context = {}; + opt.buttonComboOptions.type = BUTTON_COMBO_MODULE_COMBO_TYPE_PRESS_DOWN_OBSERVER; + opt.buttonComboOptions.basicCombo.combo = BCMPAD_BUTTON_TV; + opt.buttonComboOptions.basicCombo.controllerMask = BUTTON_COMBO_MODULE_CONTROLLER_VPAD; + opt.buttonComboOptions.optionalHoldForXMs = 0; + if (ButtonComboModule_AddButtonCombo(&opt, &sTVButtonHandle, nullptr) != BUTTON_COMBO_MODULE_ERROR_SUCCESS) { + OSReport("*** FAILED TO SET UP COMBO!\n"); + } + } + deinitLogging(); } WUMS_DEINITIALIZE() { + ButtonComboModule_RemoveButtonCombo(sTVButtonHandle); gButtonComboManager.reset(); } From 9854fa9e2fc7cea53ba8715b50a8e276e1e785f2 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Wed, 19 Feb 2025 21:19:29 -0300 Subject: [PATCH 2/6] Refactored implementation. --- source/TVOverlayManager.cpp | 83 +++++++++++++++++++++++++++++++++++++ source/TVOverlayManager.h | 13 ++++++ source/export.cpp | 4 +- source/export.h | 9 ++++ source/function_patches.cpp | 29 +++---------- source/globals.cpp | 2 +- source/globals.h | 5 --- source/main.cpp | 45 ++------------------ 8 files changed, 117 insertions(+), 73 deletions(-) create mode 100644 source/TVOverlayManager.cpp create mode 100644 source/TVOverlayManager.h create mode 100644 source/export.h diff --git a/source/TVOverlayManager.cpp b/source/TVOverlayManager.cpp new file mode 100644 index 0000000..b78aaf1 --- /dev/null +++ b/source/TVOverlayManager.cpp @@ -0,0 +1,83 @@ +#include "ButtonComboManager.h" +#include "globals.h" +#include "export.h" +#include "logger.h" +#include "TVOverlayManager.h" + +#include +#include +#include + +static ButtonComboModule_ComboHandle sTVButtonHandle; +static OSTime sTVPressed[2]; // when the button was last pressed, or zero if timeout expired +static bool sTVMenuBlocked[2]; + +static void TVComboCallback(ButtonComboModule_ControllerTypes triggeredBy, + ButtonComboModule_ComboHandle, + void *) { + VPADChan chan; + switch (triggeredBy) { + case BUTTON_COMBO_MODULE_CONTROLLER_VPAD_0: + chan = VPAD_CHAN_0; + break; + case BUTTON_COMBO_MODULE_CONTROLLER_VPAD_1: + chan = VPAD_CHAN_1; + break; + default: + return; + } + // OSReport("TV pressed\n"); + sTVPressed[chan] = OSGetSystemTime(); + OSMemoryBarrier(); +} + +void registerTVCombo() { + ButtonComboModule_ComboOptions opt = {}; + opt.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION; + opt.metaOptions.label = "TV remote overlay combo"; + opt.callbackOptions.callback = TVComboCallback; + opt.callbackOptions.context = {}; + opt.buttonComboOptions.type = BUTTON_COMBO_MODULE_COMBO_TYPE_PRESS_DOWN_OBSERVER; + opt.buttonComboOptions.basicCombo.combo = BCMPAD_BUTTON_TV; + opt.buttonComboOptions.basicCombo.controllerMask = BUTTON_COMBO_MODULE_CONTROLLER_VPAD; + opt.buttonComboOptions.optionalHoldForXMs = 0; + if (ButtonComboModule_AddButtonCombo(&opt, &sTVButtonHandle, nullptr) != BUTTON_COMBO_MODULE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE("FAILED TO SET UP TV COMBO!"); + } +} + +void unregisterTVCombo() { + ButtonComboModule_RemoveButtonCombo(sTVButtonHandle); +} + +void initTVStatus(VPADChan channel, bool block) { + VPADSetTVMenuInvalid(channel, block); + sTVMenuBlocked[channel] = block; + + sTVPressed[channel] = 0; + OSMemoryBarrier(); +} + +void resetTVStatus(VPADChan channel) { + sTVPressed[channel] = 0; + OSMemoryBarrier(); +} + +void updateTVStatus(VPADChan channel) { + if (sTVPressed[channel]) { + uint64_t elapsed = OSGetSystemTime() - sTVPressed[channel]; + if (elapsed > OSMillisecondsToTicks(100) && sTVMenuBlocked[channel]) { + // OSReport("TV menu unblocked\n"); + VPADSetTVMenuInvalid(channel, false); + sTVMenuBlocked[channel] = false; + } + if (elapsed > OSMillisecondsToTicks(1000) && !VPADGetTVMenuStatus(channel)) { + bool block = gButtonComboManager->hasActiveComboWithTVButton(); + // OSReport("TV timeout reached, setting TV Menu block to %s\n", + // block ? "blocked" : "unblocked"); + VPADSetTVMenuInvalid(channel, block); + sTVMenuBlocked[channel] = block; + sTVPressed[channel] = 0; + } + } +} diff --git a/source/TVOverlayManager.h b/source/TVOverlayManager.h new file mode 100644 index 0000000..dc3b5b8 --- /dev/null +++ b/source/TVOverlayManager.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +void registerTVCombo(); + +void unregisterTVCombo(); + +void initTVStatus(VPADChan channel, bool block); + +void resetTVStatus(VPADChan channel); + +void updateTVStatus(VPADChan channel); diff --git a/source/export.cpp b/source/export.cpp index 24c1e20..c2378e3 100644 --- a/source/export.cpp +++ b/source/export.cpp @@ -1,7 +1,7 @@ #include "ButtonComboManager.h" +#include "export.h" #include "globals.h" -#include #include #include @@ -227,4 +227,4 @@ WUMS_EXPORT_FUNCTION(ButtonComboModule_GetButtonComboCallback); WUMS_EXPORT_FUNCTION(ButtonComboModule_GetButtonComboInfoEx); WUMS_EXPORT_FUNCTION(ButtonComboModule_CheckComboAvailable); WUMS_EXPORT_FUNCTION(ButtonComboModule_DetectButtonCombo_Blocking); -WUMS_EXPORT_FUNCTION(ButtonComboModule_GetVersion); \ No newline at end of file +WUMS_EXPORT_FUNCTION(ButtonComboModule_GetVersion); diff --git a/source/export.h b/source/export.h new file mode 100644 index 0000000..23117c4 --- /dev/null +++ b/source/export.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +extern ButtonComboModule_Error ButtonComboModule_AddButtonCombo(const ButtonComboModule_ComboOptions *options, + ButtonComboModule_ComboHandle *outHandle, + ButtonComboModule_ComboStatus *outStatus); + +extern ButtonComboModule_Error ButtonComboModule_RemoveButtonCombo(const ButtonComboModule_ComboHandle handle); diff --git a/source/function_patches.cpp b/source/function_patches.cpp index 93d96a2..1b72dee 100644 --- a/source/function_patches.cpp +++ b/source/function_patches.cpp @@ -1,12 +1,11 @@ #include "ButtonComboInfo.h" #include "ButtonComboManager.h" #include "globals.h" +#include "TVOverlayManager.h" #include #include -#include -#include #include #include @@ -21,23 +20,7 @@ DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buf *error = real_error; } - if (gTVPressed[chan]) { - uint64_t elapsed = OSGetSystemTime() - gTVPressed[chan]; - if (elapsed > OSMillisecondsToTicks(100) && gTVMenuBlocked[chan]) { - OSReport("TV menu unblocked\n"); - VPADSetTVMenuInvalid(chan, false); - gTVMenuBlocked[chan] = false; - } - if (elapsed > OSMillisecondsToTicks(1000) && !VPADGetTVMenuStatus(chan)) { - bool block = gButtonComboManager->hasActiveComboWithTVButton(); - OSReport("TV timeout reached, setting TV Menu block to %s\n", - block ? "blocked" : "unblocked"); - VPADSetTVMenuInvalid(chan, block); - gTVMenuBlocked[chan] = block; - gTVPressed[chan] = 0; - OSMemoryBarrier(); - } - } + updateTVStatus(chan); return result; } @@ -60,12 +43,10 @@ DECL_FUNCTION(void, __VPADBASEAttachCallback, CCRCDCCallbackData *data, void *co if (data) { if (data->attached && gButtonComboManager) { - const bool block = gButtonComboManager->hasActiveComboWithTVButton(); - VPADSetTVMenuInvalid(data->chan, block); - gTVMenuBlocked[data->chan] = block; + initTVStatus(data->chan, gButtonComboManager->hasActiveComboWithTVButton()); + } else { + resetTVStatus(data->chan); } - gTVPressed[data->chan] = 0; - OSMemoryBarrier(); } } diff --git a/source/globals.cpp b/source/globals.cpp index acbcc62..30b91a2 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -4,4 +4,4 @@ std::unique_ptr gButtonComboManager = {}; OSTime gTVPressed[2]; -bool gTVMenuBlocked[2] = {true, true}; +bool gTVMenuBlocked[2]; diff --git a/source/globals.h b/source/globals.h index ca23253..669adb2 100644 --- a/source/globals.h +++ b/source/globals.h @@ -1,10 +1,5 @@ #include -#include - class ButtonComboManager; extern std::unique_ptr gButtonComboManager; - -extern OSTime gTVPressed[2]; -extern bool gTVMenuBlocked[2]; diff --git a/source/main.cpp b/source/main.cpp index f00cc7c..f696c6c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,7 +1,9 @@ #include "ButtonComboManager.h" #include "function_patches.h" +#include "export.h" #include "globals.h" #include "logger.h" +#include "TVOverlayManager.h" #include "version.h" #include @@ -21,13 +23,6 @@ WUMS_DEPENDS_ON(homebrew_functionpatcher); #define MODULE_VERSION "v0.1.0" -extern ButtonComboModule_Error ButtonComboModule_AddButtonCombo(const ButtonComboModule_ComboOptions *options, - ButtonComboModule_ComboHandle *outHandle, - ButtonComboModule_ComboStatus *outStatus); - -extern ButtonComboModule_Error ButtonComboModule_RemoveButtonCombo(const ButtonComboModule_ComboHandle handle); - -static ButtonComboModule_ComboHandle sTVButtonHandle; WUMS_INITIALIZE() { initLogging(); @@ -47,45 +42,13 @@ WUMS_INITIALIZE() { gButtonComboManager = std::make_unique(); - // register observer combo on the TV button - { - ButtonComboModule_ComboOptions opt = {}; - opt.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION; - opt.metaOptions.label = "TV remote overlay combo"; - opt.callbackOptions.callback = [](ButtonComboModule_ControllerTypes triggeredBy, - ButtonComboModule_ComboHandle, - void *) - { - VPADChan chan; - switch (triggeredBy) { - case BUTTON_COMBO_MODULE_CONTROLLER_VPAD_0: - chan = VPAD_CHAN_0; - break; - case BUTTON_COMBO_MODULE_CONTROLLER_VPAD_1: - chan = VPAD_CHAN_1; - break; - default: - return; - } - OSReport("TV pressed\n"); - gTVPressed[chan] = OSGetSystemTime(); - OSMemoryBarrier(); - }; - opt.callbackOptions.context = {}; - opt.buttonComboOptions.type = BUTTON_COMBO_MODULE_COMBO_TYPE_PRESS_DOWN_OBSERVER; - opt.buttonComboOptions.basicCombo.combo = BCMPAD_BUTTON_TV; - opt.buttonComboOptions.basicCombo.controllerMask = BUTTON_COMBO_MODULE_CONTROLLER_VPAD; - opt.buttonComboOptions.optionalHoldForXMs = 0; - if (ButtonComboModule_AddButtonCombo(&opt, &sTVButtonHandle, nullptr) != BUTTON_COMBO_MODULE_ERROR_SUCCESS) { - OSReport("*** FAILED TO SET UP COMBO!\n"); - } - } + registerTVCombo(); deinitLogging(); } WUMS_DEINITIALIZE() { - ButtonComboModule_RemoveButtonCombo(sTVButtonHandle); + unregisterTVCombo(); gButtonComboManager.reset(); } From 65a1173e094c4533117c1d62d25a352fdbbaba28 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Wed, 19 Feb 2025 21:31:59 -0300 Subject: [PATCH 3/6] Removed unused globals. --- source/globals.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/globals.cpp b/source/globals.cpp index 30b91a2..4d7dd1c 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -2,6 +2,3 @@ #include "ButtonComboManager.h" std::unique_ptr gButtonComboManager = {}; - -OSTime gTVPressed[2]; -bool gTVMenuBlocked[2]; From 937b451c8ba0b96864c6115ec76de89ebb4e9514 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Wed, 19 Feb 2025 21:33:37 -0300 Subject: [PATCH 4/6] Removed unused includes. --- source/main.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/main.cpp b/source/main.cpp index f696c6c..37129e5 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -6,14 +6,9 @@ #include "TVOverlayManager.h" #include "version.h" -#include -#include -#include - #include #include -#include #include @@ -23,7 +18,6 @@ WUMS_DEPENDS_ON(homebrew_functionpatcher); #define MODULE_VERSION "v0.1.0" - WUMS_INITIALIZE() { initLogging(); From dd04d6086453072048838d6fd95fc4347ebe03fc Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Thu, 20 Feb 2025 14:14:36 -0300 Subject: [PATCH 5/6] Reformatted for clang-format. --- source/TVOverlayManager.cpp | 30 +++++++++++++++--------------- source/function_patches.cpp | 2 +- source/main.cpp | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source/TVOverlayManager.cpp b/source/TVOverlayManager.cpp index b78aaf1..fc7d64a 100644 --- a/source/TVOverlayManager.cpp +++ b/source/TVOverlayManager.cpp @@ -1,8 +1,8 @@ +#include "TVOverlayManager.h" #include "ButtonComboManager.h" -#include "globals.h" #include "export.h" +#include "globals.h" #include "logger.h" -#include "TVOverlayManager.h" #include #include @@ -32,18 +32,18 @@ static void TVComboCallback(ButtonComboModule_ControllerTypes triggeredBy, } void registerTVCombo() { - ButtonComboModule_ComboOptions opt = {}; - opt.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION; - opt.metaOptions.label = "TV remote overlay combo"; - opt.callbackOptions.callback = TVComboCallback; - opt.callbackOptions.context = {}; - opt.buttonComboOptions.type = BUTTON_COMBO_MODULE_COMBO_TYPE_PRESS_DOWN_OBSERVER; - opt.buttonComboOptions.basicCombo.combo = BCMPAD_BUTTON_TV; - opt.buttonComboOptions.basicCombo.controllerMask = BUTTON_COMBO_MODULE_CONTROLLER_VPAD; - opt.buttonComboOptions.optionalHoldForXMs = 0; - if (ButtonComboModule_AddButtonCombo(&opt, &sTVButtonHandle, nullptr) != BUTTON_COMBO_MODULE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE("FAILED TO SET UP TV COMBO!"); - } + ButtonComboModule_ComboOptions opt = {}; + opt.version = BUTTON_COMBO_MODULE_COMBO_OPTIONS_VERSION; + opt.metaOptions.label = "TV remote overlay combo"; + opt.callbackOptions.callback = TVComboCallback; + opt.callbackOptions.context = {}; + opt.buttonComboOptions.type = BUTTON_COMBO_MODULE_COMBO_TYPE_PRESS_DOWN_OBSERVER; + opt.buttonComboOptions.basicCombo.combo = BCMPAD_BUTTON_TV; + opt.buttonComboOptions.basicCombo.controllerMask = BUTTON_COMBO_MODULE_CONTROLLER_VPAD; + opt.buttonComboOptions.optionalHoldForXMs = 0; + if (ButtonComboModule_AddButtonCombo(&opt, &sTVButtonHandle, nullptr) != BUTTON_COMBO_MODULE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE("FAILED TO SET UP TV COMBO!"); + } } void unregisterTVCombo() { @@ -77,7 +77,7 @@ void updateTVStatus(VPADChan channel) { // block ? "blocked" : "unblocked"); VPADSetTVMenuInvalid(channel, block); sTVMenuBlocked[channel] = block; - sTVPressed[channel] = 0; + sTVPressed[channel] = 0; } } } diff --git a/source/function_patches.cpp b/source/function_patches.cpp index 1b72dee..0635598 100644 --- a/source/function_patches.cpp +++ b/source/function_patches.cpp @@ -1,7 +1,7 @@ #include "ButtonComboInfo.h" #include "ButtonComboManager.h" -#include "globals.h" #include "TVOverlayManager.h" +#include "globals.h" #include #include diff --git a/source/main.cpp b/source/main.cpp index 37129e5..f41d618 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,9 +1,9 @@ #include "ButtonComboManager.h" -#include "function_patches.h" +#include "TVOverlayManager.h" #include "export.h" +#include "function_patches.h" #include "globals.h" #include "logger.h" -#include "TVOverlayManager.h" #include "version.h" #include From 5296d78fe0d88c287016002abf0ede42f846d4a5 Mon Sep 17 00:00:00 2001 From: "Daniel K. O. (dkosmari)" Date: Wed, 5 Mar 2025 03:05:37 -0300 Subject: [PATCH 6/6] Reordered includes. --- source/export.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/export.cpp b/source/export.cpp index c2378e3..6b77a01 100644 --- a/source/export.cpp +++ b/source/export.cpp @@ -1,5 +1,5 @@ -#include "ButtonComboManager.h" #include "export.h" +#include "ButtonComboManager.h" #include "globals.h" #include