mirror of
https://github.com/wiiu-env/ScreenshotWUPS.git
synced 2025-01-24 09:51:12 +01:00
Use WUPSButtonComboAPI to register button combos
This commit is contained in:
parent
001ab2ccb7
commit
16088a54d6
@ -1,6 +1,6 @@
|
|||||||
FROM ghcr.io/wiiu-env/devkitppc:20240505
|
FROM ghcr.io/wiiu-env/devkitppc:20241128
|
||||||
|
|
||||||
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20240505 /artifacts $DEVKITPRO
|
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:0.8.2-dev-20250104-1569d27 /artifacts $DEVKITPRO
|
||||||
COPY --from=ghcr.io/wiiu-env/libmappedmemory:20230621 /artifacts $DEVKITPRO
|
COPY --from=ghcr.io/wiiu-env/libmappedmemory:20230621 /artifacts $DEVKITPRO
|
||||||
COPY --from=ghcr.io/wiiu-env/libnotifications:20240426 /artifacts $DEVKITPRO
|
COPY --from=ghcr.io/wiiu-env/libnotifications:20240426 /artifacts $DEVKITPRO
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <coreinit/time.h>
|
#include <coreinit/time.h>
|
||||||
|
|
||||||
#define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/"
|
#define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/"
|
||||||
|
|
||||||
enum ImageOutputFormatEnum {
|
enum ImageOutputFormatEnum {
|
||||||
|
143
src/config.cpp
143
src/config.cpp
@ -1,19 +1,92 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "retain_vars.hpp"
|
#include "retain_vars.hpp"
|
||||||
#include "utils/WUPSConfigItemButtonCombo.h"
|
#include "screenshot_utils.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include <vpad/input.h>
|
|
||||||
|
#include <notifications/notifications.h>
|
||||||
|
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
#include <wups/button_combo/api.h>
|
||||||
#include <wups/config/WUPSConfigCategory.h>
|
#include <wups/config/WUPSConfigCategory.h>
|
||||||
#include <wups/config/WUPSConfigItemBoolean.h>
|
#include <wups/config/WUPSConfigItemBoolean.h>
|
||||||
|
#include <wups/config/WUPSConfigItemButtonCombo.h>
|
||||||
#include <wups/config/WUPSConfigItemIntegerRange.h>
|
#include <wups/config/WUPSConfigItemIntegerRange.h>
|
||||||
#include <wups/config/WUPSConfigItemMultipleValues.h>
|
#include <wups/config/WUPSConfigItemMultipleValues.h>
|
||||||
#include <wups/storage.h>
|
#include <wups/storage.h>
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
|
|
||||||
WUPS_USE_STORAGE("screenshot_plugin");
|
WUPS_USE_STORAGE("screenshot_plugin");
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle);
|
WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle rootHandle);
|
||||||
|
|
||||||
void ConfigMenuClosedCallback() {
|
void ConfigMenuClosedCallback() {
|
||||||
@ -23,13 +96,16 @@ void ConfigMenuClosedCallback() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InitConfig() {
|
void InitConfig() {
|
||||||
WUPSConfigAPIOptionsV1 configOptions = {.name = "Screenshot Plugin"};
|
WUPSConfigAPIOptionsV1 configOptions = {.name = "Screenshot Plugin"};
|
||||||
if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) {
|
if (WUPSConfigAPI_Init(configOptions, ConfigMenuOpenedCallback, ConfigMenuClosedCallback) != WUPSCONFIG_API_RESULT_SUCCESS) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to init config api");
|
DEBUG_FUNCTION_LINE_ERR("Failed to init config api");
|
||||||
}
|
}
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_KEEP_UNTIL_SHOWN, true);
|
||||||
gButtonCombo = BUTTON_COMBO_CONFIG_DEFAULT;
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 20.0f);
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_ERROR, NOTIFICATION_MODULE_DEFAULT_OPTION_KEEP_UNTIL_SHOWN, true);
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_ERROR, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 20.0f);
|
||||||
|
|
||||||
WUPSStorageError storageRes;
|
WUPSStorageError storageRes;
|
||||||
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(ENABLED_CONFIG_STRING, gEnabled, ENABLED_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault(ENABLED_CONFIG_STRING, gEnabled, ENABLED_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
@ -48,7 +124,20 @@ void InitConfig() {
|
|||||||
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
|
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault<uint32_t>(BUTTON_COMBO_CONFIG_STRING, gButtonCombo, BUTTON_COMBO_CONFIG_DEFAULT)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
bool showButtonComboInfo = false;
|
||||||
|
auto defaultButtonCombo = BUTTON_COMBO_CONFIG_DEFAULT;
|
||||||
|
storageRes = WUPSStorageAPI::Get<uint32_t>(BUTTON_COMBO_LEGACY_CONFIG_STRING, gButtonCombo);
|
||||||
|
if (storageRes == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
DEBUG_FUNCTION_LINE_INFO("Migrated button combo for screenshot plugin.");
|
||||||
|
gButtonCombo = migrateButtonCombo(gButtonCombo);
|
||||||
|
defaultButtonCombo = static_cast<WUPSButtonCombo_Buttons>(gButtonCombo);
|
||||||
|
WUPSStorageAPI::DeleteItem(BUTTON_COMBO_LEGACY_CONFIG_STRING);
|
||||||
|
} else if (storageRes == WUPS_STORAGE_ERROR_NOT_FOUND && WUPSStorageAPI::Get<uint32_t>(BUTTON_COMBO_CONFIG_STRING, gButtonCombo) == WUPS_STORAGE_ERROR_NOT_FOUND) {
|
||||||
|
showButtonComboInfo = true;
|
||||||
|
}
|
||||||
|
gButtonCombo = defaultButtonCombo;
|
||||||
|
|
||||||
|
if ((storageRes = WUPSStorageAPI::GetOrStoreDefault<uint32_t>(BUTTON_COMBO_CONFIG_STRING, gButtonCombo, defaultButtonCombo)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
|
DEBUG_FUNCTION_LINE_ERR("Failed to GetOrStoreDefault value %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,12 +149,31 @@ void InitConfig() {
|
|||||||
DEBUG_FUNCTION_LINE_ERR("Failed to save storage %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
|
DEBUG_FUNCTION_LINE_ERR("Failed to save storage %s (%d)", WUPSStorageAPI::GetStatusStr(storageRes).data(), storageRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gButtonCombo & VPAD_BUTTON_TV) {
|
if (gButtonCombo == 0) {
|
||||||
DEBUG_FUNCTION_LINE("Block TV Menu");
|
gButtonCombo = defaultButtonCombo;
|
||||||
VPADSetTVMenuInvalid(VPAD_CHAN_0, true);
|
}
|
||||||
|
|
||||||
|
WUPSButtonCombo_ComboStatus comboStatus;
|
||||||
|
WUPSButtonCombo_Error comboError = WUPS_BUTTON_COMBO_ERROR_UNKNOWN_ERROR;
|
||||||
|
auto buttonComboOpt = WUPSButtonComboAPI::CreateComboPressDown(
|
||||||
|
"Screenshot button combo", static_cast<WUPSButtonCombo_Buttons>(gButtonCombo), [](WUPSButtonCombo_ControllerTypes, WUPSButtonCombo_ComboHandle, void *) { RequestScreenshot(); }, nullptr, comboStatus, comboError);
|
||||||
|
if (!buttonComboOpt || comboError != WUPS_BUTTON_COMBO_ERROR_SUCCESS) {
|
||||||
|
const auto errorMsg = string_format("Failed to register button combo for screenshots. %s", WUPSButtonComboAPI::GetStatusStr(comboError).data());
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("%s", errorMsg.c_str());
|
||||||
|
NotificationModule_AddErrorNotification(errorMsg.c_str());
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("Unblock TV Menu");
|
gButtonComboInstances.emplace_front(std::move(*buttonComboOpt));
|
||||||
VPADSetTVMenuInvalid(VPAD_CHAN_0, false);
|
if (comboStatus == WUPS_BUTTON_COMBO_COMBO_STATUS_CONFLICT) {
|
||||||
|
const auto conflictMsg = "ScreenshotPlugin: Button combo was disabled due to a conflict with another combo. Please assign a different combo";
|
||||||
|
DEBUG_FUNCTION_LINE_INFO("%s", conflictMsg);
|
||||||
|
NotificationModule_AddInfoNotification(conflictMsg);
|
||||||
|
} else if (comboStatus != WUPS_BUTTON_COMBO_COMBO_STATUS_VALID) {
|
||||||
|
const auto conflictMsg = string_format("Unknown error happened while registering button combo for the Screenshots. Error: %d", comboStatus);
|
||||||
|
DEBUG_FUNCTION_LINE_INFO("%s", conflictMsg.c_str());
|
||||||
|
NotificationModule_AddInfoNotification(conflictMsg.c_str());
|
||||||
|
} else if (showButtonComboInfo) {
|
||||||
|
NotificationModule_AddInfoNotification("Press \ue089+\ue07B to take screenshots! You can change this button combination at any time in the config menu");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gOutputFormat >= 3) {
|
if (gOutputFormat >= 3) {
|
||||||
@ -76,6 +184,11 @@ void InitConfig() {
|
|||||||
} else if (gQuality > 100) {
|
} else if (gQuality > 100) {
|
||||||
gQuality = 100;
|
gQuality = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_KEEP_UNTIL_SHOWN, false);
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_INFO, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 2.0f);
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_ERROR, NOTIFICATION_MODULE_DEFAULT_OPTION_KEEP_UNTIL_SHOWN, false);
|
||||||
|
NotificationModule_SetDefaultValue(NOTIFICATION_MODULE_NOTIFICATION_TYPE_ERROR, NOTIFICATION_MODULE_DEFAULT_OPTION_DURATION_BEFORE_FADE_OUT, 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void multipleValueItemCallback(ConfigItemMultipleValues *item, uint32_t newValue) {
|
void multipleValueItemCallback(ConfigItemMultipleValues *item, uint32_t newValue) {
|
||||||
@ -149,18 +262,12 @@ void boolItemCallback(ConfigItemBoolean *item, bool newValue) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void buttonComboItemChanged(ConfigItemButtonCombo *item, uint32_t newValue) {
|
void buttonComboItemChanged(ConfigItemButtonCombo *item, uint32_t newValue) {
|
||||||
if (item && item->identifier) {
|
if (item && item->identifier) {
|
||||||
DEBUG_FUNCTION_LINE("New value in %s changed: %08X", item->configId, newValue);
|
DEBUG_FUNCTION_LINE("New value in %s changed: %08X", item->configId, newValue);
|
||||||
if (std::string_view(item->identifier) == BUTTON_COMBO_CONFIG_STRING) {
|
if (std::string_view(item->identifier) == BUTTON_COMBO_CONFIG_STRING) {
|
||||||
gButtonCombo = newValue;
|
gButtonCombo = newValue;
|
||||||
if (gButtonCombo & VPAD_BUTTON_TV) {
|
|
||||||
DEBUG_FUNCTION_LINE("Block TV Menu");
|
|
||||||
VPADSetTVMenuInvalid(VPAD_CHAN_0, true);
|
|
||||||
} else {
|
|
||||||
DEBUG_FUNCTION_LINE("Unblock TV Menu");
|
|
||||||
VPADSetTVMenuInvalid(VPAD_CHAN_0, false);
|
|
||||||
}
|
|
||||||
WUPSStorageError err;
|
WUPSStorageError err;
|
||||||
if ((err = WUPSStorageAPI::Store(item->identifier, gButtonCombo)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
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());
|
DEBUG_FUNCTION_LINE_ERR("Failed to store item %s (newValue: %08X): %s", item->identifier, gButtonCombo, WUPSStorageAPI::GetStatusStr(err).data());
|
||||||
@ -180,7 +287,7 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro
|
|||||||
|
|
||||||
root.add(WUPSConfigItemButtonCombo::Create(BUTTON_COMBO_CONFIG_STRING,
|
root.add(WUPSConfigItemButtonCombo::Create(BUTTON_COMBO_CONFIG_STRING,
|
||||||
"Button combo",
|
"Button combo",
|
||||||
BUTTON_COMBO_CONFIG_DEFAULT, gButtonCombo,
|
BUTTON_COMBO_CONFIG_DEFAULT, gButtonComboHandle,
|
||||||
&buttonComboItemChanged));
|
&buttonComboItemChanged));
|
||||||
|
|
||||||
constexpr WUPSConfigItemMultipleValues::ValuePair possibleScreenValues[] = {
|
constexpr WUPSConfigItemMultipleValues::ValuePair possibleScreenValues[] = {
|
||||||
|
28
src/config.h
28
src/config.h
@ -1,18 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vpad/input.h>
|
#include <wups/button_combo/defines.h>
|
||||||
|
|
||||||
#define ENABLED_CONFIG_DEFAULT true
|
#define ENABLED_CONFIG_DEFAULT true
|
||||||
#define FORMAT_CONFIG_DEFAULT IMAGE_OUTPUT_FORMAT_JPEG
|
#define FORMAT_CONFIG_DEFAULT IMAGE_OUTPUT_FORMAT_JPEG
|
||||||
#define QUALITY_CONFIG_DEFAULT 90
|
#define QUALITY_CONFIG_DEFAULT 90
|
||||||
#define SCREEN_CONFIG_DEFAULT IMAGE_SOURCE_TV_AND_DRC
|
#define SCREEN_CONFIG_DEFAULT IMAGE_SOURCE_TV_AND_DRC
|
||||||
#define BUTTON_COMBO_CONFIG_DEFAULT VPAD_BUTTON_TV
|
#define BUTTON_COMBO_CONFIG_DEFAULT ((WUPSButtonCombo_Buttons) (WUPS_BUTTON_COMBO_BUTTON_TV | WUPS_BUTTON_COMBO_BUTTON_LEFT))
|
||||||
#define RESERVED_BIT_USAGE_CONFIG_DEFAULT true
|
#define RESERVED_BIT_USAGE_CONFIG_DEFAULT true
|
||||||
|
|
||||||
#define ENABLED_CONFIG_STRING "enabled"
|
#define ENABLED_CONFIG_STRING "enabled"
|
||||||
#define BUTTON_COMBO_CONFIG_STRING "buttonCombo"
|
#define BUTTON_COMBO_LEGACY_CONFIG_STRING "buttonCombo"
|
||||||
#define FORMAT_CONFIG_STRING "format"
|
#define BUTTON_COMBO_CONFIG_STRING "buttonComboNew"
|
||||||
#define QUALITY_CONFIG_STRING "quality"
|
#define FORMAT_CONFIG_STRING "format"
|
||||||
#define SCREEN_CONFIG_STRING "screen"
|
#define QUALITY_CONFIG_STRING "quality"
|
||||||
#define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"
|
#define SCREEN_CONFIG_STRING "screen"
|
||||||
|
#define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"
|
||||||
|
#define BUTTON_COMBO_INFO_SHOWN_CONFIG_STRING "buttonComboInfoShown"
|
||||||
|
|
||||||
void InitConfig();
|
void InitConfig();
|
||||||
|
@ -1,176 +1,13 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "fs/FSUtils.h"
|
|
||||||
#include "retain_vars.hpp"
|
#include "retain_vars.hpp"
|
||||||
#include "screenshot_utils.h"
|
#include "screenshot_utils.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "utils/input.h"
|
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include <coreinit/cache.h>
|
|
||||||
#include <gx2/surface.h>
|
#include <gx2/surface.h>
|
||||||
#include <padscore/wpad.h>
|
|
||||||
#include <vpad/input.h>
|
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
|
||||||
extern "C" uint32_t VPADGetButtonProcMode(uint32_t);
|
|
||||||
|
|
||||||
void AlreadyInProgressCallback(NotificationModuleHandle handle, void *context) {
|
|
||||||
auto scanTarget = (GX2ScanTarget) (uint32_t) context;
|
|
||||||
if (scanTarget == GX2_SCAN_TARGET_TV) {
|
|
||||||
gInProgressNotificationDisplayedTV = false;
|
|
||||||
} else if (scanTarget == GX2_SCAN_TARGET_DRC) {
|
|
||||||
gInProgressNotificationDisplayedDRC = false;
|
|
||||||
}
|
|
||||||
OSMemoryBarrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotAvailableCallback(NotificationModuleHandle handle, void *context) {
|
|
||||||
gNotAvailableNotificationDisplayed = false;
|
|
||||||
OSMemoryBarrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RequestScreenshot() {
|
|
||||||
NotificationModuleStatus err;
|
|
||||||
if (gBlockScreenshots) {
|
|
||||||
if (!gNotAvailableNotificationDisplayed) {
|
|
||||||
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshots not available at the moment.",
|
|
||||||
NotAvailableCallback,
|
|
||||||
nullptr)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to display \"Screenshots not available at the moment.\" notification");
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Error: %s,", NotificationModule_GetStatusStr(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gNotAvailableNotificationDisplayed = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OSCalendarTime time;
|
|
||||||
OSTicksToCalendarTime(OSGetTime(), &time);
|
|
||||||
if (gImageSource == IMAGE_SOURCE_TV_AND_DRC || gImageSource == IMAGE_SOURCE_TV) {
|
|
||||||
if (gTakeScreenshotTV.state == SCREENSHOT_STATE_READY) {
|
|
||||||
DEBUG_FUNCTION_LINE("Requested screenshot for TV!");
|
|
||||||
gTakeScreenshotTV.state = SCREENSHOT_STATE_REQUESTED;
|
|
||||||
gTakeScreenshotTV.time = time;
|
|
||||||
gReadySinceFramesTV = 0;
|
|
||||||
} else if (!gInProgressNotificationDisplayedTV) {
|
|
||||||
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the TV already in progress.",
|
|
||||||
AlreadyInProgressCallback,
|
|
||||||
(void *) GX2_SCAN_TARGET_TV)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to display \"Screenshot of the TV already in progress.\" notification");
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Error: %s,", NotificationModule_GetStatusStr(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gInProgressNotificationDisplayedTV = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gImageSource == IMAGE_SOURCE_TV_AND_DRC || gImageSource == IMAGE_SOURCE_DRC) {
|
|
||||||
if (gBlockDRCScreenshots) {
|
|
||||||
DEBUG_FUNCTION_LINE("Screenshots are blocked for DRC because it's not connected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (gTakeScreenshotDRC.state == SCREENSHOT_STATE_READY) {
|
|
||||||
DEBUG_FUNCTION_LINE("Requested screenshot for DRC!");
|
|
||||||
gTakeScreenshotDRC.state = SCREENSHOT_STATE_REQUESTED;
|
|
||||||
gTakeScreenshotDRC.time = time;
|
|
||||||
|
|
||||||
gReadySinceFramesDRC = 0;
|
|
||||||
} else if (!gInProgressNotificationDisplayedDRC) {
|
|
||||||
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the GamePad already in progress.",
|
|
||||||
AlreadyInProgressCallback,
|
|
||||||
(void *) GX2_SCAN_TARGET_DRC)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to display \"Screenshot of the GamePad already in progress.\" notification");
|
|
||||||
DEBUG_FUNCTION_LINE_ERR("Error: %s,", NotificationModule_GetStatusStr(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gInProgressNotificationDisplayedDRC = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OSMemoryBarrier();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t sWasHoldForXFrameGamePad;
|
|
||||||
DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buffer_size, VPADReadError *error) {
|
|
||||||
VPADReadError real_error;
|
|
||||||
int32_t result = real_VPADRead(chan, buffer, buffer_size, &real_error);
|
|
||||||
|
|
||||||
if (gEnabled && gButtonCombo != 0) {
|
|
||||||
if (result > 0 && real_error == VPAD_READ_SUCCESS) {
|
|
||||||
uint32_t end = 1;
|
|
||||||
// Fix games like TP HD
|
|
||||||
if (VPADGetButtonProcMode(chan) == 1) {
|
|
||||||
end = result;
|
|
||||||
}
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < end; i++) {
|
|
||||||
if ((((buffer[i].hold & 0x000FFFFF) & gButtonCombo) == gButtonCombo)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
if (sWasHoldForXFrameGamePad == 0) {
|
|
||||||
RequestScreenshot();
|
|
||||||
}
|
|
||||||
sWasHoldForXFrameGamePad++;
|
|
||||||
} else {
|
|
||||||
sWasHoldForXFrameGamePad = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
*error = real_error;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t sWPADLastButtonHold[4];
|
|
||||||
static uint32_t sWasHoldForXFrame[4];
|
|
||||||
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
|
|
||||||
real_WPADRead(chan, data);
|
|
||||||
|
|
||||||
if (gEnabled && gButtonCombo > 0 && chan >= 0 && chan < 4) {
|
|
||||||
if (data[0].err == 0) {
|
|
||||||
if (data[0].extensionType != 0xFF) {
|
|
||||||
uint32_t curButtonHold = 0;
|
|
||||||
if (data[0].extensionType == WPAD_EXT_CORE || data[0].extensionType == WPAD_EXT_NUNCHUK) {
|
|
||||||
// button data is in the first 2 bytes for wiimotes
|
|
||||||
curButtonHold = remapWiiMoteButtons(((uint16_t *) data)[0]);
|
|
||||||
} else if (data[0].extensionType == WPAD_EXT_CLASSIC) {
|
|
||||||
curButtonHold = remapClassicButtons(((uint32_t *) data)[10] & 0xFFFF);
|
|
||||||
} else if (data[0].extensionType == WPAD_EXT_PRO_CONTROLLER) {
|
|
||||||
curButtonHold = remapProButtons(data[0].buttons);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t curButtonTrigger = (curButtonHold & (~(sWPADLastButtonHold[chan])));
|
|
||||||
|
|
||||||
bool takeScreenshot = false;
|
|
||||||
if (gReservedBitUsage && curButtonTrigger & VPAD_BUTTON_RESERVED_BIT) {
|
|
||||||
takeScreenshot = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!takeScreenshot) {
|
|
||||||
if ((gButtonCombo != 0 && (curButtonHold & gButtonCombo) == gButtonCombo)) {
|
|
||||||
if (sWasHoldForXFrame[chan] == 0) {
|
|
||||||
takeScreenshot = true;
|
|
||||||
}
|
|
||||||
sWasHoldForXFrame[chan]++;
|
|
||||||
} else {
|
|
||||||
sWasHoldForXFrame[chan] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (takeScreenshot) {
|
|
||||||
RequestScreenshot();
|
|
||||||
}
|
|
||||||
|
|
||||||
sWPADLastButtonHold[chan] = curButtonHold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) {
|
DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) {
|
||||||
if (gEnabled) {
|
if (gEnabled) {
|
||||||
if (gCheckIfScreenRendered) {
|
if (gCheckIfScreenRendered) {
|
||||||
@ -251,7 +88,6 @@ DECL_FUNCTION(void, GX2MarkScanBufferCopied, GX2ScanTarget scan_target) {
|
|||||||
real_GX2MarkScanBufferCopied(scan_target);
|
real_GX2MarkScanBufferCopied(scan_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPS_MUST_REPLACE(VPADRead, WUPS_LOADER_LIBRARY_VPAD, VPADRead);
|
|
||||||
struct WUT_PACKED CCRCDCCallbackData {
|
struct WUT_PACKED CCRCDCCallbackData {
|
||||||
uint32_t attached;
|
uint32_t attached;
|
||||||
VPADChan chan;
|
VPADChan chan;
|
||||||
@ -271,5 +107,4 @@ WUPS_MUST_REPLACE(GX2GetCurrentScanBuffer, WUPS_LOADER_LIBRARY_GX2, GX2GetCurren
|
|||||||
WUPS_MUST_REPLACE(GX2CopyColorBufferToScanBuffer, WUPS_LOADER_LIBRARY_GX2, GX2CopyColorBufferToScanBuffer);
|
WUPS_MUST_REPLACE(GX2CopyColorBufferToScanBuffer, WUPS_LOADER_LIBRARY_GX2, GX2CopyColorBufferToScanBuffer);
|
||||||
WUPS_MUST_REPLACE(GX2SetTVBuffer, WUPS_LOADER_LIBRARY_GX2, GX2SetTVBuffer);
|
WUPS_MUST_REPLACE(GX2SetTVBuffer, WUPS_LOADER_LIBRARY_GX2, GX2SetTVBuffer);
|
||||||
WUPS_MUST_REPLACE(GX2SetDRCBuffer, WUPS_LOADER_LIBRARY_GX2, GX2SetDRCBuffer);
|
WUPS_MUST_REPLACE(GX2SetDRCBuffer, WUPS_LOADER_LIBRARY_GX2, GX2SetDRCBuffer);
|
||||||
WUPS_MUST_REPLACE(WPADRead, WUPS_LOADER_LIBRARY_PADSCORE, WPADRead);
|
|
||||||
WUPS_MUST_REPLACE_PHYSICAL(__VPADBASEAttachCallback, (0x31000000 + 0x0200146c - 0x00EE0100), (0x0200146c - 0x00EE0100));
|
WUPS_MUST_REPLACE_PHYSICAL(__VPADBASEAttachCallback, (0x31000000 + 0x0200146c - 0x00EE0100), (0x0200146c - 0x00EE0100));
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "retain_vars.hpp"
|
#include "retain_vars.hpp"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "utils/WUPSConfigItemButtonCombo.h"
|
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
|
|
||||||
#include <notifications/notifications.h>
|
#include <notifications/notifications.h>
|
||||||
#include <string>
|
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// Mandatory plugin information.
|
// Mandatory plugin information.
|
||||||
WUPS_PLUGIN_NAME("Screenshot plugin");
|
WUPS_PLUGIN_NAME("Screenshot plugin");
|
||||||
WUPS_PLUGIN_DESCRIPTION("This plugin allows you to make screenshots that will be saved to the sd card");
|
WUPS_PLUGIN_DESCRIPTION("This plugin allows you to make screenshots that will be saved to the sd card");
|
||||||
@ -22,6 +24,7 @@ WUPS_USE_WUT_DEVOPTAB();
|
|||||||
// Gets called once the loader exists.
|
// Gets called once the loader exists.
|
||||||
INITIALIZE_PLUGIN() {
|
INITIALIZE_PLUGIN() {
|
||||||
initLogging();
|
initLogging();
|
||||||
|
NotificationModule_InitLibrary();
|
||||||
InitConfig();
|
InitConfig();
|
||||||
if (gEnabled) {
|
if (gEnabled) {
|
||||||
InitNotificationModule();
|
InitNotificationModule();
|
||||||
@ -30,6 +33,7 @@ INITIALIZE_PLUGIN() {
|
|||||||
|
|
||||||
DEINITIALIZE_PLUGIN() {
|
DEINITIALIZE_PLUGIN() {
|
||||||
NotificationModule_DeInitLibrary();
|
NotificationModule_DeInitLibrary();
|
||||||
|
gButtonComboInstances.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "retain_vars.hpp"
|
#include "retain_vars.hpp"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||||
@ -33,3 +35,7 @@ bool gCheckIfScreenRendered = false;
|
|||||||
|
|
||||||
uint32_t gReadySinceFramesTV = 0;
|
uint32_t gReadySinceFramesTV = 0;
|
||||||
uint32_t gReadySinceFramesDRC = 0;
|
uint32_t gReadySinceFramesDRC = 0;
|
||||||
|
|
||||||
|
|
||||||
|
WUPSButtonCombo_ComboHandle gButtonComboHandle(nullptr);
|
||||||
|
std::forward_list<WUPSButtonComboAPI::ButtonCombo> gButtonComboInstances;
|
@ -1,9 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <gx2/surface.h>
|
#include <gx2/surface.h>
|
||||||
#include <notifications/notifications.h>
|
|
||||||
|
#include <notifications/notification_defines.h>
|
||||||
|
|
||||||
|
#include <wups/button_combo/WUPSButtonCombo.h>
|
||||||
|
#include <wups/button_combo/defines.h>
|
||||||
|
|
||||||
|
#include <forward_list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace WUPSButtonComboAPI {
|
||||||
|
class ButtonCombo;
|
||||||
|
}
|
||||||
|
|
||||||
extern GX2SurfaceFormat gTVSurfaceFormat;
|
extern GX2SurfaceFormat gTVSurfaceFormat;
|
||||||
extern GX2SurfaceFormat gDRCSurfaceFormat;
|
extern GX2SurfaceFormat gDRCSurfaceFormat;
|
||||||
|
|
||||||
@ -19,7 +30,6 @@ extern std::string gShortNameEn;
|
|||||||
extern ScreenshotStateInfo gTakeScreenshotTV;
|
extern ScreenshotStateInfo gTakeScreenshotTV;
|
||||||
extern ScreenshotStateInfo gTakeScreenshotDRC;
|
extern ScreenshotStateInfo gTakeScreenshotDRC;
|
||||||
|
|
||||||
|
|
||||||
extern bool gInProgressNotificationDisplayedDRC;
|
extern bool gInProgressNotificationDisplayedDRC;
|
||||||
extern bool gInProgressNotificationDisplayedTV;
|
extern bool gInProgressNotificationDisplayedTV;
|
||||||
extern bool gNotAvailableNotificationDisplayed;
|
extern bool gNotAvailableNotificationDisplayed;
|
||||||
@ -36,3 +46,6 @@ extern bool gCheckIfScreenRendered;
|
|||||||
|
|
||||||
extern uint32_t gReadySinceFramesTV;
|
extern uint32_t gReadySinceFramesTV;
|
||||||
extern uint32_t gReadySinceFramesDRC;
|
extern uint32_t gReadySinceFramesDRC;
|
||||||
|
|
||||||
|
extern WUPSButtonCombo_ComboHandle gButtonComboHandle;
|
||||||
|
extern std::forward_list<WUPSButtonComboAPI::ButtonCombo> gButtonComboInstances;
|
||||||
|
@ -4,13 +4,92 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "utils/StringTools.h"
|
#include "utils/StringTools.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include <coreinit/cache.h>
|
|
||||||
#include <gd.h>
|
|
||||||
#include <gx2/event.h>
|
|
||||||
#include <gx2/mem.h>
|
|
||||||
#include <memory/mappedmemory.h>
|
#include <memory/mappedmemory.h>
|
||||||
#include <notifications/notifications.h>
|
#include <notifications/notifications.h>
|
||||||
#include <valarray>
|
|
||||||
|
#include <coreinit/cache.h>
|
||||||
|
#include <gx2/event.h>
|
||||||
|
#include <gx2/mem.h>
|
||||||
|
|
||||||
|
#include <gd.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void AlreadyInProgressCallback(NotificationModuleHandle handle, void *context) {
|
||||||
|
auto scanTarget = (GX2ScanTarget) (uint32_t) context;
|
||||||
|
if (scanTarget == GX2_SCAN_TARGET_TV) {
|
||||||
|
gInProgressNotificationDisplayedTV = false;
|
||||||
|
} else if (scanTarget == GX2_SCAN_TARGET_DRC) {
|
||||||
|
gInProgressNotificationDisplayedDRC = false;
|
||||||
|
}
|
||||||
|
OSMemoryBarrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotAvailableCallback(NotificationModuleHandle handle, void *context) {
|
||||||
|
gNotAvailableNotificationDisplayed = false;
|
||||||
|
OSMemoryBarrier();
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void RequestScreenshot() {
|
||||||
|
NotificationModuleStatus err;
|
||||||
|
if (gBlockScreenshots) {
|
||||||
|
if (!gNotAvailableNotificationDisplayed) {
|
||||||
|
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshots not available at the moment.",
|
||||||
|
NotAvailableCallback,
|
||||||
|
nullptr)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to display \"Screenshots not available at the moment.\" notification");
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Error: %s,", NotificationModule_GetStatusStr(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gNotAvailableNotificationDisplayed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OSCalendarTime time;
|
||||||
|
OSTicksToCalendarTime(OSGetTime(), &time);
|
||||||
|
if (gImageSource == IMAGE_SOURCE_TV_AND_DRC || gImageSource == IMAGE_SOURCE_TV) {
|
||||||
|
if (gTakeScreenshotTV.state == SCREENSHOT_STATE_READY) {
|
||||||
|
DEBUG_FUNCTION_LINE("Requested screenshot for TV!");
|
||||||
|
gTakeScreenshotTV.state = SCREENSHOT_STATE_REQUESTED;
|
||||||
|
gTakeScreenshotTV.time = time;
|
||||||
|
gReadySinceFramesTV = 0;
|
||||||
|
} else if (!gInProgressNotificationDisplayedTV) {
|
||||||
|
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the TV already in progress.",
|
||||||
|
AlreadyInProgressCallback,
|
||||||
|
(void *) GX2_SCAN_TARGET_TV)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to display \"Screenshot of the TV already in progress.\" notification");
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Error: %s,", NotificationModule_GetStatusStr(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gInProgressNotificationDisplayedTV = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gImageSource == IMAGE_SOURCE_TV_AND_DRC || gImageSource == IMAGE_SOURCE_DRC) {
|
||||||
|
if (gBlockDRCScreenshots) {
|
||||||
|
DEBUG_FUNCTION_LINE("Screenshots are blocked for DRC because it's not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (gTakeScreenshotDRC.state == SCREENSHOT_STATE_READY) {
|
||||||
|
DEBUG_FUNCTION_LINE("Requested screenshot for DRC!");
|
||||||
|
gTakeScreenshotDRC.state = SCREENSHOT_STATE_REQUESTED;
|
||||||
|
gTakeScreenshotDRC.time = time;
|
||||||
|
|
||||||
|
gReadySinceFramesDRC = 0;
|
||||||
|
} else if (!gInProgressNotificationDisplayedDRC) {
|
||||||
|
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the GamePad already in progress.",
|
||||||
|
AlreadyInProgressCallback,
|
||||||
|
(void *) GX2_SCAN_TARGET_DRC)) != NOTIFICATION_MODULE_RESULT_SUCCESS) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to display \"Screenshot of the GamePad already in progress.\" notification");
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Error: %s,", NotificationModule_GetStatusStr(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gInProgressNotificationDisplayedDRC = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OSMemoryBarrier();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool saveTextureAsPicture(const std::string &path, uint8_t *sourceBuffer, uint32_t width, uint32_t height, uint32_t pitch, GX2SurfaceFormat format, ImageOutputFormatEnum outputFormat, bool convertRGBtoSRGB, int quality) {
|
bool saveTextureAsPicture(const std::string &path, uint8_t *sourceBuffer, uint32_t width, uint32_t height, uint32_t pitch, GX2SurfaceFormat format, ImageOutputFormatEnum outputFormat, bool convertRGBtoSRGB, int quality) {
|
||||||
if (sourceBuffer == nullptr) {
|
if (sourceBuffer == nullptr) {
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
|
||||||
#include <gx2/surface.h>
|
#include <gx2/surface.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
bool saveTextureAsPicture(const std::string &path, uint8_t *sourceBuffer, uint32_t width, uint32_t height, uint32_t pitch, GX2SurfaceFormat format, ImageOutputFormatEnum outputFormat, bool convertRGBtoSRGB, int quality);
|
bool saveTextureAsPicture(const std::string &path, uint8_t *sourceBuffer, uint32_t width, uint32_t height, uint32_t pitch, GX2SurfaceFormat format, ImageOutputFormatEnum outputFormat, bool convertRGBtoSRGB, int quality);
|
||||||
|
|
||||||
bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2SurfaceFormat outputBufferSurfaceFormat, ImageOutputFormatEnum outputFormat, int quality, const OSCalendarTime &time);
|
bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2SurfaceFormat outputBufferSurfaceFormat, ImageOutputFormatEnum outputFormat, int quality, const OSCalendarTime &time);
|
||||||
|
|
||||||
|
void RequestScreenshot();
|
||||||
|
void InitDRCAttachCallbacks();
|
@ -4,11 +4,14 @@
|
|||||||
#include "screenshot_utils.h"
|
#include "screenshot_utils.h"
|
||||||
#include "utils/StringTools.h"
|
#include "utils/StringTools.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
#include <memory/mappedmemory.h>
|
||||||
|
|
||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <coreinit/title.h>
|
#include <coreinit/title.h>
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <memory/mappedmemory.h>
|
|
||||||
|
|
||||||
FSIOThreadData gThreadData;
|
FSIOThreadData gThreadData;
|
||||||
bool gThreadsRunning;
|
bool gThreadsRunning;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include "notifications/notifications.h"
|
#include "notifications/notifications.h"
|
||||||
|
|
||||||
#include <coreinit/messagequeue.h>
|
#include <coreinit/messagequeue.h>
|
||||||
#include <coreinit/semaphore.h>
|
#include <coreinit/semaphore.h>
|
||||||
#include <coreinit/thread.h>
|
#include <coreinit/thread.h>
|
||||||
#include <gx2/enum.h>
|
#include <gx2/enum.h>
|
||||||
#include <memory.h>
|
|
||||||
|
|
||||||
struct FSIOThreadData {
|
struct FSIOThreadData {
|
||||||
OSThread *thread;
|
OSThread *thread;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
std::string string_format(const std::string &format, Args... args) {
|
std::string string_format(const std::string &format, Args... args) {
|
||||||
@ -11,4 +10,4 @@ std::string string_format(const std::string &format, Args... args) {
|
|||||||
auto buf = std::make_unique<char[]>(size);
|
auto buf = std::make_unique<char[]>(size);
|
||||||
std::snprintf(buf.get(), size, format.c_str(), args...);
|
std::snprintf(buf.get(), size, format.c_str(), args...);
|
||||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||||
}
|
}
|
@ -1,298 +0,0 @@
|
|||||||
#include "WUPSConfigItemButtonCombo.h"
|
|
||||||
#include "utils/input.h"
|
|
||||||
#include <coreinit/debug.h>
|
|
||||||
#include <coreinit/thread.h>
|
|
||||||
#include <coreinit/time.h>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
#include <vpad/input.h>
|
|
||||||
#include <wups.h>
|
|
||||||
|
|
||||||
static 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 "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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<VPADButtons>(bitMask));
|
|
||||||
if (val[0] != '\0') {
|
|
||||||
strcat(comboString, val);
|
|
||||||
strcat(comboString, "+");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string res(comboString);
|
|
||||||
if (res.ends_with("+")) {
|
|
||||||
res.pop_back();
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WUPSConfigItemButtonCombo_onCloseCallback(void *context) {
|
|
||||||
auto *item = (ConfigItemButtonCombo *) context;
|
|
||||||
if (item->valueAtCreation != item->value && item->valueChangedCallback != nullptr) {
|
|
||||||
((ButtonComboValueChangedCallback) (item->valueChangedCallback))(item, item->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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 = {};
|
|
||||||
if (VPADRead(VPAD_CHAN_0, &vpad_data, 1, &vpad_error) > 0 && 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WUPSConfigItemButtonCombo_onInput(void *context, WUPSConfigSimplePadData input) {
|
|
||||||
auto *item = (ConfigItemButtonCombo *) context;
|
|
||||||
if (item->state == BUTTON_COMBO_STATE_NONE) {
|
|
||||||
if ((input.buttons_d & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) {
|
|
||||||
item->state = BUTTON_COMBO_STATE_PREPARE_FOR_HOLD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
item->state = BUTTON_COMBO_STATE_WAIT_FOR_HOLD;
|
|
||||||
snprintf(out_buf, out_size, "<Hold new combo for %dms; hold %s to abort>", 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WUPSConfigItemButtonCombo_restoreDefault(void *context) {
|
|
||||||
auto *item = (ConfigItemButtonCombo *) context;
|
|
||||||
item->value = item->defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WUPSConfigItemButtonCombo_Cleanup(ConfigItemButtonCombo *item) {
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
free((void *) item->identifier);
|
|
||||||
free(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (identifier != nullptr) {
|
|
||||||
item->identifier = strdup(identifier);
|
|
||||||
} else {
|
|
||||||
item->identifier = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
item->abortButton = abortButton;
|
|
||||||
item->abortButtonHoldDurationInMs = abortButtonHoldDurationInMs;
|
|
||||||
item->holdDurationInMs = holdDurationInMs;
|
|
||||||
item->defaultValue = defaultComboInVPADButtons;
|
|
||||||
item->value = currentComboInVPADButtons;
|
|
||||||
item->valueAtCreation = currentComboInVPADButtons;
|
|
||||||
item->valueChangedCallback = (void *) callback;
|
|
||||||
item->state = BUTTON_COMBO_STATE_NONE;
|
|
||||||
|
|
||||||
WUPSConfigAPIItemCallbacksV2 callbacks = {
|
|
||||||
.getCurrentValueDisplay = &WUPSConfigItemButtonCombo_getCurrentValueDisplay,
|
|
||||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemButtonCombo_getCurrentValueSelectedDisplay,
|
|
||||||
.onSelected = nullptr,
|
|
||||||
.restoreDefault = &WUPSConfigItemButtonCombo_restoreDefault,
|
|
||||||
.isMovementAllowed = nullptr,
|
|
||||||
.onCloseCallback = &WUPSConfigItemButtonCombo_onCloseCallback,
|
|
||||||
.onInput = &WUPSConfigItemButtonCombo_onInput,
|
|
||||||
.onInputEx = nullptr,
|
|
||||||
.onDelete = &WUPSConfigItemButtonCombo_onDelete,
|
|
||||||
};
|
|
||||||
|
|
||||||
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");
|
|
||||||
WUPSConfigItemButtonCombo_Cleanup(item);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
*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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 *displayName, uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons, ButtonComboValueChangedCallback callback) {
|
|
||||||
return WUPSConfigItemButtonComboAddToCategoryEx(cat, displayName, defaultComboInVPADButtons, currentComboInVPADButtons, 2000, VPAD_BUTTON_B, 250, callback);
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include <vpad/input.h>
|
|
||||||
#include <wups.h>
|
|
||||||
|
|
||||||
#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 {
|
|
||||||
const char *identifier;
|
|
||||||
WUPSConfigItemHandle handle;
|
|
||||||
uint32_t defaultValue;
|
|
||||||
uint32_t value;
|
|
||||||
uint32_t valueAtCreation;
|
|
||||||
uint32_t holdDurationInMs;
|
|
||||||
VPADButtons abortButton;
|
|
||||||
uint32_t abortButtonHoldDurationInMs;
|
|
||||||
ButtonComboState state;
|
|
||||||
void *valueChangedCallback;
|
|
||||||
} ConfigItemButtonCombo;
|
|
||||||
|
|
||||||
typedef void (*ButtonComboValueChangedCallback)(ConfigItemButtonCombo *item, uint32_t buttonComboInVPADButtons);
|
|
||||||
|
|
||||||
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 WUPSConfigItemButtonComboAddToCategory(WUPSConfigCategoryHandle cat,
|
|
||||||
const char *displayName,
|
|
||||||
uint32_t defaultComboInVPADButtons, uint32_t currentComboInVPADButtons,
|
|
||||||
ButtonComboValueChangedCallback callback);
|
|
||||||
|
|
||||||
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
|
|
@ -1,52 +0,0 @@
|
|||||||
#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);
|
|
||||||
}
|
|
@ -1,5 +1,8 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
|
#include <padscore/wpad.h>
|
||||||
|
#include <vpad/input.h>
|
||||||
|
|
||||||
uint32_t remapWiiMoteButtons(uint32_t buttons) {
|
uint32_t remapWiiMoteButtons(uint32_t buttons) {
|
||||||
uint32_t conv_buttons = 0;
|
uint32_t conv_buttons = 0;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <padscore/kpad.h>
|
|
||||||
#include <vpad/input.h>
|
|
||||||
|
|
||||||
#define VPAD_BUTTON_RESERVED_BIT 0x80000
|
#define VPAD_BUTTON_RESERVED_BIT 0x80000
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS)
|
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS)
|
||||||
#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##WARN ## ", "\n", FMT, ##ARGS)
|
#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##WARN ## ", "\n", FMT, ##ARGS)
|
||||||
|
#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##INFO ## ", "\n", FMT, ##ARGS)
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, OSReport, "##ERROR## ", "\n", FMT, ##ARGS);
|
#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, OSReport, "##ERROR## ", "\n", FMT, ##ARGS);
|
||||||
|
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "retain_vars.hpp"
|
#include "retain_vars.hpp"
|
||||||
|
|
||||||
|
#include <wups/storage.h>
|
||||||
|
|
||||||
#include <coreinit/title.h>
|
#include <coreinit/title.h>
|
||||||
#include <malloc.h>
|
|
||||||
#include <nn/acp/client.h>
|
#include <nn/acp/client.h>
|
||||||
#include <nn/acp/title.h>
|
#include <nn/acp/title.h>
|
||||||
#include <wups/storage.h>
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <notifications/notifications.h>
|
||||||
|
|
||||||
uint8_t RGBComponentToSRGBTable[] = {0x00, 0x0C, 0x15, 0x1C, 0x21, 0x26, 0x2A, 0x2E, 0x31, 0x34, 0x37, 0x3A, 0x3D, 0x3F, 0x42, 0x44,
|
uint8_t RGBComponentToSRGBTable[] = {0x00, 0x0C, 0x15, 0x1C, 0x21, 0x26, 0x2A, 0x2E, 0x31, 0x34, 0x37, 0x3A, 0x3D, 0x3F, 0x42, 0x44,
|
||||||
0x46, 0x49, 0x4B, 0x4D, 0x4F, 0x51, 0x52, 0x54, 0x56, 0x58, 0x59, 0x5B, 0x5D, 0x5E, 0x60, 0x61,
|
0x46, 0x49, 0x4B, 0x4D, 0x4F, 0x51, 0x52, 0x54, 0x56, 0x58, 0x59, 0x5B, 0x5D, 0x5E, 0x60, 0x61,
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
extern uint8_t SRGBComponentToRGBTable[];
|
extern uint8_t SRGBComponentToRGBTable[];
|
||||||
extern uint8_t RGBComponentToSRGBTable[];
|
extern uint8_t RGBComponentToSRGBTable[];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user