diff --git a/Dockerfile b/Dockerfile index 41a4029..bc48449 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ -FROM ghcr.io/wiiu-env/devkitppc:20230326 +FROM ghcr.io/wiiu-env/devkitppc:20260225 -COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20230316 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20260418 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libnotifications:20260331 /artifacts $DEVKITPRO WORKDIR project diff --git a/Makefile b/Makefile index d67c135..a3016ac 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ CXXFLAGS += -DDEBUG -DVERBOSE_DEBUG -g CFLAGS += -DDEBUG -DVERBOSE_DEBUG -g endif -LIBS := -lwups -lwut +LIBS := -lwups -lwut -lnotifications #------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level diff --git a/src/main.cpp b/src/main.cpp index c8e209c..1c9174f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,13 +1,21 @@ #include "main.h" -#include "utils/WUPSConfigItemButtonCombo.h" + +#include "utils/StringTools.h" #include "utils/logger.h" + +#include #include +#include #include #include #include +#include #include +#include -WUPS_PLUGIN_NAME("Padcon"); +#define PLUGIN_NAME "Padcon" + +WUPS_PLUGIN_NAME(PLUGIN_NAME); WUPS_PLUGIN_DESCRIPTION("Turns the gamepad screen on/off or shuts the GamePad off"); WUPS_PLUGIN_VERSION(VERSION_FULL); WUPS_PLUGIN_AUTHOR("WiiDatabase.de"); @@ -15,26 +23,99 @@ WUPS_PLUGIN_LICENSE("GPLv3"); WUPS_USE_STORAGE("padcon_plugin"); -#define BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING "buttonComboDisableScreen" -#define BUTTON_COMBO_SHUT_OFF_CONFIG_STRING "buttonComboShutOff" -#define ENABLED_CONFIG_STRING "enabled" +#define BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING_DEPRECATED "buttonComboDisableScreen" +#define BUTTON_COMBO_SHUT_OFF_CONFIG_STRING_DEPRECATED "buttonComboShutOff" + +#define BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING "buttonComboDisableScreenV2" +#define BUTTON_COMBO_SHUT_OFF_CONFIG_STRING "buttonComboShutOffV2" +#define ENABLED_CONFIG_STRING "enabled" + +constexpr bool CONFIG_ENABLED_DEFAULT = true; +constexpr WUPSButtonCombo_Buttons CONFIG_BUTTON_COMBO_DISABLE_SCREEN_DEFAULT = (WUPS_BUTTON_COMBO_BUTTON_ZL | WUPS_BUTTON_COMBO_BUTTON_ZR | WUPS_BUTTON_COMBO_BUTTON_L | WUPS_BUTTON_COMBO_BUTTON_R | WUPS_BUTTON_COMBO_BUTTON_PLUS); +constexpr WUPSButtonCombo_Buttons CONFIG_BUTTON_COMBO_SHUT_OFF_DEFAULT = (WUPS_BUTTON_COMBO_BUTTON_ZL | WUPS_BUTTON_COMBO_BUTTON_ZR | WUPS_BUTTON_COMBO_BUTTON_L | WUPS_BUTTON_COMBO_BUTTON_R | WUPS_BUTTON_COMBO_BUTTON_MINUS); + +static bool sEnabled = CONFIG_ENABLED_DEFAULT; +static WUPSButtonCombo_Buttons sButtonComboDisableScreen = CONFIG_BUTTON_COMBO_DISABLE_SCREEN_DEFAULT; +static WUPSButtonCombo_Buttons sButtonComboShutOff = CONFIG_BUTTON_COMBO_SHUT_OFF_DEFAULT; + +static std::forward_list sButtonComboInstances; +static WUPSButtonCombo_ComboHandle sDisableScreenHandle(nullptr); +static WUPSButtonCombo_ComboHandle sShutOffHandle(nullptr); +static bool sNotificationModuleInitDone = false; -uint8_t cooldown = 0; -bool enabled = true; -uint32_t buttonComboDisableScreen = (VPAD_BUTTON_ZL | VPAD_BUTTON_ZR | VPAD_BUTTON_L | - VPAD_BUTTON_R | VPAD_BUTTON_PLUS); -uint32_t buttonComboShutOff = (VPAD_BUTTON_ZL | VPAD_BUTTON_ZR | VPAD_BUTTON_L | - VPAD_BUTTON_R | VPAD_BUTTON_MINUS); +uint32_t migrateButtonCombo(const uint32_t buttons) { + uint32_t conv_buttons = 0; + + if (buttons & VPAD_BUTTON_A) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_A; + } + if (buttons & VPAD_BUTTON_B) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_B; + } + if (buttons & VPAD_BUTTON_X) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_X; + } + if (buttons & VPAD_BUTTON_Y) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_Y; + } + + if (buttons & VPAD_BUTTON_LEFT) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_LEFT; + } + if (buttons & VPAD_BUTTON_RIGHT) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_RIGHT; + } + if (buttons & VPAD_BUTTON_UP) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_UP; + } + if (buttons & VPAD_BUTTON_DOWN) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_DOWN; + } + + if (buttons & VPAD_BUTTON_ZL) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_ZL; + } + if (buttons & VPAD_BUTTON_ZR) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_ZR; + } + + if (buttons & VPAD_BUTTON_L) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_L; + } + if (buttons & VPAD_BUTTON_R) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_R; + } + + if (buttons & VPAD_BUTTON_PLUS) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_PLUS; + } + if (buttons & VPAD_BUTTON_MINUS) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_MINUS; + } + + if (buttons & VPAD_BUTTON_STICK_R) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_STICK_R; + } + if (buttons & VPAD_BUTTON_STICK_L) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_STICK_L; + } + + if (buttons & VPAD_BUTTON_TV) { + conv_buttons |= WUPS_BUTTON_COMBO_BUTTON_TV; + } + + return conv_buttons; +} void blockTvButton() { - if (!enabled) { + if (!sEnabled) { DEBUG_FUNCTION_LINE("Unblock TV Menu"); VPADSetTVMenuInvalid(VPAD_CHAN_0, false); return; } - if (buttonComboDisableScreen & VPAD_BUTTON_TV || buttonComboShutOff & VPAD_BUTTON_TV) { + if (sButtonComboDisableScreen & WUPS_BUTTON_COMBO_BUTTON_TV || sButtonComboShutOff & WUPS_BUTTON_COMBO_BUTTON_TV) { DEBUG_FUNCTION_LINE("Block TV Menu"); VPADSetTVMenuInvalid(VPAD_CHAN_0, true); } else { @@ -43,169 +124,202 @@ void blockTvButton() { } } -INITIALIZE_PLUGIN() { - initLogging(); - DEBUG_FUNCTION_LINE("init plugin"); - - // Open storage to read values - WUPSStorageError storageRes = WUPS_OpenStorage(); - if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to open storage %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); - } else { - // Try to get value from storage - if ((storageRes = WUPS_GetBool(nullptr, ENABLED_CONFIG_STRING, &enabled)) == WUPS_STORAGE_ERROR_NOT_FOUND) { - // Add the value to the storage if it's missing. - if (WUPS_StoreBool(nullptr, ENABLED_CONFIG_STRING, enabled) != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to store value"); - } - } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to get value %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); +void buttonComboItemChanged(ConfigItemButtonCombo *item, uint32_t newValue) { + if (item && item->identifier) { + DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->identifier, newValue); + if (std::string_view(item->identifier) == BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING) { + sButtonComboDisableScreen = static_cast(newValue); + WUPSStorageAPI::Store(item->identifier, sButtonComboDisableScreen); + } else if (std::string_view(item->identifier) == BUTTON_COMBO_SHUT_OFF_CONFIG_STRING) { + sButtonComboShutOff = static_cast(newValue); + WUPSStorageAPI::Store(item->identifier, sButtonComboShutOff); } + } +} - // Try to get value from storage - if ((storageRes = WUPS_GetInt(nullptr, BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING, reinterpret_cast(&buttonComboDisableScreen))) == WUPS_STORAGE_ERROR_NOT_FOUND) { - // Add the value to the storage if it's missing. - if (WUPS_StoreInt(nullptr, BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING, (int32_t) buttonComboDisableScreen) != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to store value"); - } - } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to get value %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); +void boolItemCallback(ConfigItemBoolean *item, bool newValue) { + if (item && item->identifier) { + DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->identifier, newValue); + if (std::string_view(item->identifier) == ENABLED_CONFIG_STRING) { + sEnabled = newValue; + WUPSStorageAPI::Store(item->identifier, sEnabled); } + } +} - // Try to get value from storage - if ((storageRes = WUPS_GetInt(nullptr, BUTTON_COMBO_SHUT_OFF_CONFIG_STRING, reinterpret_cast(&buttonComboShutOff))) == WUPS_STORAGE_ERROR_NOT_FOUND) { - // Add the value to the storage if it's missing. - if (WUPS_StoreInt(nullptr, BUTTON_COMBO_SHUT_OFF_CONFIG_STRING, (int32_t) buttonComboShutOff) != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to store value"); - } - } else if (storageRes != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to get value %s (%d)", WUPS_GetStorageStatusStr(storageRes), storageRes); - } +WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle) { + WUPSConfigCategory root = WUPSConfigCategory(rootHandle); - // Close storage - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to close storage"); - } + try { + auto settingsCat = WUPSConfigCategory::Create("Settings"); + + settingsCat.add(WUPSConfigItemBoolean::Create(ENABLED_CONFIG_STRING, "Enable plugin", + CONFIG_ENABLED_DEFAULT, + sEnabled, + boolItemCallback)); + + settingsCat.add(WUPSConfigItemButtonCombo::Create(BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING, "Disable screen", + CONFIG_BUTTON_COMBO_DISABLE_SCREEN_DEFAULT, + sDisableScreenHandle, + buttonComboItemChanged)); + + settingsCat.add(WUPSConfigItemButtonCombo::Create(BUTTON_COMBO_SHUT_OFF_CONFIG_STRING, "Shut off", + CONFIG_BUTTON_COMBO_SHUT_OFF_DEFAULT, + sShutOffHandle, + buttonComboItemChanged)); + + root.add(std::move(settingsCat)); + } catch (std::exception &e) { + DEBUG_FUNCTION_LINE_ERR("Creating config menu failed: %s", e.what()); + return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; } - blockTvButton(); + return WUPSCONFIG_API_CALLBACK_RESULT_SUCCESS; +} - deinitLogging(); +void ConfigMenuClosedCallback() { + WUPSStorageAPI::SaveStorage(); } -void buttonComboItemChanged(ConfigItemButtonCombo *item, uint32_t newValue) { - if (item && item->configId) { - DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->configId, newValue); - if (std::string_view(item->configId) == BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING) { - buttonComboDisableScreen = newValue; - WUPS_StoreInt(nullptr, item->configId, (int32_t) buttonComboDisableScreen); - } else if (std::string_view(item->configId) == BUTTON_COMBO_SHUT_OFF_CONFIG_STRING) { - buttonComboShutOff = newValue; - WUPS_StoreInt(nullptr, item->configId, (int32_t) buttonComboShutOff); +WUPSButtonCombo_ComboHandle RegisterButtonCombo(const std::string_view label, const WUPSButtonCombo_Buttons buttonCombo, const WUPSButtonCombo_ComboCallback callback) { + const auto buttonComboLabel = string_format(PLUGIN_NAME ": %s", label.data()); + WUPSButtonCombo_ComboStatus status = WUPS_BUTTON_COMBO_COMBO_STATUS_INVALID_STATUS; + WUPSButtonCombo_Error err = WUPS_BUTTON_COMBO_ERROR_UNKNOWN_ERROR; + auto res = WUPSButtonComboAPI::CreateComboPressDown(buttonComboLabel, + buttonCombo, + callback, + nullptr, + status, + err); + if (!res || err != WUPS_BUTTON_COMBO_ERROR_SUCCESS) { + const std::string errorMsg = string_format(PLUGIN_NAME ": Failed to register button combo \"%s\"", label.data()); + DEBUG_FUNCTION_LINE_ERR("%s", errorMsg.c_str()); + if (sNotificationModuleInitDone) { + NotificationModule_AddErrorNotification(errorMsg.c_str()); + } + } else { + if (status == WUPS_BUTTON_COMBO_COMBO_STATUS_CONFLICT) { + const auto conflictMsg = string_format(PLUGIN_NAME ": \"%s\"-combo was disabled due to a conflict. Please assign a different combo", label.data()); + DEBUG_FUNCTION_LINE_INFO("%s", conflictMsg.c_str()); + if (sNotificationModuleInitDone) { + NotificationModule_AddInfoNotification(conflictMsg.c_str()); + } + } else if (status != WUPS_BUTTON_COMBO_COMBO_STATUS_VALID) { + const auto conflictMsg = string_format(PLUGIN_NAME ": Unknown error happened while registering button combo \"%s\"", label.data()); + DEBUG_FUNCTION_LINE_INFO("%s", conflictMsg.c_str()); + if (sNotificationModuleInitDone) { + NotificationModule_AddInfoNotification(conflictMsg.c_str()); + } } + const auto handle = res->getHandle(); + sButtonComboInstances.emplace_front(std::move(*res)); + return handle; } + return WUPSButtonCombo_ComboHandle(nullptr); } -void boolItemCallback(ConfigItemBoolean *item, bool newValue) { - if (item && item->configId) { - DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->configId, newValue); - if (std::string_view(item->configId) == ENABLED_CONFIG_STRING) { - enabled = newValue; - WUPS_StoreBool(nullptr, item->configId, enabled); - } +void ScreenOffCallback(const WUPSButtonCombo_ControllerTypes triggeredBy, WUPSButtonCombo_ComboHandle, void *) { + if (!sEnabled) { + return; } -} + VPADLcdMode lcdMode; + VPADGetLcdMode(VPAD_CHAN_0, &lcdMode); -WUPS_CONFIG_CLOSED() { - // Save all changes - if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to close storage"); + if (lcdMode == VPAD_LCD_ON) { + DEBUG_FUNCTION_LINE_INFO("Turning off GamePad screen"); + VPADSetLcdMode(VPAD_CHAN_0, VPAD_LCD_OFF); + } else { + DEBUG_FUNCTION_LINE_INFO("Turning on GamePad screen"); + VPADSetLcdMode(VPAD_CHAN_0, VPAD_LCD_ON); } - blockTvButton(); } -ON_APPLICATION_START() { - initLogging(); -} +void ShutOffCallback(const WUPSButtonCombo_ControllerTypes, WUPSButtonCombo_ComboHandle, void *) { + if (!sEnabled) { + return; + } + VPADLcdMode lcdMode; + VPADGetLcdMode(VPAD_CHAN_0, &lcdMode); -ON_APPLICATION_ENDS() { - deinitLogging(); -} + int32_t ret = 0; -WUPS_GET_CONFIG() { - // We open the storage, so we can persist the configuration the user did. - if (WUPS_OpenStorage() != WUPS_STORAGE_ERROR_SUCCESS) { - DEBUG_FUNCTION_LINE_ERR("Failed to open storage"); - return 0; + if (lcdMode == VPAD_LCD_OFF) { + DEBUG_FUNCTION_LINE_INFO("Turning on GamePad screen"); + ret = VPADSetLcdMode(VPAD_CHAN_0, VPAD_LCD_ON); } - WUPSConfigHandle config; - WUPSConfig_CreateHandled(&config, "Padcon"); - - WUPSConfigCategoryHandle cat; - WUPSConfig_AddCategoryByNameHandled(config, "Settings", &cat); + if (ret == 0) { + DEBUG_FUNCTION_LINE_INFO("Shutting off GamePad"); + CCRSysDRCShutdown(); + } +} - WUPSConfigItemBoolean_AddToCategoryHandled( - config, cat, ENABLED_CONFIG_STRING, "Enable plugin", enabled, - &boolItemCallback); +void migrateStorage() { + uint32_t oldButtonCombo = 0; + if (WUPSStorageAPI::Get(BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING_DEPRECATED, oldButtonCombo) == WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_INFO("Found deprecated config in storage. Storage will be migrated"); + sButtonComboDisableScreen = static_cast(migrateButtonCombo(oldButtonCombo)); + if (WUPSStorageAPI::DeleteItem(BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING_DEPRECATED) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_WARN("Failed to delete deprecated value: \"%s\" from storage", BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING_DEPRECATED); + } + } + if (WUPSStorageAPI::Get(BUTTON_COMBO_SHUT_OFF_CONFIG_STRING_DEPRECATED, oldButtonCombo) == WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_INFO("Found deprecated config in storage. Storage will be migrated"); + sButtonComboShutOff = static_cast(migrateButtonCombo(oldButtonCombo)); + if (WUPSStorageAPI::DeleteItem(BUTTON_COMBO_SHUT_OFF_CONFIG_STRING_DEPRECATED) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_WARN("Failed to delete deprecated value: \"%s\" from storage", BUTTON_COMBO_SHUT_OFF_CONFIG_STRING_DEPRECATED); + } + } +} - WUPSConfigItemButtonCombo_AddToCategoryHandled(config, cat, BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING, "Disable screen", buttonComboDisableScreen, &buttonComboItemChanged); +INITIALIZE_PLUGIN() { + initLogging(); - WUPSConfigItemButtonCombo_AddToCategoryHandled(config, cat, BUTTON_COMBO_SHUT_OFF_CONFIG_STRING, "Shut off", buttonComboShutOff, &buttonComboItemChanged); + if (NotificationModule_InitLibrary() == NOTIFICATION_MODULE_RESULT_SUCCESS) { + sNotificationModuleInitDone = true; + } else { + sNotificationModuleInitDone = false; + DEBUG_FUNCTION_LINE_ERR("Failed to init notification lib"); + } - return config; -} + WUPSConfigAPIOptionsV1 configOptions = {.name = PLUGIN_NAME}; + if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("Failed to init config api"); + } -DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, - uint32_t buffer_size, VPADReadError *error) { - int32_t result = real_VPADRead(chan, buffer, buffer_size, error); + sButtonComboDisableScreen = CONFIG_BUTTON_COMBO_DISABLE_SCREEN_DEFAULT; // migrateStorage might override this + sButtonComboShutOff = CONFIG_BUTTON_COMBO_SHUT_OFF_DEFAULT; // migrateStorage might override this + // migrate old button combos + migrateStorage(); - if (!enabled) { - return result; + WUPSStorageError storageRes; + if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(ENABLED_CONFIG_STRING, sEnabled, CONFIG_ENABLED_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("GetOrStoreDefault failed: %s (%d)", WUPSStorageAPI_GetStatusStr(storageRes), storageRes); } - - if (result > 0) { - if (error && *error != VPAD_READ_SUCCESS) { - return result; - } - if (cooldown == 0) { - cooldown = 60; // 1 second cooldown - - uint32_t hold = buffer[0].hold; - VPADLcdMode lcdMode; - - if (hold == buttonComboDisableScreen) { - VPADGetLcdMode(VPAD_CHAN_0, &lcdMode); - - if (lcdMode == VPAD_LCD_ON) { - DEBUG_FUNCTION_LINE("Turning off GamePad screen"); - VPADSetLcdMode(VPAD_CHAN_0, VPAD_LCD_OFF); - } else { - DEBUG_FUNCTION_LINE("Turning on GamePad screen"); - VPADSetLcdMode(VPAD_CHAN_0, VPAD_LCD_ON); - } - } else if (hold == buttonComboShutOff) { - VPADGetLcdMode(VPAD_CHAN_0, &lcdMode); - - int32_t ret = 0; - - if (lcdMode == VPAD_LCD_OFF) { - DEBUG_FUNCTION_LINE("Shutting off GamePad"); - ret = VPADSetLcdMode(VPAD_CHAN_0, VPAD_LCD_ON); - } - - if (ret == 0) { - CCRSysDRCShutdown(); - } - } - } + if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(BUTTON_COMBO_DISABLE_SCREEN_CONFIG_STRING, sButtonComboDisableScreen, CONFIG_BUTTON_COMBO_DISABLE_SCREEN_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("GetOrStoreDefault failed: %s (%d)", WUPSStorageAPI_GetStatusStr(storageRes), storageRes); + } + if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(BUTTON_COMBO_SHUT_OFF_CONFIG_STRING, sButtonComboShutOff, CONFIG_BUTTON_COMBO_SHUT_OFF_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("GetOrStoreDefault failed: %s (%d)", WUPSStorageAPI_GetStatusStr(storageRes), storageRes); } - if (cooldown > 0) { - cooldown--; + if ((storageRes = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) { + DEBUG_FUNCTION_LINE_ERR("GetOrStoreDefault failed: %s (%d)", WUPSStorageAPI_GetStatusStr(storageRes), storageRes); } - return result; + + sDisableScreenHandle = RegisterButtonCombo("Disable screen", sButtonComboDisableScreen, ScreenOffCallback); + sShutOffHandle = RegisterButtonCombo("Shut off", sButtonComboShutOff, ShutOffCallback); + + blockTvButton(); + + deinitLogging(); } -WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead); +ON_APPLICATION_START() { + initLogging(); +} + +ON_APPLICATION_ENDS() { + deinitLogging(); +} diff --git a/src/main.h b/src/main.h index cd96393..099058d 100644 --- a/src/main.h +++ b/src/main.h @@ -2,5 +2,5 @@ #include "version.h" -#define VERSION "v2.0.0" +#define VERSION "v3.0.0" #define VERSION_FULL VERSION VERSION_EXTRA diff --git a/src/utils/WUPSConfigItemButtonCombo.cpp b/src/utils/WUPSConfigItemButtonCombo.cpp deleted file mode 100644 index d23c9f7..0000000 --- a/src/utils/WUPSConfigItemButtonCombo.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "WUPSConfigItemButtonCombo.h" -#include "StringTools.h" -#include "utils/input.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *getButtonChar(VPADButtons value) { - std::string combo; - if (value & VPAD_BUTTON_A) { - return "\ue000"; - } - if (value & VPAD_BUTTON_B) { - return "\ue001"; - } - if (value & VPAD_BUTTON_X) { - return "\ue002"; - } - if (value & VPAD_BUTTON_Y) { - return "\ue003"; - } - if (value & VPAD_BUTTON_L) { - return "\ue083"; - } - if (value & VPAD_BUTTON_R) { - return "\ue084"; - } - if (value & VPAD_BUTTON_ZL) { - return "\ue085"; - } - if (value & VPAD_BUTTON_ZR) { - return "\ue086"; - } - if (value & VPAD_BUTTON_UP) { - return "\ue079"; - } - if (value & VPAD_BUTTON_DOWN) { - return "\ue07A"; - } - if (value & VPAD_BUTTON_LEFT) { - return "\ue07B"; - } - if (value & VPAD_BUTTON_RIGHT) { - return "\ue07C"; - } - if (value & VPAD_BUTTON_STICK_L) { - return "\ue081"; - } - if (value & VPAD_BUTTON_STICK_R) { - return "\ue082"; - } - if (value & VPAD_BUTTON_PLUS) { - return "\ue045"; - } - if (value & VPAD_BUTTON_MINUS) { - return "\ue046"; - } - if (value & VPAD_BUTTON_TV) { - return "\ue089"; - } - if (value & VPAD_BUTTON_RESERVED_BIT) { - return "\ue01E"; - } - return ""; -} - -std::string getComboAsString(uint32_t value) { - char comboString[60]; - memset(comboString, 0, sizeof(comboString)); - - for (uint32_t i = 0; i < 32; i++) { - uint32_t bitMask = 1 << i; - if (value & bitMask) { - auto val = getButtonChar(static_cast(bitMask)); - if (val[0] != '\0') { - strcat(comboString, val); - strcat(comboString, "+"); - } - } - } - std::string res(comboString); - if (res.ends_with("+")) { - res.pop_back(); - } - return res; -} - -int32_t WUPSConfigItemButtonCombo_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) { - auto *item = (ConfigItemButtonCombo *) context; - snprintf(out_buf, out_size, "%s", getComboAsString(item->value).c_str()); - return 0; -} - -bool WUPSConfigItemButtonCombo_callCallback(void *context) { - auto *item = (ConfigItemButtonCombo *) context; - if (item->callback != nullptr) { - ((ButtonComboValueChangedCallback) (item->callback))(item, item->value); - return true; - } - return false; -} - -void checkForHold(ConfigItemButtonCombo *item) { - uint32_t lastHold = 0; - uint32_t holdFor = 0; - uint32_t holdForTarget = item->holdDurationInMs >> 4; - uint32_t holdAbortTarget = item->abortButtonHoldDurationInMs >> 4; - - auto mask = VPAD_BUTTON_A | VPAD_BUTTON_B | VPAD_BUTTON_X | VPAD_BUTTON_Y | VPAD_BUTTON_L | VPAD_BUTTON_R | - VPAD_BUTTON_ZL | VPAD_BUTTON_ZR | VPAD_BUTTON_UP | VPAD_BUTTON_DOWN | VPAD_BUTTON_LEFT | VPAD_BUTTON_RIGHT | - VPAD_BUTTON_STICK_L | VPAD_BUTTON_STICK_R | VPAD_BUTTON_PLUS | VPAD_BUTTON_MINUS | VPAD_BUTTON_TV | VPAD_BUTTON_RESERVED_BIT; - - KPADStatus kpad_data{}; - KPADError kpad_error; - - while (true) { - uint32_t buttonsHold = 0; - VPADReadError vpad_error = VPAD_READ_UNINITIALIZED; - VPADStatus vpad_data; - VPADRead(VPAD_CHAN_0, &vpad_data, 1, &vpad_error); - if (vpad_error == VPAD_READ_SUCCESS) { - buttonsHold = vpad_data.hold; - } - - for (int i = 0; i < 4; i++) { - memset(&kpad_data, 0, sizeof(kpad_data)); - if (KPADReadEx((KPADChan) i, &kpad_data, 1, &kpad_error) > 0) { - if (kpad_error == KPAD_ERROR_OK && kpad_data.extensionType != 0xFF) { - if (kpad_data.extensionType == WPAD_EXT_CORE || kpad_data.extensionType == WPAD_EXT_NUNCHUK) { - buttonsHold |= remapWiiMoteButtons(kpad_data.hold); - } else if (kpad_data.extensionType == WPAD_EXT_PRO_CONTROLLER) { - buttonsHold |= remapProButtons(kpad_data.pro.hold); - } else { - buttonsHold |= remapClassicButtons(kpad_data.classic.hold); - } - } - } - } - - buttonsHold &= mask; - - if (buttonsHold == lastHold) { - if (buttonsHold != 0) { - holdFor++; - } - } else { - holdFor = 0; - } - lastHold = buttonsHold; - - if (holdFor >= holdAbortTarget && lastHold == item->abortButton) { - break; - } - - if (holdFor >= holdForTarget) { - item->value = lastHold; - break; - } - OSSleepTicks(OSMillisecondsToTicks(16)); - } -} - -void WUPSConfigItemButtonCombo_onButtonPressed(void *context, WUPSConfigButtons buttons) { - auto *item = (ConfigItemButtonCombo *) context; - if (item->state == BUTTON_COMBO_STATE_NONE) { - if ((buttons & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) { - item->state = BUTTON_COMBO_STATE_PREPARE_FOR_HOLD; - } - } -} - -bool WUPSConfigItemButtonCombo_isMovementAllowed(void *context) { - return true; -} - -int32_t WUPSConfigItemButtonCombo_getCurrentValueSelectedDisplay(void *context, char *out_buf, int32_t out_size) { - auto *item = (ConfigItemButtonCombo *) context; - if (item->state == BUTTON_COMBO_STATE_PREPARE_FOR_HOLD || item->state == BUTTON_COMBO_STATE_WAIT_FOR_HOLD) { - if (item->state == BUTTON_COMBO_STATE_PREPARE_FOR_HOLD) { - item->state = BUTTON_COMBO_STATE_WAIT_FOR_HOLD; - snprintf(out_buf, out_size, "", item->holdDurationInMs, getButtonChar(item->abortButton)); - return 0; - } else { - checkForHold(item); - item->state = BUTTON_COMBO_STATE_NONE; - } - } - snprintf(out_buf, out_size, "(Press \ue000 to change) %s", getComboAsString(item->value).c_str()); - return 0; -} - -void WUPSConfigItemButtonCombo_restoreDefault(void *context) { - auto *item = (ConfigItemButtonCombo *) context; - item->value = item->defaultValue; -} - -void WUPSConfigItemButtonCombo_onSelected(void *context, bool isSelected) { -} - -void WUPSConfigItemButtonCombo_onDelete(void *context) { - auto *item = (ConfigItemButtonCombo *) context; - if (item->configId) { - free(item->configId); - } - free(item); -} - -extern "C" bool -WUPSConfigItemButtonComboAddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, uint32_t defaultComboInVPADButtons, uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs, ButtonComboValueChangedCallback callback) { - if (cat == 0) { - return false; - } - auto *item = (ConfigItemButtonCombo *) malloc(sizeof(ConfigItemButtonCombo)); - if (item == nullptr) { - OSReport("WUPSConfigItemButtonComboAddToCategoryEx: Failed to allocate memory for item data.\n"); - return false; - } - - if (configID != nullptr) { - item->configId = strdup(configID); - } else { - item->configId = nullptr; - } - - item->abortButton = abortButton; - item->abortButtonHoldDurationInMs = abortButtonHoldDurationInMs; - item->holdDurationInMs = holdDurationInMs; - item->defaultValue = defaultComboInVPADButtons; - item->value = defaultComboInVPADButtons; - item->callback = (void *) callback; - item->state = BUTTON_COMBO_STATE_NONE; - - WUPSConfigCallbacks_t callbacks = { - .getCurrentValueDisplay = &WUPSConfigItemButtonCombo_getCurrentValueDisplay, - .getCurrentValueSelectedDisplay = &WUPSConfigItemButtonCombo_getCurrentValueSelectedDisplay, - .onSelected = &WUPSConfigItemButtonCombo_onSelected, - .restoreDefault = &WUPSConfigItemButtonCombo_restoreDefault, - .isMovementAllowed = &WUPSConfigItemButtonCombo_isMovementAllowed, - .callCallback = &WUPSConfigItemButtonCombo_callCallback, - .onButtonPressed = &WUPSConfigItemButtonCombo_onButtonPressed, - .onDelete = &WUPSConfigItemButtonCombo_onDelete}; - - if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) { - OSReport("WUPSConfigItemButtonComboAddToCategoryEx: Failed to create config item.\n"); - free(item); - return false; - } - - if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) { - OSReport("WUPSConfigItemButtonComboAddToCategoryEx: Failed to add item to category.\n"); - WUPSConfigItem_Destroy(item->handle); - return false; - } - return true; -} - -extern "C" bool -WUPSConfigItemButtonComboAddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, uint32_t defaultComboInVPADButtons, ButtonComboValueChangedCallback callback) { - return WUPSConfigItemButtonComboAddToCategoryEx(cat, configID, displayName, defaultComboInVPADButtons, 2000, VPAD_BUTTON_B, 250, callback); -} diff --git a/src/utils/WUPSConfigItemButtonCombo.h b/src/utils/WUPSConfigItemButtonCombo.h deleted file mode 100644 index f270422..0000000 --- a/src/utils/WUPSConfigItemButtonCombo.h +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum ButtonComboState { - BUTTON_COMBO_STATE_NONE, - BUTTON_COMBO_STATE_PREPARE_FOR_HOLD, - BUTTON_COMBO_STATE_WAIT_FOR_HOLD, -} ButtonComboState; - -typedef struct ConfigItemButtonCombo { - char *configId; - WUPSConfigItemHandle handle; - uint32_t defaultValue; - uint32_t value; - uint32_t holdDurationInMs; - VPADButtons abortButton; - uint32_t abortButtonHoldDurationInMs; - void *callback; - ButtonComboState state; -} ConfigItemButtonCombo; - -typedef void (*ButtonComboValueChangedCallback)(ConfigItemButtonCombo *item, uint32_t buttonComboInVPADButtons); - -bool WUPSConfigItemButtonComboAddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, uint32_t defaultComboInVPADButtons, ButtonComboValueChangedCallback callback); - -bool WUPSConfigItemButtonComboAddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, uint32_t defaultComboInVPADButtons, uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs, ButtonComboValueChangedCallback callback); - -#define WUPSConfigItemButtonCombo_AddToCategoryHandled(__config__, __cat__, __configID__, __displayName__, __defaultComboInVPADButtons__, __callback__) \ - do { \ - if (!WUPSConfigItemButtonComboAddToCategory(__cat__, __configID__, __displayName__, __defaultComboInVPADButtons__, __callback__)) { \ - WUPSConfig_Destroy(__config__); \ - return 0; \ - } \ - } while (0) - -#ifdef __cplusplus -} -#endif