Add support for mirroring the TV/DRC

This commit is contained in:
Maschell 2024-03-03 18:04:14 +01:00
parent b8e96e8ae1
commit 74056b1481
7 changed files with 117 additions and 30 deletions

View File

@ -29,12 +29,36 @@
void UpdateAudioMode(); void UpdateAudioMode();
DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) { DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) {
if (gEnabled && gDoScreenSwap) { if (gEnabled && gCurScreenMode != SCREEN_MODE_NONE) {
if (scan_target == GX2_SCAN_TARGET_TV) { switch (gCurScreenMode) {
scan_target = GX2_SCAN_TARGET_DRC; case SCREEN_MODE_SWAP: {
} else if (scan_target == GX2_SCAN_TARGET_DRC) { if (scan_target == GX2_SCAN_TARGET_TV) {
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 (colorBuffer->surface.aa != GX2_AA_MODE1X) {
// If AA is enabled, we need to resolve the AA buffer. // If AA is enabled, we need to resolve the AA buffer.
GX2Surface tempSurface; GX2Surface tempSurface;
@ -66,10 +90,14 @@ DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer *colorBuffer,
} }
void SwapScreens() { void SwapScreens() {
gDoScreenSwap = !gDoScreenSwap; if (gCurScreenMode == SCREEN_MODE_SWAP) {
gCurScreenMode = SCREEN_MODE_NONE;
} else {
gCurScreenMode = SCREEN_MODE_SWAP;
}
if (gShowNotifications && gNotificationModuleInitDone) { if (gShowNotifications && gNotificationModuleInitDone) {
if (gDoScreenSwap) { if (gCurScreenMode) {
NotificationModule_AddInfoNotification("Swapping TV and GamePad screen"); NotificationModule_AddInfoNotification("Swapping TV and GamePad screen");
} else { } else {
NotificationModule_AddInfoNotification("Stop swapping TV and GamePad screen"); NotificationModule_AddInfoNotification("Stop swapping TV and GamePad screen");
@ -188,9 +216,27 @@ void DoAudioMagic(int16_t *addr, uint32_t size, bool isDRC, AIInitDMAfn targetFu
otherFunc(addr, sizeCpy); otherFunc(addr, sizeCpy);
return; return;
case AUDIO_MODE_MATCH_SCREEN: { case AUDIO_MODE_MATCH_SCREEN: {
if (gDoScreenSwap) { switch (gCurScreenMode) {
otherFunc(addr, sizeCpy); case SCREEN_MODE_SWAP:
return; 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; break;
} }

View File

@ -34,6 +34,19 @@ WUPS_USE_WUT_DEVOPTAB();
WUPS_USE_STORAGE("SwipSwapMeAroma"); 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. // Gets called once the loader exists.
INITIALIZE_PLUGIN() { INITIALIZE_PLUGIN() {
initLogging(); initLogging();
@ -45,12 +58,15 @@ INITIALIZE_PLUGIN() {
DEBUG_FUNCTION_LINE_ERR("Failed to init notification lib"); DEBUG_FUNCTION_LINE_ERR("Failed to init notification lib");
} }
gCurScreenMode = DEFAULT_SCREEN_MODE_CONFIG_VALUE; // migrateStorage might override this
migrateStorage();
WUPSStorageError err; WUPSStorageError err;
if ((err = WUPSStorageAPI::GetOrStoreDefault(ENABLED_CONFIG_STRING, gEnabled, DEFAULT_ENABLED_CONFIG_VALUE)) != WUPS_STORAGE_ERROR_SUCCESS) { 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); 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) { 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)", SWAP_SCREENS_CONFIG_STRING, WUPSStorageAPI_GetStatusStr(err), err); 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) { 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); DEBUG_FUNCTION_LINE_ERR("Failed to get or create item \"%s\": %s (%d)", ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING, WUPSStorageAPI_GetStatusStr(err), err);
@ -91,24 +107,25 @@ DEINITIALIZE_PLUGIN() {
} }
} }
SwipSwapAudioMode sAudioModeAtStart; static SwipSwapAudioMode sAudioModeAtStart;
bool sDoSwapAtStart; static SwipSwapScreenMode sScreenModeAtStart;
// Called whenever an application was started. // Called whenever an application was started.
ON_APPLICATION_START() { ON_APPLICATION_START() {
initLogging(); initLogging();
sAudioModeAtStart = gCurAudioMode;
sDoSwapAtStart = gDoScreenSwap; sAudioModeAtStart = gCurAudioMode;
sScreenModeAtStart = gCurScreenMode;
} }
ON_APPLICATION_REQUESTS_EXIT() { ON_APPLICATION_REQUESTS_EXIT() {
if (sAudioModeAtStart != gCurAudioMode || sDoSwapAtStart != gDoScreenSwap) { if (sAudioModeAtStart != gCurAudioMode || sScreenModeAtStart != gCurScreenMode) {
WUPSStorageError err; WUPSStorageError err;
if ((err = WUPSStorageAPI::Store(AUDIO_MODE_CONFIG_STRING, gCurAudioMode)) != WUPS_STORAGE_ERROR_SUCCESS) { 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); 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); 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) { if ((err = WUPSStorageAPI::SaveStorage()) != WUPS_STORAGE_ERROR_SUCCESS) {

View File

@ -2,12 +2,13 @@
#include "utils/config.h" #include "utils/config.h"
bool gEnabled = DEFAULT_ENABLED_CONFIG_VALUE; 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 gSwapScreenButtonCombo = DEFAULT_SWAP_SCREEN_BUTTON_COMBO_CONFIG_VALUE;
uint32_t gSwapAudioButtonCombo = DEFAULT_CHANGE_AUDIO_BUTTON_COMBO_CONFIG_VALUE; uint32_t gSwapAudioButtonCombo = DEFAULT_CHANGE_AUDIO_BUTTON_COMBO_CONFIG_VALUE;
bool gSwapScreenButtonComboEnabled = DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE; bool gSwapScreenButtonComboEnabled = DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE;
bool gChangeAudioModeButtonComboEnabled = DEFAULT_ENABLED_CHANGE_AUDIO_COMBO_CONFIG_VALUE; bool gChangeAudioModeButtonComboEnabled = DEFAULT_ENABLED_CHANGE_AUDIO_COMBO_CONFIG_VALUE;
bool gShowNotifications = DEFAULT_ENABLE_NOTIFICATIONS_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; bool gNotificationModuleInitDone = true;

View File

@ -11,12 +11,21 @@ typedef enum SwipSwapAudioMode {
AUDIO_MODE_MAX_VALUE = 5 AUDIO_MODE_MAX_VALUE = 5
} SwipSwapAudioMode; } 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 gSwapScreenButtonCombo;
extern uint32_t gSwapAudioButtonCombo; extern uint32_t gSwapAudioButtonCombo;
extern bool gSwapScreenButtonComboEnabled; extern bool gSwapScreenButtonComboEnabled;
extern bool gChangeAudioModeButtonComboEnabled; extern bool gChangeAudioModeButtonComboEnabled;
extern bool gEnabled; extern bool gEnabled;
extern bool gDoScreenSwap;
extern bool gShowNotifications; extern bool gShowNotifications;
extern bool gNotificationModuleInitDone; extern bool gNotificationModuleInitDone;
extern SwipSwapScreenMode gCurScreenMode;
extern SwipSwapAudioMode gCurAudioMode; extern SwipSwapAudioMode gCurAudioMode;

View File

@ -15,8 +15,6 @@ static void boolItemChangedConfig(ConfigItemBoolean *item, bool newValue) {
if (std::string_view(ENABLED_CONFIG_STRING) == item->identifier) { if (std::string_view(ENABLED_CONFIG_STRING) == item->identifier) {
gEnabled = newValue; gEnabled = newValue;
UpdateAudioMode(); 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) { } else if (std::string_view(ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING) == item->identifier) {
gSwapScreenButtonComboEnabled = newValue; gSwapScreenButtonComboEnabled = newValue;
} else if (std::string_view(ENABLED_CHANGE_AUDIO_COMBO_CONFIG_STRING) == item->identifier) { } else if (std::string_view(ENABLED_CHANGE_AUDIO_COMBO_CONFIG_STRING) == item->identifier) {
@ -63,6 +61,8 @@ static void multiItemChanged(ConfigItemMultipleValues *item, uint32_t newValue)
if (std::string_view(AUDIO_MODE_CONFIG_STRING) == item->identifier) { if (std::string_view(AUDIO_MODE_CONFIG_STRING) == item->identifier) {
gCurAudioMode = static_cast<SwipSwapAudioMode>(newValue); gCurAudioMode = static_cast<SwipSwapAudioMode>(newValue);
} else if (std::string_view(SCREEN_MODE_CONFIG_STRING) == item->identifier) {
gCurScreenMode = static_cast<SwipSwapScreenMode>(newValue);
} else { } else {
DEBUG_FUNCTION_LINE_WARN("Unexpected button combo item: %s", item->identifier); DEBUG_FUNCTION_LINE_WARN("Unexpected button combo item: %s", item->identifier);
return; return;
@ -86,10 +86,20 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro
"Show notifications", "Show notifications",
DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE, gShowNotifications, DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE, gShowNotifications,
&boolItemChangedConfig)); &boolItemChangedConfig));
root.add(WUPSConfigItemBoolean::Create(SWAP_SCREENS_CONFIG_STRING,
"Swap screens",
DEFAULT_SWAP_SCREENS_CONFIG_VALUE, gDoScreenSwap, constexpr WUPSConfigItemMultipleValues::ValuePair screenModeMap[] = {
&boolItemChangedConfig)); {SCREEN_MODE_NONE, "Normal"},
{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[] = { constexpr WUPSConfigItemMultipleValues::ValuePair audioModeMap[] = {
{AUDIO_MODE_NONE, "Normal"}, {AUDIO_MODE_NONE, "Normal"},
@ -107,7 +117,7 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro
auto buttonCombos = WUPSConfigCategory::Create("Button Combos"); auto buttonCombos = WUPSConfigCategory::Create("Button Combos");
buttonCombos.add(WUPSConfigItemBoolean::Create(ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING, buttonCombos.add(WUPSConfigItemBoolean::Create(ENABLED_SWAP_SCREENS_COMBO_CONFIG_STRING,
"Enable swap screen button combo", "Enable change swap screen button combo",
DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE, gSwapScreenButtonComboEnabled, DEFAULT_ENABLED_SWAP_SCREENS_COMBO_CONFIG_VALUE, gSwapScreenButtonComboEnabled,
&boolItemChangedConfig)); &boolItemChangedConfig));

View File

@ -7,16 +7,18 @@
#include <wups/storage.h> #include <wups/storage.h>
#define DEFAULT_ENABLED_CONFIG_VALUE true #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_SWAP_SCREENS_COMBO_CONFIG_VALUE true
#define DEFAULT_ENABLED_CHANGE_AUDIO_COMBO_CONFIG_VALUE false #define DEFAULT_ENABLED_CHANGE_AUDIO_COMBO_CONFIG_VALUE false
#define DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE true #define DEFAULT_ENABLE_NOTIFICATIONS_CONFIG_VALUE true
#define DEFAULT_SWAP_SCREEN_BUTTON_COMBO_CONFIG_VALUE VPAD_BUTTON_TV #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_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 DEFAULT_AUDIO_MODE_CONFIG_VALUE AUDIO_MODE_MATCH_SCREEN
#define ENABLED_CONFIG_STRING "enabled" #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_SWAP_SCREENS_COMBO_CONFIG_STRING "swapScreensComboEnabled"
#define ENABLED_CHANGE_AUDIO_COMBO_CONFIG_STRING "changeAudioComboEnabled" #define ENABLED_CHANGE_AUDIO_COMBO_CONFIG_STRING "changeAudioComboEnabled"
#define ENABLE_NOTIFICATIONS_CONFIG_STRING "notificationsEnabled" #define ENABLE_NOTIFICATIONS_CONFIG_STRING "notificationsEnabled"

View File

@ -39,6 +39,7 @@ extern "C" {
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS) #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_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); #define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS);
@ -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_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);