Implement support for WUPS 0.8.0

This commit is contained in:
Maschell 2023-12-14 21:29:11 +01:00
parent b2921402cb
commit f447e0333f
10 changed files with 371 additions and 257 deletions

View File

@ -1,6 +1,6 @@
FROM ghcr.io/wiiu-env/devkitppc:20231112
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20230719 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:0.8.0-dev-20240223-46f4cf6 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libmappedmemory:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20230621 /artifacts $DEVKITPRO

View File

@ -2,17 +2,17 @@
#define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/"
typedef enum {
enum ImageOutputFormatEnum {
IMAGE_OUTPUT_FORMAT_JPEG = 0,
IMAGE_OUTPUT_FORMAT_PNG = 1,
IMAGE_OUTPUT_FORMAT_BMP = 2,
} ImageOutputFormatEnum;
};
typedef enum {
enum ImageSourceEnum {
IMAGE_SOURCE_TV_AND_DRC = 0,
IMAGE_SOURCE_TV = 1,
IMAGE_SOURCE_DRC = 2,
} ImageSourceEnum;
};
enum ScreenshotState {
SCREENSHOT_STATE_READY,

View File

@ -6,6 +6,7 @@
#include "utils/utils.h"
#include <vpad/input.h>
#include <wups.h>
#include <wups/config/WUPSConfigCategory.h>
#include <wups/config/WUPSConfigItemBoolean.h>
#include <wups/config/WUPSConfigItemIntegerRange.h>
#include <wups/config/WUPSConfigItemMultipleValues.h>
@ -13,76 +14,50 @@
WUPS_USE_STORAGE("screenshot_plugin");
WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle);
void ConfigMenuClosedCallback() {
WUPSStorageError storageRes;
if ((storageRes = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to close storage %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
}
void InitConfig() {
WUPSConfigAPIOptionsV1 configOptions = {.name = "Screenshot Plugin"};
if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to init config api");
}
gButtonCombo = VPAD_BUTTON_TV;
// 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, &gEnabled)) == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Add the value to the storage if it's missing.
if (WUPS_StoreBool(nullptr, ENABLED_CONFIG_STRING, gEnabled) != 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);
}
// Try to get value from storage
if ((storageRes = WUPS_GetInt(nullptr, FORMAT_CONFIG_STRING, reinterpret_cast<int32_t *>(&gOutputFormat))) == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Add the value to the storage if it's missing.
if (WUPS_StoreInt(nullptr, FORMAT_CONFIG_STRING, gOutputFormat) != 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);
}
// Try to get value from storage
if ((storageRes = WUPS_GetInt(nullptr, QUALITY_CONFIG_STRING, reinterpret_cast<int32_t *>(&gQuality))) == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Add the value to the storage if it's missing.
if (WUPS_StoreInt(nullptr, QUALITY_CONFIG_STRING, (int32_t) gQuality) != 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);
}
WUPSStorageError storageRes;
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(ENABLED_CONFIG_STRING, gEnabled, ENABLED_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
// Try to get value from storage
if ((storageRes = WUPS_GetInt(nullptr, SCREEN_CONFIG_STRING, reinterpret_cast<int32_t *>(&gImageSource))) == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Add the value to the storage if it's missing.
if (WUPS_StoreInt(nullptr, SCREEN_CONFIG_STRING, (int32_t) gImageSource) != 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);
}
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(FORMAT_CONFIG_STRING, gOutputFormat, FORMAT_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
// Try to get value from storage
if ((storageRes = WUPS_GetInt(nullptr, BUTTON_COMBO_CONFIG_STRING, reinterpret_cast<int32_t *>(&gButtonCombo))) == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Add the value to the storage if it's missing.
if (WUPS_StoreInt(nullptr, BUTTON_COMBO_CONFIG_STRING, (int32_t) gButtonCombo) != 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);
}
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(QUALITY_CONFIG_STRING, gQuality, QUALITY_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
// Try to get value from storage
if ((storageRes = WUPS_GetBool(nullptr, RESERVED_BIT_USAGE_CONFIG_STRING, &gReservedBitUsage)) == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Add the value to the storage if it's missing.
if (WUPS_StoreBool(nullptr, RESERVED_BIT_USAGE_CONFIG_STRING, gReservedBitUsage) != 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);
}
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(SCREEN_CONFIG_STRING, gImageSource, SCREEN_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
// Close storage
if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to close storage");
}
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault<uint32_t>(BUTTON_COMBO_CONFIG_STRING, gButtonCombo, BUTTON_COMBO_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(RESERVED_BIT_USAGE_CONFIG_STRING, gReservedBitUsage, RESERVED_BIT_USAGE_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
if ((storageRes = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to save storage %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
}
if (gButtonCombo & VPAD_BUTTON_TV) {
@ -104,32 +79,38 @@ void InitConfig() {
}
void multipleValueItemCallback(ConfigItemMultipleValues *item, uint32_t newValue) {
if (item && item->configId) {
if (item && item->identifier) {
DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->configId, newValue);
if (std::string_view(item->configId) == FORMAT_CONFIG_STRING) {
if (std::string_view(item->identifier) == FORMAT_CONFIG_STRING) {
gOutputFormat = (ImageOutputFormatEnum) newValue;
if (gOutputFormat >= 3) {
gOutputFormat = IMAGE_OUTPUT_FORMAT_JPEG;
}
WUPS_StoreInt(nullptr, item->configId, (int32_t) newValue);
} else if (std::string_view(item->configId) == SCREEN_CONFIG_STRING) {
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(item->identifier, gOutputFormat)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %d): %s", item->identifier, gOutputFormat, WUPSStorageAPI::GetStatusStr(err).data());
}
} else if (std::string_view(item->identifier) == SCREEN_CONFIG_STRING) {
gImageSource = (ImageSourceEnum) newValue;
if (gImageSource >= 3) {
gImageSource = IMAGE_SOURCE_TV_AND_DRC;
}
WUPS_StoreInt(nullptr, item->configId, (int32_t) newValue);
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(item->identifier, gImageSource)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %d): %s", item->identifier, gImageSource, WUPSStorageAPI::GetStatusStr(err).data());
}
}
}
}
void integerRangeItemCallback(ConfigItemIntegerRange *item, int32_t newValue) {
if (item && item->configId) {
if (item && item->identifier) {
DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->configId, newValue);
if (std::string_view(item->configId) == QUALITY_CONFIG_STRING) {
if (std::string_view(item->identifier) == QUALITY_CONFIG_STRING) {
gQuality = (ImageOutputFormatEnum) newValue;
if (gQuality < 10) {
@ -138,31 +119,40 @@ void integerRangeItemCallback(ConfigItemIntegerRange *item, int32_t newValue) {
gQuality = 100;
}
WUPS_StoreInt(nullptr, item->configId, (int32_t) gQuality);
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(item->identifier, gQuality)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %d): %s", item->identifier, gQuality, WUPSStorageAPI::GetStatusStr(err).data());
}
}
}
}
void boolItemCallback(ConfigItemBoolean *item, bool newValue) {
if (item && item->configId) {
if (item && item->identifier) {
DEBUG_FUNCTION_LINE("New value in %s changed: %d", item->configId, newValue);
if (std::string_view(item->configId) == ENABLED_CONFIG_STRING) {
if (std::string_view(item->identifier) == ENABLED_CONFIG_STRING) {
gEnabled = newValue;
if (gEnabled) {
InitNotificationModule();
}
WUPS_StoreBool(nullptr, item->configId, gEnabled);
} else if (std::string_view(item->configId) == RESERVED_BIT_USAGE_CONFIG_STRING) {
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(item->identifier, gEnabled)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %d): %s", item->identifier, gEnabled, WUPSStorageAPI::GetStatusStr(err).data());
}
} else if (std::string_view(item->identifier) == RESERVED_BIT_USAGE_CONFIG_STRING) {
gReservedBitUsage = newValue;
WUPS_StoreBool(nullptr, item->configId, gReservedBitUsage);
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(item->identifier, gReservedBitUsage)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %d): %s", item->identifier, gReservedBitUsage, WUPSStorageAPI::GetStatusStr(err).data());
}
}
}
}
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_CONFIG_STRING) {
if (item && item->identifier) {
DEBUG_FUNCTION_LINE("New value in %s changed: %08X", item->configId, newValue);
if (std::string_view(item->identifier) == BUTTON_COMBO_CONFIG_STRING) {
gButtonCombo = newValue;
if (gButtonCombo & VPAD_BUTTON_TV) {
DEBUG_FUNCTION_LINE("Block TV Menu");
@ -171,85 +161,65 @@ void buttonComboItemChanged(ConfigItemButtonCombo *item, uint32_t newValue) {
DEBUG_FUNCTION_LINE("Unblock TV Menu");
VPADSetTVMenuInvalid(VPAD_CHAN_0, false);
}
WUPS_StoreInt(nullptr, item->configId, (int32_t) gButtonCombo);
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(item->identifier, gButtonCombo)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %08X): %s", item->identifier, gButtonCombo, WUPSStorageAPI::GetStatusStr(err).data());
}
}
}
}
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;
WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle) {
try {
WUPSConfigCategory root = WUPSConfigCategory(rootHandle);
root.add(WUPSConfigItemBoolean::Create(ENABLED_CONFIG_STRING,
"Enabled",
ENABLED_CONFIG_DEFAULT, gEnabled,
&boolItemCallback));
root.add(WUPSConfigItemButtonCombo::Create(BUTTON_COMBO_CONFIG_STRING,
"Button combo",
BUTTON_COMBO_CONFIG_DEFAULT, gButtonCombo,
&buttonComboItemChanged));
constexpr WUPSConfigItemMultipleValues::ValuePair possibleScreenValues[] = {
{IMAGE_SOURCE_TV_AND_DRC, "TV & GamePad"},
{IMAGE_SOURCE_TV, "TV only"},
{IMAGE_SOURCE_DRC, "GamePad only"},
};
root.add(WUPSConfigItemMultipleValues::CreateFromValue(SCREEN_CONFIG_STRING,
"Screen",
SCREEN_CONFIG_DEFAULT, gImageSource,
possibleScreenValues,
&multipleValueItemCallback));
constexpr WUPSConfigItemMultipleValues::ValuePair possibleFormatValues[] = {
{IMAGE_OUTPUT_FORMAT_JPEG, "JPEG"},
{IMAGE_OUTPUT_FORMAT_PNG, "PNG"},
{IMAGE_OUTPUT_FORMAT_BMP, "BMP"}};
root.add(WUPSConfigItemMultipleValues::CreateFromValue(FORMAT_CONFIG_STRING,
"Output format",
FORMAT_CONFIG_DEFAULT, gOutputFormat,
possibleFormatValues,
&multipleValueItemCallback));
root.add(WUPSConfigItemIntegerRange::Create(FORMAT_CONFIG_STRING,
"JPEG quality",
FORMAT_CONFIG_DEFAULT, gQuality,
10, 100,
&integerRangeItemCallback));
root.add(WUPSConfigItemBoolean::Create(RESERVED_BIT_USAGE_CONFIG_STRING,
"Check ReservedBit for taking screenshots",
RESERVED_BIT_USAGE_CONFIG_DEFAULT, gReservedBitUsage,
&boolItemCallback));
} catch (std::exception &e) {
OSReport("Exception T_T : %s\n", e.what());
return WUPSCONFIG_API_CALLBACK_RESULT_ERROR;
}
WUPSConfigHandle config;
WUPSConfig_CreateHandled(&config, "Screenshot plugin");
WUPSConfigCategoryHandle setting;
WUPSConfig_AddCategoryByNameHandled(config, "Settings", &setting);
WUPSConfigItemBoolean_AddToCategoryHandled(config, setting, ENABLED_CONFIG_STRING, "Enabled", gEnabled, &boolItemCallback);
WUPSConfigItemButtonCombo_AddToCategoryHandled(config, setting, BUTTON_COMBO_CONFIG_STRING, "Button combo", gButtonCombo, &buttonComboItemChanged);
ConfigItemMultipleValuesPair source[3];
source[0].value = IMAGE_SOURCE_TV_AND_DRC;
source[0].valueName = (char *) "TV & GamePad";
source[1].value = IMAGE_SOURCE_TV;
source[1].valueName = (char *) "TV only";
source[2].value = IMAGE_SOURCE_DRC;
source[2].valueName = (char *) "GamePad only";
uint32_t defaultIndex = 0;
uint32_t curIndex = 0;
for (auto &cur : source) {
if (cur.value == gImageSource) {
defaultIndex = curIndex;
break;
}
curIndex++;
}
WUPSConfigItemMultipleValues_AddToCategoryHandled(config, setting, SCREEN_CONFIG_STRING, "Screen", defaultIndex, source,
sizeof(source) / sizeof(source[0]), &multipleValueItemCallback);
ConfigItemMultipleValuesPair fileFormat[3];
fileFormat[0].value = IMAGE_OUTPUT_FORMAT_JPEG;
fileFormat[0].valueName = (char *) "JPEG";
fileFormat[1].value = IMAGE_OUTPUT_FORMAT_PNG;
fileFormat[1].valueName = (char *) "PNG";
fileFormat[2].value = IMAGE_OUTPUT_FORMAT_BMP;
fileFormat[2].valueName = (char *) "BMP";
defaultIndex = 0;
curIndex = 0;
for (auto &cur : fileFormat) {
if (cur.value == gOutputFormat) {
defaultIndex = curIndex;
break;
}
curIndex++;
}
WUPSConfigItemMultipleValues_AddToCategoryHandled(config, setting, FORMAT_CONFIG_STRING, "Output format", defaultIndex, fileFormat,
sizeof(fileFormat) / sizeof(fileFormat[0]), &multipleValueItemCallback);
WUPSConfigItemIntegerRange_AddToCategoryHandled(config, setting, QUALITY_CONFIG_STRING, "JPEG quality", gQuality, 10, 100, &integerRangeItemCallback);
WUPSConfigItemBoolean_AddToCategoryHandled(config, setting, RESERVED_BIT_USAGE_CONFIG_STRING, "Check ReservedBit for taking screenshots", gReservedBitUsage, &boolItemCallback);
return config;
return WUPSCONFIG_API_CALLBACK_RESULT_SUCCESS;
}
WUPS_CONFIG_CLOSED() {
// Save all changes
if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to close storage");
}
}

