diff --git a/source/TVOverlayManager.cpp b/source/TVOverlayManager.cpp new file mode 100644 index 0000000..fc7d64a --- /dev/null +++ b/source/TVOverlayManager.cpp @@ -0,0 +1,83 @@ +#include "TVOverlayManager.h" +#include "ButtonComboManager.h" +#include "export.h" +#include "globals.h" +#include "logger.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..6b77a01 100644 --- a/source/export.cpp +++ b/source/export.cpp @@ -1,7 +1,7 @@ +#include "export.h" #include "ButtonComboManager.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 d890c72..0635598 100644 --- a/source/function_patches.cpp +++ b/source/function_patches.cpp @@ -1,5 +1,6 @@ #include "ButtonComboInfo.h" #include "ButtonComboManager.h" +#include "TVOverlayManager.h" #include "globals.h" #include @@ -18,6 +19,9 @@ DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buf if (error) { *error = real_error; } + + updateTVStatus(chan); + return result; } @@ -37,10 +41,11 @@ struct WUT_PACKED CCRCDCCallbackData { DECL_FUNCTION(void, __VPADBASEAttachCallback, CCRCDCCallbackData *data, void *context) { real___VPADBASEAttachCallback(data, context); - if (data && data->attached) { - if (gButtonComboManager) { - const bool block = gButtonComboManager->hasActiveComboWithTVButton(); - VPADSetTVMenuInvalid(data->chan, block); + if (data) { + if (data->attached && gButtonComboManager) { + initTVStatus(data->chan, gButtonComboManager->hasActiveComboWithTVButton()); + } else { + resetTVStatus(data->chan); } } } diff --git a/source/globals.cpp b/source/globals.cpp index 0faee48..4d7dd1c 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -1,4 +1,4 @@ #include "globals.h" #include "ButtonComboManager.h" -std::unique_ptr gButtonComboManager = {}; \ No newline at end of file +std::unique_ptr gButtonComboManager = {}; diff --git a/source/globals.h b/source/globals.h index d94388d..669adb2 100644 --- a/source/globals.h +++ b/source/globals.h @@ -2,4 +2,4 @@ class ButtonComboManager; -extern std::unique_ptr gButtonComboManager; \ No newline at end of file +extern std::unique_ptr gButtonComboManager; diff --git a/source/main.cpp b/source/main.cpp index 74123f6..f41d618 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,4 +1,6 @@ #include "ButtonComboManager.h" +#include "TVOverlayManager.h" +#include "export.h" #include "function_patches.h" #include "globals.h" #include "logger.h" @@ -34,10 +36,13 @@ WUMS_INITIALIZE() { gButtonComboManager = std::make_unique(); + registerTVCombo(); + deinitLogging(); } WUMS_DEINITIALIZE() { + unregisterTVCombo(); gButtonComboManager.reset(); }