Skip to content

Commit

Permalink
Add support for mirroring the TV/DRC
Browse files Browse the repository at this point in the history
  • Loading branch information
Maschell committed Mar 4, 2024
1 parent 6cd7e25 commit 4b52598
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 29 deletions.
66 changes: 56 additions & 10 deletions src/function_patcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,36 @@
void UpdateAudioMode();

DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) {
if (gEnabled && gDoScreenSwap) {
if (scan_target == GX2_SCAN_TARGET_TV) {
scan_target = GX2_SCAN_TARGET_DRC;
} else if (scan_target == GX2_SCAN_TARGET_DRC) {
scan_target = GX2_SCAN_TARGET_TV;
if (gEnabled && gCurScreenMode != SCREEN_MODE_NONE) {
switch (gCurScreenMode) {
case SCREEN_MODE_SWAP: {
if (scan_target == GX2_SCAN_TARGET_TV) {
scan_target = GX2_SCAN_TARGET_DRC;
} else if (scan_target == GX2_SCAN_TARGET_DRC) {
scan_target = GX2_SCAN_TARGET_TV;
}
break;
}
case SCREEN_MODE_MIRROR_TV: {
if (scan_target == GX2_SCAN_TARGET_TV) {
scan_target = GX2_SCAN_TARGET_TV | GX2_SCAN_TARGET_DRC;
} else if (scan_target == GX2_SCAN_TARGET_DRC) {
return;
}
break;
}
case SCREEN_MODE_MIRROR_DRC: {
if (scan_target == GX2_SCAN_TARGET_DRC) {
scan_target = GX2_SCAN_TARGET_TV | GX2_SCAN_TARGET_DRC;
} else if (scan_target == GX2_SCAN_TARGET_TV) {
return;
}
break;
}
default:
break;
}

if (colorBuffer->surface.aa != GX2_AA_MODE1X) {
// If AA is enabled, we need to resolve the AA buffer.
GX2Surface tempSurface;
Expand Down Expand Up @@ -66,10 +90,14 @@ DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer *colorBuffer,
}

void SwapScreens() {
gDoScreenSwap = !gDoScreenSwap;
if (gCurScreenMode == SCREEN_MODE_SWAP) {
gCurScreenMode = SCREEN_MODE_NONE;
} else {
gCurScreenMode = SCREEN_MODE_SWAP;
}

if (gShowNotifications && gNotificationModuleInitDone) {
if (gDoScreenSwap) {
if (gCurScreenMode) {
NotificationModule_AddInfoNotification("Swapping TV and GamePad screen");
} else {
NotificationModule_AddInfoNotification("Stop swapping TV and GamePad screen");
Expand Down Expand Up @@ -188,9 +216,27 @@ void DoAudioMagic(int16_t *addr, uint32_t size, bool isDRC, AIInitDMAfn targetFu
otherFunc(addr, sizeCpy);
return;
case AUDIO_MODE_MATCH_SCREEN: {
if (gDoScreenSwap) {
otherFunc(addr, sizeCpy);
return;
switch (gCurScreenMode) {
case SCREEN_MODE_SWAP:
otherFunc(addr, sizeCpy);
return;
case SCREEN_MODE_MIRROR_TV:
case SCREEN_MODE_MIRROR_DRC: {
if (isDRC) {
memcpy(DRCCopy, addr, sizeCpy);
} else {
memcpy(TVCopy, addr, sizeCpy);
}
if (gCurScreenMode == SCREEN_MODE_MIRROR_TV) {
memcpy(addr, TVCopy, sizeCpy);
} else if (gCurScreenMode == SCREEN_MODE_MIRROR_DRC) {
memcpy(addr, DRCCopy, sizeCpy);
}
break;
}
case SCREEN_MODE_NONE:
case SCREEN_MODE_MAX_VALUE:
break;
}
break;
}
Expand Down
33 changes: 25 additions & 8 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ WUPS_USE_WUT_DEVOPTAB();

WUPS_USE_STORAGE("SwipSwapMeAroma");

void migrateStorage() {
uint32_t doSwap = false;
if (WUPSStorageAPI_GetU32(nullptr, SWAP_SCREENS_CONFIG_STRING_DEPRECATED, &doSwap) == WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_INFO("Found deprecated config in storage. Storage will be migrated");
if (doSwap) {
gCurScreenMode = SCREEN_MODE_SWAP;
}
if (WUPSStorageAPI_DeleteItem(nullptr, SWAP_SCREENS_CONFIG_STRING_DEPRECATED) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_WARN("Failed to delete deprecated value: \"%s\" from storage", SWAP_SCREENS_CONFIG_STRING_DEPRECATED);
}
}
}

// Gets called once the loader exists.
INITIALIZE_PLUGIN() {
initLogging();
Expand All @@ -45,12 +58,15 @@ INITIALIZE_PLUGIN() {
DEBUG_FUNCTION_LINE_ERR("Failed to init notification lib");
}

gCurScreenMode = DEFAULT_SCREEN_MODE_CONFIG_VALUE; // migrateStorage might override this
migrateStorage();

WUPSStorageError err;
if ((err = WUPSStorageAPI::GetOrStoreDefault(ENABLED_CONFIG_STRING, gEnabled, DEFAULT_ENABLED_CONFIG_VALUE)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s (%d)", ENABLED_CONFIG_STRING, WUPSStorageAPI_GetStatusStr(err), err);
}
if ((err = WUPSStorageAPI::GetOrStoreDefault(SWAP_SCREENS_CONFIG_STRING, gDoScreenSwap, DEFAULT_SWAP_SCREENS_CONFIG_VALUE)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s (%d)", SWAP_SCREENS_CONFIG_STRING, WUPSStorageAPI_GetStatusStr(err), err);
if ((err = WUPSStorageAPI::GetOrStoreDefault(SCREEN_MODE_CONFIG_STRING, gCurScreenMode, gCurScreenMode)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s (%d)", SCREEN_MODE_CONFIG_STRING, WUPSStorageAPI_GetStatusStr(err), err);
}
if ((err = WUPSStorageAPI::GetOrStoreDefault(ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING, gSwapScreenButtonComboEnabled, DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s (%d)", ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING, WUPSStorageAPI_GetStatusStr(err), err);
Expand Down Expand Up @@ -91,24 +107,25 @@ DEINITIALIZE_PLUGIN() {
}
}

SwipSwapAudioMode sAudioModeAtStart;
bool sDoSwapAtStart;
static SwipSwapAudioMode sAudioModeAtStart;
static SwipSwapScreenMode sScreenModeAtStart;

// Called whenever an application was started.
ON_APPLICATION_START() {
initLogging();
sAudioModeAtStart = gCurAudioMode;
sDoSwapAtStart = gDoScreenSwap;

sAudioModeAtStart = gCurAudioMode;
sScreenModeAtStart = gCurScreenMode;
}

ON_APPLICATION_REQUESTS_EXIT() {
if (sAudioModeAtStart != gCurAudioMode || sDoSwapAtStart != gDoScreenSwap) {
if (sAudioModeAtStart != gCurAudioMode || sScreenModeAtStart != gCurScreenMode) {
WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(AUDIO_MODE_CONFIG_STRING, gCurAudioMode)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store audio mode to storage: %s (%d)", WUPSStorageAPI_GetStatusStr(err), err);
}

if ((err = WUPSStorageAPI::Store(SWAP_SCREENS_CONFIG_STRING, gDoScreenSwap)) != WUPS_STORAGE_ERROR_SUCCESS) {
if ((err = WUPSStorageAPI::Store(SCREEN_MODE_CONFIG_STRING, gCurScreenMode)) != WUPS_STORAGE_ERROR_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to store screen mode to storage: %s (%d)", WUPSStorageAPI_GetStatusStr(err), err);
}
if ((err = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) {
Expand Down
5 changes: 3 additions & 2 deletions src/retain_vars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
#include "utils/config.h"

bool gEnabled = DEFAULT_ENABLED_CONFIG_VALUE;
bool gDoScreenSwap = DEFAULT_SWAP_SCREENS_CONFIG_VALUE;
uint32_t gSwapScreenButtonCombo = DEFAULT_SWAP_SCREEN_BUTTON_COMBO_CONFIG_VALUE;
uint32_t gSwapAudioButtonCombo = DEFAULT_CHANGE_AUDIO_BUTTON_COMBO_CONFIG_VALUE;
bool gSwapScreenButtonComboEnabled = DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE;
bool gChangeAudioModeButtonComboEnabled = DEFAULT_ENABLED_CHANGE_AUDIO_COMBO_CONFIG_VALUE;
bool gShowNotifications = DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE;
SwipSwapAudioMode gCurAudioMode = DEFAULT_AUDIO_MODE_CONFIG_VALUE;

SwipSwapScreenMode gCurScreenMode = DEFAULT_SCREEN_MODE_CONFIG_VALUE;
SwipSwapAudioMode gCurAudioMode = DEFAULT_AUDIO_MODE_CONFIG_VALUE;

bool gNotificationModuleInitDone = true;
11 changes: 10 additions & 1 deletion src/retain_vars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,21 @@ typedef enum SwipSwapAudioMode {
AUDIO_MODE_MAX_VALUE = 5
} SwipSwapAudioMode;

typedef enum SwipSwapScreenMode {
SCREEN_MODE_NONE = 0,
SCREEN_MODE_SWAP = 1,
SCREEN_MODE_MIRROR_TV = 2,
SCREEN_MODE_MIRROR_DRC = 3,
SCREEN_MODE_MAX_VALUE = 4
} SwipSwapScreenMode;

extern uint32_t gSwapScreenButtonCombo;
extern uint32_t gSwapAudioButtonCombo;
extern bool gSwapScreenButtonComboEnabled;
extern bool gChangeAudioModeButtonComboEnabled;
extern bool gEnabled;
extern bool gDoScreenSwap;
extern bool gShowNotifications;
extern bool gNotificationModuleInitDone;

extern SwipSwapScreenMode gCurScreenMode;
extern SwipSwapAudioMode gCurAudioMode;
22 changes: 16 additions & 6 deletions src/utils/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ static void boolItemChangedConfig(ConfigItemBoolean *item, bool newValue) {
if (std::string_view(ENABLED_CONFIG_STRING) == item->identifier) {
gEnabled = newValue;
UpdateAudioMode();
} else if (std::string_view(SWAP_SCREENS_CONFIG_STRING) == item->identifier) {
gDoScreenSwap = newValue;
} else if (std::string_view(ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING) == item->identifier) {
gSwapScreenButtonComboEnabled = newValue;
} else if (std::string_view(ENABLED_CHANGE_AUDIO_COMBO_CONFIG_STRING) == item->identifier) {
Expand Down Expand Up @@ -63,6 +61,8 @@ static void multiItemChanged(ConfigItemMultipleValues *item, uint32_t newValue)

if (std::string_view(AUDIO_MODE_CONFIG_STRING) == item->identifier) {
gCurAudioMode = static_cast<SwipSwapAudioMode>(newValue);
} else if (std::string_view(SCREEN_MODE_CONFIG_STRING) == item->identifier) {
gCurScreenMode = static_cast<SwipSwapScreenMode>(newValue);
} else {
DEBUG_FUNCTION_LINE_WARN("Unexpected button combo item: %s", item->identifier);
return;
Expand All @@ -86,10 +86,20 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro
"Show notifications",
DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE, gShowNotifications,
&boolItemChangedConfig));
root.add(WUPSConfigItemBoolean::Create(SWAP_SCREENS_CONFIG_STRING,
"Swap screens",
DEFAULT_SWAP_SCREENS_CONFIG_VALUE, gDoScreenSwap,
&boolItemChangedConfig));


constexpr WUPSConfigItemMultipleValues::ValuePair screenModeMap[] = {
{SCREEN_MODE_NONE, "None"},
{SCREEN_MODE_SWAP, "Swap TV and GamePad"},
{SCREEN_MODE_MIRROR_TV, "Mirror TV"},
{SCREEN_MODE_MIRROR_DRC, "Mirror DRC"},
};

root.add(WUPSConfigItemMultipleValues::CreateFromValue(SCREEN_MODE_CONFIG_STRING,
"Screen mode:",
DEFAULT_SCREEN_MODE_CONFIG_VALUE, gCurScreenMode,
screenModeMap,
&multiItemChanged));

constexpr WUPSConfigItemMultipleValues::ValuePair audioModeMap[] = {
{AUDIO_MODE_NONE, "Normal"},
Expand Down
6 changes: 4 additions & 2 deletions src/utils/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@
#include <wups/storage.h>

#define DEFAULT_ENABLED_CONFIG_VALUE true
#define DEFAULT_SWAP_SCREENS_CONFIG_VALUE false
#define DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE true
#define DEFAULT_ENABLED_CHANGE_AUDIO_COMBO_CONFIG_VALUE false
#define DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE true
#define DEFAULT_SWAP_SCREEN_BUTTON_COMBO_CONFIG_VALUE VPAD_BUTTON_TV
#define DEFAULT_CHANGE_AUDIO_BUTTON_COMBO_CONFIG_VALUE VPAD_BUTTON_STICK_L

#define DEFAULT_SCREEN_MODE_CONFIG_VALUE SCREEN_MODE_NONE
#define DEFAULT_AUDIO_MODE_CONFIG_VALUE AUDIO_MODE_MATCH_SCREEN

#define ENABLED_CONFIG_STRING "enabled"
#define SWAP_SCREENS_CONFIG_STRING "swapScreens"
#define SWAP_SCREENS_CONFIG_STRING_DEPRECATED "swapScreens"
#define SCREEN_MODE_CONFIG_STRING "screenMode"
#define ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING "swapScreensComboEnabled"
#define ENABLED_CHANGE_AUDIO_COMBO_CONFIG_STRING "changeAudioComboEnabled"
#define ENABLE_NOTIFICATIONS_CONFIG_STRING "notificationsEnabled"
Expand Down
2 changes: 2 additions & 0 deletions src/utils/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extern "C" {

#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS)
#define DEBUG_FUNCTION_LINE_WARN(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "##WARN ## ", "", FMT, ##ARGS)
#define DEBUG_FUNCTION_LINE_INFO(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "##INFO ## ", "", FMT, ##ARGS)

#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS);

Expand All @@ -54,6 +55,7 @@ extern "C" {

#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_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);

Expand Down

0 comments on commit 4b52598

Please sign in to comment.