View File

@ -1,10 +1,17 @@
#pragma once
#define ENABLED_CONFIG_STRING "enabled"
#define BUTTON_COMBO_CONFIG_STRING "buttonCombo"
#define FORMAT_CONFIG_STRING "format"
#define QUALITY_CONFIG_STRING "quality"
#define SCREEN_CONFIG_STRING "screen"
#define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"
#define ENABLED_CONFIG_DEFAULT true
#define FORMAT_CONFIG_DEFAULT IMAGE_OUTPUT_FORMAT_JPEG
#define QUALITY_CONFIG_DEFAULT 90
#define SCREEN_CONFIG_DEFAULT IMAGE_SOURCE_TV_AND_DRC
#define BUTTON_COMBO_CONFIG_DEFAULT 0
#define RESERVED_BIT_USAGE_CONFIG_DEFAULT true
#define ENABLED_CONFIG_STRING "enabled"
#define BUTTON_COMBO_CONFIG_STRING "buttonCombo"
#define FORMAT_CONFIG_STRING "format"
#define QUALITY_CONFIG_STRING "quality"
#define SCREEN_CONFIG_STRING "screen"
#define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"
void InitConfig();

View File

@ -1,20 +1,22 @@
#include "retain_vars.hpp"
#include "config.h"
#include <string>
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
ImageSourceEnum gImageSource = IMAGE_SOURCE_TV_AND_DRC;
bool gEnabled = true;
uint32_t gButtonCombo = 0;
int32_t gQuality = 90;
ImageOutputFormatEnum gOutputFormat = IMAGE_OUTPUT_FORMAT_JPEG;
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
ImageSourceEnum gImageSource = SCREEN_CONFIG_DEFAULT;
bool gEnabled = ENABLED_CONFIG_DEFAULT;
uint32_t gButtonCombo = BUTTON_COMBO_CONFIG_DEFAULT;
int32_t gQuality = QUALITY_CONFIG_DEFAULT;
ImageOutputFormatEnum gOutputFormat = FORMAT_CONFIG_DEFAULT;
bool gReservedBitUsage = RESERVED_BIT_USAGE_CONFIG_DEFAULT;
std::string gShortNameEn;
ScreenshotState gTakeScreenshotTV = SCREENSHOT_STATE_READY;
ScreenshotState gTakeScreenshotDRC = SCREENSHOT_STATE_READY;
bool gReservedBitUsage = true;
bool gInProgressNotificationDisplayedDRC = false;
bool gInProgressNotificationDisplayedTV = false;
bool gNotAvailableNotificationDisplayed = false;

View File

@ -4,19 +4,21 @@
#include <notifications/notifications.h>
#include <string>
extern bool gEnabled;
extern ImageSourceEnum gImageSource;
extern GX2SurfaceFormat gTVSurfaceFormat;
extern GX2SurfaceFormat gDRCSurfaceFormat;
extern ImageSourceEnum gImageSource;
extern bool gEnabled;
extern uint32_t gButtonCombo;
extern int32_t gQuality;
extern ImageOutputFormatEnum gOutputFormat;
extern bool gReservedBitUsage;
extern std::string gShortNameEn;
extern ScreenshotState gTakeScreenshotTV;
extern ScreenshotState gTakeScreenshotDRC;
extern bool gReservedBitUsage;
extern bool gInProgressNotificationDisplayedDRC;
extern bool gInProgressNotificationDisplayedTV;

View File

@ -1,5 +1,4 @@
#include "WUPSConfigItemButtonCombo.h"
#include "StringTools.h"
#include "utils/input.h"
#include <coreinit/debug.h>
#include <coreinit/thread.h>
@ -11,7 +10,7 @@
#include <vpad/input.h>
#include <wups.h>
const char *getButtonChar(VPADButtons value) {
static const char *getButtonChar(VPADButtons value) {
std::string combo;
if (value & VPAD_BUTTON_A) {
return "\ue000";
@ -70,7 +69,7 @@ const char *getButtonChar(VPADButtons value) {
return "";
}
std::string getComboAsString(uint32_t value) {
static std::string getComboAsString(uint32_t value) {
char comboString[60];
memset(comboString, 0, sizeof(comboString));
@ -91,22 +90,20 @@ std::string getComboAsString(uint32_t value) {
return res;
}
int32_t WUPSConfigItemButtonCombo_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
static 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) {
static void WUPSConfigItemButtonCombo_onCloseCallback(void *context) {
auto *item = (ConfigItemButtonCombo *) context;
if (item->callback != nullptr) {
((ButtonComboValueChangedCallback) (item->callback))(item, item->value);
return true;
if (item->valueAtCreation != item->value && item->valueChangedCallback != nullptr) {
((ButtonComboValueChangedCallback) (item->valueChangedCallback))(item, item->value);
}
return false;
}
void checkForHold(ConfigItemButtonCombo *item) {
static void checkForHold(ConfigItemButtonCombo *item) {
uint32_t lastHold = 0;
uint32_t holdFor = 0;
uint32_t holdForTarget = item->holdDurationInMs >> 4;
@ -122,9 +119,8 @@ void checkForHold(ConfigItemButtonCombo *item) {
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) {
VPADStatus vpad_data = {};
if (VPADRead(VPAD_CHAN_0, &vpad_data, 1, &vpad_error) > 0 && vpad_error == VPAD_READ_SUCCESS) {
buttonsHold = vpad_data.hold;
}
@ -166,20 +162,16 @@ void checkForHold(ConfigItemButtonCombo *item) {
}
}
void WUPSConfigItemButtonCombo_onButtonPressed(void *context, WUPSConfigButtons buttons) {
static void WUPSConfigItemButtonCombo_onInput(void *context, WUPSConfigSimplePadData input) {
auto *item = (ConfigItemButtonCombo *) context;
if (item->state == BUTTON_COMBO_STATE_NONE) {
if ((buttons & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) {
if ((input.buttons_d & 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) {
static 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) {
@ -195,72 +187,112 @@ int32_t WUPSConfigItemButtonCombo_getCurrentValueSelectedDisplay(void *context,
return 0;
}
void WUPSConfigItemButtonCombo_restoreDefault(void *context) {
static 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);
static void WUPSConfigItemButtonCombo_Cleanup(ConfigItemButtonCombo *item) {
if (!item) {
return;
}
free((void *) item->identifier);
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;
static void WUPSConfigItemButtonCombo_onDelete(void *context) {
WUPSConfigItemButtonCombo_Cleanup((ConfigItemButtonCombo *) context);
}
extern "C" WUPSConfigAPIStatus
WUPSConfigItemButtonCombo_CreateEx(const char *identifier,
const char *displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs,
VPADButtons abortButton,
uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback,
WUPSConfigItemHandle *outHandle) {
if (outHandle == nullptr) {
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
}
auto *item = (ConfigItemButtonCombo *) malloc(sizeof(ConfigItemButtonCombo));
if (item == nullptr) {
OSReport("WUPSConfigItemButtonComboAddToCategoryEx: Failed to allocate memory for item data.\n");
return false;
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
}
if (configID != nullptr) {
item->configId = strdup(configID);
if (identifier != nullptr) {
item->identifier = strdup(identifier);
} else {
item->configId = nullptr;
item->identifier = nullptr;
}
item->abortButton = abortButton;
item->abortButtonHoldDurationInMs = abortButtonHoldDurationInMs;
item->holdDurationInMs = holdDurationInMs;
item->defaultValue = defaultComboInVPADButtons;
item->value = defaultComboInVPADButtons;
item->callback = (void *) callback;
item->value = currentComboInVPADButtons;
item->valueAtCreation = currentComboInVPADButtons;
item->valueChangedCallback = (void *) callback;
item->state = BUTTON_COMBO_STATE_NONE;
WUPSConfigCallbacks_t callbacks = {
WUPSConfigAPIItemCallbacksV2 callbacks = {
.getCurrentValueDisplay = &WUPSConfigItemButtonCombo_getCurrentValueDisplay,
.getCurrentValueSelectedDisplay = &WUPSConfigItemButtonCombo_getCurrentValueSelectedDisplay,
.onSelected = &WUPSConfigItemButtonCombo_onSelected,
.onSelected = nullptr,
.restoreDefault = &WUPSConfigItemButtonCombo_restoreDefault,
.isMovementAllowed = &WUPSConfigItemButtonCombo_isMovementAllowed,
.callCallback = &WUPSConfigItemButtonCombo_callCallback,
.onButtonPressed = &WUPSConfigItemButtonCombo_onButtonPressed,
.onDelete = &WUPSConfigItemButtonCombo_onDelete};
.isMovementAllowed = nullptr,
.onCloseCallback = &WUPSConfigItemButtonCombo_onCloseCallback,
.onInput = &WUPSConfigItemButtonCombo_onInput,
.onInputEx = nullptr,
.onDelete = &WUPSConfigItemButtonCombo_onDelete,
};
if (WUPSConfigItem_Create(&item->handle, configID, displayName, callbacks, item) < 0) {
WUPSConfigAPIItemOptionsV2 options = {
.displayName = displayName,
.context = item,
.callbacks = callbacks,
};
WUPSConfigAPIStatus err;
if ((err = WUPSConfigAPI_Item_Create(options, &item->handle)) != WUPSCONFIG_API_RESULT_SUCCESS) {
OSReport("WUPSConfigItemButtonComboAddToCategoryEx: Failed to create config item.\n");
free(item);
return false;
WUPSConfigItemButtonCombo_Cleanup(item);
return err;
}
if (WUPSConfigCategory_AddItem(cat, item->handle) < 0) {
OSReport("WUPSConfigItemButtonComboAddToCategoryEx: Failed to add item to category.\n");
WUPSConfigItem_Destroy(item->handle);
return false;
*outHandle = item->handle;
return WUPSCONFIG_API_RESULT_SUCCESS;
}
extern "C" WUPSConfigAPIStatus
WUPSConfigItemButtonCombo_AddToCategoryEx(WUPSConfigCategoryHandle cat,
const char *identifier,
const char *displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback) {
WUPSConfigItemHandle itemHandle;
WUPSConfigAPIStatus res;
if ((res = WUPSConfigItemButtonCombo_CreateEx(identifier,
displayName,
defaultComboInVPADButtons, currentComboInVPADButtons,
holdDurationInMs, abortButton, abortButtonHoldDurationInMs,
callback, &itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) {
return res;
}
return true;
if ((res = WUPSConfigAPI_Category_AddItem(cat, itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) {
WUPSConfigAPI_Item_Destroy(itemHandle);
return res;
}
return WUPSCONFIG_API_RESULT_SUCCESS;
}
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);
WUPSConfigItemButtonComboAddToCategory(WUPSConfigCategoryHandle cat, const char *displayName, uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons, ButtonComboValueChangedCallback callback) {
return WUPSConfigItemButtonComboAddToCategoryEx(cat, displayName, defaultComboInVPADButtons, currentComboInVPADButtons, 2000, VPAD_BUTTON_B, 250, callback);
}

View File

@ -13,31 +13,82 @@ typedef enum ButtonComboState {
} ButtonComboState;
typedef struct ConfigItemButtonCombo {
char *configId;
const char *identifier;
WUPSConfigItemHandle handle;
uint32_t defaultValue;
uint32_t value;
uint32_t valueAtCreation;
uint32_t holdDurationInMs;
VPADButtons abortButton;
uint32_t abortButtonHoldDurationInMs;
void *callback;
ButtonComboState state;
void *valueChangedCallback;
} ConfigItemButtonCombo;
typedef void (*ButtonComboValueChangedCallback)(ConfigItemButtonCombo *item, uint32_t buttonComboInVPADButtons);
bool WUPSConfigItemButtonComboAddToCategory(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, uint32_t defaultComboInVPADButtons, ButtonComboValueChangedCallback callback);
extern "C" WUPSConfigAPIStatus
WUPSConfigItemButtonCombo_CreateEx(const char *identifier,
const char *displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback,
WUPSConfigItemHandle *outHandle);
bool WUPSConfigItemButtonComboAddToCategoryEx(WUPSConfigCategoryHandle cat, const char *configId, const char *displayName, uint32_t defaultComboInVPADButtons, uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs, ButtonComboValueChangedCallback callback);
bool WUPSConfigItemButtonComboAddToCategory(WUPSConfigCategoryHandle cat,
const char *displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
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)
bool WUPSConfigItemButtonComboAddToCategoryEx(WUPSConfigCategoryHandle cat,
const char *displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs,
VPADButtons abortButton,
uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include <optional>
#include <stdexcept>
#include <string>
#include <wups/config/WUPSConfigItem.h>
#include <wups/config_api.h>
class WUPSConfigItemButtonCombo : public WUPSConfigItem {
public:
static std::optional<WUPSConfigItemButtonCombo> CreateEx(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback,
WUPSConfigAPIStatus &err) noexcept;
static WUPSConfigItemButtonCombo CreateEx(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback);
static std::optional<WUPSConfigItemButtonCombo> Create(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
ButtonComboValueChangedCallback callback,
WUPSConfigAPIStatus &err) noexcept;
static WUPSConfigItemButtonCombo Create(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
ButtonComboValueChangedCallback callback);
private:
explicit WUPSConfigItemButtonCombo(WUPSConfigItemHandle itemHandle) : WUPSConfigItem(itemHandle) {
}
};
#endif

View File

@ -0,0 +1,52 @@
#include "WUPSConfigItemButtonCombo.h"
std::optional<WUPSConfigItemButtonCombo> WUPSConfigItemButtonCombo::CreateEx(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback,
WUPSConfigAPIStatus &err) noexcept {
WUPSConfigItemHandle itemHandle;
if ((err = WUPSConfigItemButtonCombo_CreateEx(identifier ? identifier->data() : nullptr,
displayName.data(),
defaultComboInVPADButtons, currentComboInVPADButtons,
holdDurationInMs, abortButton, abortButtonHoldDurationInMs,
callback,
&itemHandle)) != WUPSCONFIG_API_RESULT_SUCCESS) {
return std::nullopt;
}
return WUPSConfigItemButtonCombo(itemHandle);
}
WUPSConfigItemButtonCombo WUPSConfigItemButtonCombo::CreateEx(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
uint32_t holdDurationInMs, VPADButtons abortButton, uint32_t abortButtonHoldDurationInMs,
ButtonComboValueChangedCallback callback) {
WUPSConfigAPIStatus err;
auto result = CreateEx(std::move(identifier), displayName, defaultComboInVPADButtons, currentComboInVPADButtons, holdDurationInMs, abortButton, abortButtonHoldDurationInMs, callback, err);
if (!result) {
throw std::runtime_error(std::string("Failed to create WUPSConfigItemButtonCombo: ").append(WUPSConfigAPI_GetStatusStr(err)));
}
return std::move(*result);
}
std::optional<WUPSConfigItemButtonCombo> WUPSConfigItemButtonCombo::Create(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
ButtonComboValueChangedCallback callback,
WUPSConfigAPIStatus &err) noexcept {
return CreateEx(std::move(identifier), displayName, defaultComboInVPADButtons, currentComboInVPADButtons, 2000, VPAD_BUTTON_B, 250, callback, err);
}
WUPSConfigItemButtonCombo WUPSConfigItemButtonCombo::Create(std::optional<std::string> identifier,
std::string_view displayName,
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
ButtonComboValueChangedCallback callback) {
WUPSConfigAPIStatus err = WUPSCONFIG_API_RESULT_UNKNOWN_ERROR;
auto res = Create(std::move(identifier), displayName, defaultComboInVPADButtons, currentComboInVPADButtons, callback, err);
if (!res) {
throw std::runtime_error(std::string("Failed to create WUPSConfigItemButtonCombo: ").append(WUPSConfigAPI_GetStatusStr(err)));
}
return std::move(*res);
}

View File

@ -86,22 +86,20 @@ void InitNotificationModule() {
}
NotificationModuleStatus res;
if ((res = NotificationModule_InitLibrary()) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
gInitNotificationModule = true;
std::string error = string_format("Failed to init Screenshot Plugin: \n"
"NotificationModule_InitLibrary returned:\n%s\n\n"
"Please update to latest Aroma before using the plugin.\n\n"
"The plugin has been disabled. You need to enable again in the\n"
"config menu after updating\n\n"
"Hold the POWER button of your CONSOLE for 5 seconds to shut down.",
NotificationModule_GetStatusStr(res));
gEnabled = false;
WUPSStorageError storageRes = WUPS_OpenStorage();
if (storageRes == WUPS_STORAGE_ERROR_SUCCESS) {
if (WUPS_StoreBool(nullptr, ENABLED_CONFIG_STRING, gEnabled) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store value");
}
WUPS_CloseStorage();
gInitNotificationModule = true;
std::string error = string_format("Failed to init Screenshot Plugin: \n"
"NotificationModule_InitLibrary returned:\n%s\n\n"
"Please update to latest Aroma before using the plugin.\n\n"
"The plugin has been disabled. You need to enable again in the\n"
"config menu after updating\n\n"
"Hold the POWER button of your CONSOLE for 5 seconds to shut down.",
NotificationModule_GetStatusStr(res));
gEnabled = false;
if (WUPSStorageAPI::Store(ENABLED_CONFIG_STRING, gEnabled) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store value");
}
WUPSStorageAPI::SaveStorage();
OSFatal(error.c_str());
}