From 777b43b28524a025a90618e5f76d6b49a701b84d Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Tue, 31 Jan 2023 00:32:16 +0000 Subject: [PATCH] rosalina: allow setting top and bot screen filters separately --- arm9/data/config_template.ini | Bin 6251 -> 6432 bytes arm9/source/config.c | 86 +++++-- arm9/source/config.h | 2 +- arm9/source/patches.c | 16 +- arm9/source/types.h | 18 +- k11_extension/include/globals.h | 17 +- k11_extension/source/svc/GetSystemInfo.c | 27 ++- sysmodules/rosalina/data/config_template.ini | Bin 6251 -> 6432 bytes .../rosalina/include/menus/screen_filters.h | 16 +- sysmodules/rosalina/source/menu.c | 27 +-- .../rosalina/source/menus/miscellaneous.c | 42 ++-- .../rosalina/source/menus/screen_filters.c | 216 +++++++++++++----- 12 files changed, 303 insertions(+), 164 deletions(-) diff --git a/arm9/data/config_template.ini b/arm9/data/config_template.ini index 9b521faa41f365d3d9a685cd88a25b0e50b9ae5f..697b4fe40fc882f3cf88d1a8f34a03a2d0313855 100644 GIT binary patch delta 293 zcmaEDu)t`8KA%8zadJ^=YF>O=W==_JQE}{KJw9=*@>GS=;#7r_j8p~pfKc^fh2;F4 z{30M(RFs-rl9`{UkdvREU0T3pJ-LjphcRTbAioHQLS`{YSITBp{)vq8CHV#M$;l-O zwhF2#T&Q-$C*_w+-YPIr5u_$PF*i36q^cO3Dp$c!6|hP9c_l@O#bD#GDx4`8sRmM* jRFs*XQIeNhT#VDqkAl%kAf=gkWvN9t9k|(BNP!Ii_6BL} delta 105 zcmZ2r^x9y9KHp>qJ~7^){Nlu%%)CT}(&E(O$uWG=oLtrlIr;h7r3I54_ntpTzOffetMinutes = (s16)opt; return 1; - } else if (strcmp(name, "screen_filters_cct") == 0) { + } else { + CHECK_PARSE_OPTION(-1); + } + } else if (strcmp(section, "screen_filters") == 0) { + if (strcmp(name, "screen_filters_top_cct") == 0) { s64 opt; CHECK_PARSE_OPTION(parseDecIntOption(&opt, value, 1000, 25100)); - cfg->screenFiltersCct = (u32)opt; + cfg->topScreenFilter.cct = (u32)opt; return 1; - } else if (strcmp(name, "screen_filters_gamma") == 0) { + } else if (strcmp(name, "screen_filters_top_gamma") == 0) { s64 opt; CHECK_PARSE_OPTION(parseDecFloatOption(&opt, value, 0, 1411 * FLOAT_CONV_MULT)); - cfg->screenFiltersGammaEnc = opt; + cfg->topScreenFilter.gammaEnc = opt; return 1; - } else if (strcmp(name, "screen_filters_contrast") == 0) { + } else if (strcmp(name, "screen_filters_top_contrast") == 0) { s64 opt; CHECK_PARSE_OPTION(parseDecFloatOption(&opt, value, 0, 255 * FLOAT_CONV_MULT)); - cfg->screenFiltersContrastEnc = opt; + cfg->topScreenFilter.contrastEnc = opt; return 1; - } else if (strcmp(name, "screen_filters_brightness") == 0) { + } else if (strcmp(name, "screen_filters_top_brightness") == 0) { s64 opt; CHECK_PARSE_OPTION(parseDecFloatOption(&opt, value, -1 * FLOAT_CONV_MULT, 1 * FLOAT_CONV_MULT)); - cfg->screenFiltersBrightnessEnc = opt; + cfg->topScreenFilter.brightnessEnc = opt; return 1; - } else if (strcmp(name, "screen_filters_invert") == 0) { + } else if (strcmp(name, "screen_filters_top_invert") == 0) { bool opt; CHECK_PARSE_OPTION(parseBoolOption(&opt, value)); - cfg->screenFiltersInvert = opt; + cfg->topScreenFilter.invert = opt; return 1; - } - else { + } else if (strcmp(name, "screen_filters_bot_cct") == 0) { + s64 opt; + CHECK_PARSE_OPTION(parseDecIntOption(&opt, value, 1000, 25100)); + cfg->bottomScreenFilter.cct = (u32)opt; + return 1; + } else if (strcmp(name, "screen_filters_bot_gamma") == 0) { + s64 opt; + CHECK_PARSE_OPTION(parseDecFloatOption(&opt, value, 0, 1411 * FLOAT_CONV_MULT)); + cfg->bottomScreenFilter.gammaEnc = opt; + return 1; + } else if (strcmp(name, "screen_filters_bot_contrast") == 0) { + s64 opt; + CHECK_PARSE_OPTION(parseDecFloatOption(&opt, value, 0, 255 * FLOAT_CONV_MULT)); + cfg->bottomScreenFilter.contrastEnc = opt; + return 1; + } else if (strcmp(name, "screen_filters_bot_brightness") == 0) { + s64 opt; + CHECK_PARSE_OPTION(parseDecFloatOption(&opt, value, -1 * FLOAT_CONV_MULT, 1 * FLOAT_CONV_MULT)); + cfg->bottomScreenFilter.brightnessEnc = opt; + return 1; + } else if (strcmp(name, "screen_filters_bot_invert") == 0) { + bool opt; + CHECK_PARSE_OPTION(parseBoolOption(&opt, value)); + cfg->bottomScreenFilter.invert = opt; + return 1; + } else { CHECK_PARSE_OPTION(-1); } } else if (strcmp(section, "autoboot") == 0) { @@ -531,12 +559,19 @@ static size_t saveLumaIniConfigToStr(char *out) static const int pinOptionToDigits[] = { 0, 4, 6, 8 }; int pinNumDigits = pinOptionToDigits[MULTICONFIG(PIN)]; - char screenFiltersGammaStr[32]; - char screenFiltersContrastStr[32]; - char screenFiltersBrightnessStr[32]; - encodedFloatToString(screenFiltersGammaStr, cfg->screenFiltersGammaEnc); - encodedFloatToString(screenFiltersContrastStr, cfg->screenFiltersContrastEnc); - encodedFloatToString(screenFiltersBrightnessStr, cfg->screenFiltersBrightnessEnc); + char topScreenFilterGammaStr[32]; + char topScreenFilterContrastStr[32]; + char topScreenFilterBrightnessStr[32]; + encodedFloatToString(topScreenFilterGammaStr, cfg->topScreenFilter.gammaEnc); + encodedFloatToString(topScreenFilterContrastStr, cfg->topScreenFilter.contrastEnc); + encodedFloatToString(topScreenFilterBrightnessStr, cfg->topScreenFilter.brightnessEnc); + + char bottomScreenFilterGammaStr[32]; + char bottomScreenFilterContrastStr[32]; + char bottomScreenFilterBrightnessStr[32]; + encodedFloatToString(bottomScreenFilterGammaStr, cfg->bottomScreenFilter.gammaEnc); + encodedFloatToString(bottomScreenFilterContrastStr, cfg->bottomScreenFilter.contrastEnc); + encodedFloatToString(bottomScreenFilterBrightnessStr, cfg->bottomScreenFilter.brightnessEnc); int n = sprintf( out, (const char *)config_template_ini, @@ -555,9 +590,11 @@ static size_t saveLumaIniConfigToStr(char *out) cfg->hbldr3dsxTitleId, rosalinaMenuComboStr, (int)cfg->ntpTzOffetMinutes, - (int)cfg->screenFiltersCct, screenFiltersGammaStr, - screenFiltersContrastStr, screenFiltersBrightnessStr, - (int)cfg->screenFiltersInvert, + (int)cfg->topScreenFilter.cct, (int)cfg->bottomScreenFilter.cct, + topScreenFilterGammaStr, bottomScreenFilterGammaStr, + topScreenFilterContrastStr, bottomScreenFilterContrastStr, + topScreenFilterBrightnessStr, bottomScreenFilterBrightnessStr, + (int)cfg->topScreenFilter.invert, (int)cfg->bottomScreenFilter.invert, cfg->autobootTwlTitleId, (int)cfg->autobootCtrAppmemtype, @@ -666,9 +703,10 @@ bool readConfig(void) configData.splashDurationMsec = 3000; configData.hbldr3dsxTitleId = HBLDR_DEFAULT_3DSX_TID; configData.rosalinaMenuCombo = 1u << 9 | 1u << 7 | 1u << 2; // L+Start+Select - configData.screenFiltersCct = 6500; // default temp, no-op - configData.screenFiltersGammaEnc = 1 * FLOAT_CONV_MULT; // 1.0f - configData.screenFiltersContrastEnc = 1 * FLOAT_CONV_MULT; // 1.0f + configData.topScreenFilter.cct = 6500; // default temp, no-op + configData.topScreenFilter.gammaEnc = 1 * FLOAT_CONV_MULT; // 1.0f + configData.topScreenFilter.contrastEnc = 1 * FLOAT_CONV_MULT; // 1.0f + configData.bottomScreenFilter = configData.topScreenFilter; configData.autobootTwlTitleId = AUTOBOOT_DEFAULT_TWL_TID; ret = false; } diff --git a/arm9/source/config.h b/arm9/source/config.h index 0d79e62..7e7dae0 100644 --- a/arm9/source/config.h +++ b/arm9/source/config.h @@ -36,7 +36,7 @@ #define CONFIG_FILE "config.bin" #define CONFIG_VERSIONMAJOR 3 -#define CONFIG_VERSIONMINOR 3 +#define CONFIG_VERSIONMINOR 4 #define BOOTCFG_NAND BOOTCONFIG(0, 7) #define BOOTCFG_FIRM BOOTCONFIG(3, 7) diff --git a/arm9/source/patches.c b/arm9/source/patches.c index 93aad77..f9af12c 100644 --- a/arm9/source/patches.c +++ b/arm9/source/patches.c @@ -133,11 +133,10 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32 u64 hbldr3dsxTitleId; u32 rosalinaMenuCombo; s16 ntpTzOffetMinutes; - u16 screenFiltersCct; - s64 screenFiltersGammaEnc; - s64 screenFiltersContrastEnc; - s64 screenFiltersBrightnessEnc; - bool screenFiltersInvert; + + ScreenFiltersCfgData topScreenFilter; + ScreenFiltersCfgData bottomScreenFilter; + u64 autobootTwlTitleId; u8 autobootCtrAppmemtype; } info; @@ -214,11 +213,8 @@ u32 installK11Extension(u8 *pos, u32 size, bool needToInitSd, u32 baseK11VA, u32 info->hbldr3dsxTitleId = configData.hbldr3dsxTitleId; info->rosalinaMenuCombo = configData.rosalinaMenuCombo; info->ntpTzOffetMinutes = configData.ntpTzOffetMinutes; - info->screenFiltersCct = configData.screenFiltersCct; - info->screenFiltersGammaEnc = configData.screenFiltersGammaEnc; - info->screenFiltersContrastEnc = configData.screenFiltersContrastEnc; - info->screenFiltersBrightnessEnc = configData.screenFiltersBrightnessEnc; - info->screenFiltersInvert = configData.screenFiltersInvert; + info->topScreenFilter = configData.topScreenFilter; + info->bottomScreenFilter = configData.bottomScreenFilter; info->autobootTwlTitleId = configData.autobootTwlTitleId; info->autobootCtrAppmemtype = configData.autobootCtrAppmemtype; info->versionMajor = VERSION_MAJOR; diff --git a/arm9/source/types.h b/arm9/source/types.h index d1e7b97..6c5c9b4 100644 --- a/arm9/source/types.h +++ b/arm9/source/types.h @@ -61,7 +61,15 @@ typedef volatile s64 vs64; #define ISN3DS (CFG11_SOCINFO & 2) #define ISDEVUNIT (CFG_UNITINFO != 0) -typedef struct { +typedef struct ScreenFiltersCfgData { + u16 cct; + bool invert; + s64 gammaEnc; + s64 contrastEnc; + s64 brightnessEnc; +} ScreenFiltersCfgData; + +typedef struct CfgData { u16 formatVersionMajor, formatVersionMinor; u32 config, multiConfig, bootConfig; @@ -70,11 +78,9 @@ typedef struct { u64 hbldr3dsxTitleId; u32 rosalinaMenuCombo; s16 ntpTzOffetMinutes; - u16 screenFiltersCct; - s64 screenFiltersGammaEnc; - s64 screenFiltersContrastEnc; - s64 screenFiltersBrightnessEnc; - bool screenFiltersInvert; + + ScreenFiltersCfgData topScreenFilter; + ScreenFiltersCfgData bottomScreenFilter; u64 autobootTwlTitleId; u8 autobootCtrAppmemtype; diff --git a/k11_extension/include/globals.h b/k11_extension/include/globals.h index 3e5ed24..6468589 100644 --- a/k11_extension/include/globals.h +++ b/k11_extension/include/globals.h @@ -115,6 +115,14 @@ extern void (*initFPU)(void); extern void (*mcuReboot)(void); extern void (*coreBarrier)(void); +typedef struct ScreenFiltersCfgData { + u16 cct; + bool invert; + s64 gammaEnc; + s64 contrastEnc; + s64 brightnessEnc; +} ScreenFiltersCfgData; + typedef struct CfwInfo { char magic[4]; @@ -132,11 +140,10 @@ typedef struct CfwInfo u64 hbldr3dsxTitleId; u32 rosalinaMenuCombo; s16 ntpTzOffetMinutes; - u16 screenFiltersCct; - s64 screenFiltersGammaEnc; - s64 screenFiltersContrastEnc; - s64 screenFiltersBrightnessEnc; - bool screenFiltersInvert; + + ScreenFiltersCfgData topScreenFilter; + ScreenFiltersCfgData bottomScreenFilter; + u64 autobootTwlTitleId; u8 autobootCtrAppmemtype; } CfwInfo; diff --git a/k11_extension/source/svc/GetSystemInfo.c b/k11_extension/source/svc/GetSystemInfo.c index 855caee..0e88365 100644 --- a/k11_extension/source/svc/GetSystemInfo.c +++ b/k11_extension/source/svc/GetSystemInfo.c @@ -39,6 +39,8 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param) { switch(param) { + // Please do not use these, except 0, 1, and 0x200 + // Other types may get removed or reordered without notice case 0: *out = SYSTEM_VERSION(cfwInfo.versionMajor, cfwInfo.versionMinor, cfwInfo.versionBuild); break; @@ -75,22 +77,37 @@ Result GetSystemInfoHook(s64 *out, s32 type, s32 param) *out = cfwInfo.rosalinaMenuCombo; break; case 0x102: - *out = cfwInfo.screenFiltersCct; + *out = cfwInfo.topScreenFilter.cct; break; case 0x103: *out = (s64)cfwInfo.ntpTzOffetMinutes; break; case 0x104: - *out = cfwInfo.screenFiltersGammaEnc; + *out = cfwInfo.topScreenFilter.gammaEnc; break; case 0x105: - *out = cfwInfo.screenFiltersContrastEnc; + *out = cfwInfo.topScreenFilter.contrastEnc; break; case 0x106: - *out = cfwInfo.screenFiltersBrightnessEnc; + *out = cfwInfo.topScreenFilter.brightnessEnc; break; case 0x107: - *out = (s64)cfwInfo.screenFiltersInvert; + *out = (s64)cfwInfo.topScreenFilter.invert; + break; + case 0x108: + *out = cfwInfo.bottomScreenFilter.cct; + break; + case 0x109: + *out = cfwInfo.bottomScreenFilter.gammaEnc; + break; + case 0x10A: + *out = cfwInfo.bottomScreenFilter.contrastEnc; + break; + case 0x10B: + *out = cfwInfo.bottomScreenFilter.brightnessEnc; + break; + case 0x10C: + *out = (s64)cfwInfo.bottomScreenFilter.invert; break; case 0x200: // isRelease diff --git a/sysmodules/rosalina/data/config_template.ini b/sysmodules/rosalina/data/config_template.ini index 9b521faa41f365d3d9a685cd88a25b0e50b9ae5f..697b4fe40fc882f3cf88d1a8f34a03a2d0313855 100644 GIT binary patch delta 293 zcmaEDu)t`8KA%8zadJ^=YF>O=W==_JQE}{KJw9=*@>GS=;#7r_j8p~pfKc^fh2;F4 z{30M(RFs-rl9`{UkdvREU0T3pJ-LjphcRTbAioHQLS`{YSITBp{)vq8CHV#M$;l-O zwhF2#T&Q-$C*_w+-YPIr5u_$PF*i36q^cO3Dp$c!6|hP9c_l@O#bD#GDx4`8sRmM* jRFs*XQIeNhT#VDqkAl%kAf=gkWvN9t9k|(BNP!Ii_6BL} delta 105 zcmZ2r^x9y9KHp>qJ~7^){Nlu%%)CT}(&E(O$uWG=oLtrlIr;h7r3I54_ 25100) - screenFiltersCurrentTemperature = 6500; - - svcGetSystemInfo(&out, 0x10000, 0x104); - screenFiltersCurrentGamma = (float)(out / FLOAT_CONV_MULT); - if (screenFiltersCurrentGamma < 0.0f || screenFiltersCurrentGamma > 1411.0f) - screenFiltersCurrentGamma = 1.0f; - - svcGetSystemInfo(&out, 0x10000, 0x105); - screenFiltersCurrentContrast = (float)(out / FLOAT_CONV_MULT); - if (screenFiltersCurrentContrast < 0.0f || screenFiltersCurrentContrast > 255.0f) - screenFiltersCurrentContrast = 1.0f; - - svcGetSystemInfo(&out, 0x10000, 0x106); - screenFiltersCurrentBrightness = (float)(out / FLOAT_CONV_MULT); - if (screenFiltersCurrentBrightness < -1.0f || screenFiltersCurrentBrightness > 1.0f) - screenFiltersCurrentBrightness = 0.0f; - - svcGetSystemInfo(&out, 0x10000, 0x107); - screenFiltersCurrentInvert = (bool)out; - - ScreenFiltersMenu_RestoreSettings(); + ScreenFiltersMenu_LoadConfig(); hidInit(); // assume this doesn't fail isHidInitialized = true; diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 70055dd..0d51e22 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -100,11 +100,9 @@ typedef struct CfgData { u64 hbldr3dsxTitleId; u32 rosalinaMenuCombo; s16 ntpTzOffetMinutes; - u16 screenFiltersCct; - float screenFiltersGamma; - float screenFiltersContrast; - float screenFiltersBrightness; - bool screenFiltersInvert; + + ScreenFilter topScreenFilter; + ScreenFilter bottomScreenFilter; u64 autobootTwlTitleId; u8 autobootCtrAppmemtype; @@ -302,12 +300,19 @@ static size_t saveLumaIniConfigToStr(char *out, const CfgData *cfg) static const int pinOptionToDigits[] = { 0, 4, 6, 8 }; int pinNumDigits = pinOptionToDigits[MULTICONFIG(PIN)]; - char screenFiltersGammaStr[32]; - char screenFiltersContrastStr[32]; - char screenFiltersBrightnessStr[32]; - floatToString(screenFiltersGammaStr, cfg->screenFiltersGamma, 6, false); - floatToString(screenFiltersContrastStr, cfg->screenFiltersContrast, 6, false); - floatToString(screenFiltersBrightnessStr, cfg->screenFiltersBrightness, 6, false); + char topScreenFilterGammaStr[32]; + char topScreenFilterContrastStr[32]; + char topScreenFilterBrightnessStr[32]; + floatToString(topScreenFilterGammaStr, cfg->topScreenFilter.gamma, 6, false); + floatToString(topScreenFilterContrastStr, cfg->topScreenFilter.contrast, 6, false); + floatToString(topScreenFilterBrightnessStr, cfg->topScreenFilter.brightness, 6, false); + + char bottomScreenFilterGammaStr[32]; + char bottomScreenFilterContrastStr[32]; + char bottomScreenFilterBrightnessStr[32]; + floatToString(bottomScreenFilterGammaStr, cfg->bottomScreenFilter.gamma, 6, false); + floatToString(bottomScreenFilterContrastStr, cfg->bottomScreenFilter.contrast, 6, false); + floatToString(bottomScreenFilterBrightnessStr, cfg->bottomScreenFilter.brightness, 6, false); int n = sprintf( out, (const char *)config_template_ini, @@ -326,9 +331,11 @@ static size_t saveLumaIniConfigToStr(char *out, const CfgData *cfg) cfg->hbldr3dsxTitleId, rosalinaMenuComboStr, (int)cfg->ntpTzOffetMinutes, - (int)cfg->screenFiltersCct, screenFiltersGammaStr, - screenFiltersContrastStr, screenFiltersBrightnessStr, - (int)cfg->screenFiltersInvert, + (int)cfg->topScreenFilter.cct, (int)cfg->bottomScreenFilter.cct, + topScreenFilterGammaStr, bottomScreenFilterGammaStr, + topScreenFilterContrastStr, bottomScreenFilterContrastStr, + topScreenFilterBrightnessStr, bottomScreenFilterBrightnessStr, + (int)cfg->topScreenFilter.invert, (int)cfg->bottomScreenFilter.invert, cfg->autobootTwlTitleId, (int)cfg->autobootCtrAppmemtype, @@ -388,11 +395,8 @@ void MiscellaneousMenu_SaveSettings(void) configData.hbldr3dsxTitleId = Luma_SharedConfig->hbldr_3dsx_tid; configData.rosalinaMenuCombo = menuCombo; configData.ntpTzOffetMinutes = (s16)lastNtpTzOffset; - configData.screenFiltersCct = (u16)screenFiltersCurrentTemperature; - configData.screenFiltersGamma = screenFiltersCurrentGamma; - configData.screenFiltersContrast = screenFiltersCurrentContrast; - configData.screenFiltersBrightness = screenFiltersCurrentBrightness; - configData.screenFiltersInvert = screenFiltersCurrentInvert; + configData.topScreenFilter = topScreenFilter; + configData.bottomScreenFilter = bottomScreenFilter; configData.autobootTwlTitleId = autobootTwlTitleId; configData.autobootCtrAppmemtype = autobootCtrAppmemtype; diff --git a/sysmodules/rosalina/source/menus/screen_filters.c b/sysmodules/rosalina/source/menus/screen_filters.c index bb943d7..f80d984 100644 --- a/sysmodules/rosalina/source/menus/screen_filters.c +++ b/sysmodules/rosalina/source/menus/screen_filters.c @@ -42,19 +42,15 @@ typedef union { u32 raw; } Pixel; -int screenFiltersCurrentTemperature = 6500; -float screenFiltersCurrentGamma = 1.0f; -float screenFiltersCurrentContrast = 1.0f; -float screenFiltersCurrentBrightness = 0.0f; -bool screenFiltersCurrentInvert = false; +ScreenFilter topScreenFilter; +ScreenFilter bottomScreenFilter; static inline bool ScreenFiltersMenu_IsDefaultSettings(void) { - bool ret = screenFiltersCurrentTemperature == 6500; - ret = ret && screenFiltersCurrentGamma == 1.0f; - ret = ret && screenFiltersCurrentContrast == 1.0f; - ret = ret && screenFiltersCurrentBrightness == 0.0f; - return ret; + static const ScreenFilter defaultFilter = { 6500, false, 1.0f, 1.0f, 0.0f }; + bool ok1 = memcmp(&topScreenFilter, &defaultFilter, sizeof(defaultFilter)) == 0; + bool ok2 = memcmp(&bottomScreenFilter, &defaultFilter, sizeof(defaultFilter)) == 0; + return ok1 && ok2; } static inline u8 ScreenFiltersMenu_GetColorLevel(int inLevel, float wp, float a, float b, float g) @@ -84,10 +80,12 @@ static u8 ScreenFilterMenu_CalculatePolynomialColorLutComponent(const float coef return (u8)CLAMP(levelInt, 0, 255); // clamp again just to be sure } -static void ScreenFilterMenu_WritePolynomialColorLut(const float coeffs[][3], bool invert, float gamma, u32 dim) +static void ScreenFilterMenu_WritePolynomialColorLut(bool top, const float coeffs[][3], bool invert, float gamma, u32 dim) { - GPU_FB_TOP_COL_LUT_INDEX = 0; - GPU_FB_BOTTOM_COL_LUT_INDEX = 0; + if (top) + GPU_FB_TOP_COL_LUT_INDEX = 0; + else + GPU_FB_BOTTOM_COL_LUT_INDEX = 0; for (int i = 0; i <= 255; i++) { Pixel px; @@ -96,35 +94,39 @@ static void ScreenFilterMenu_WritePolynomialColorLut(const float coeffs[][3], bo px.g = ScreenFilterMenu_CalculatePolynomialColorLutComponent(coeffs, 1, gamma, dim, inLevel); px.b = ScreenFilterMenu_CalculatePolynomialColorLutComponent(coeffs, 2, gamma, dim, inLevel); px.z = 0; - GPU_FB_TOP_COL_LUT_ELEM = px.raw; - GPU_FB_BOTTOM_COL_LUT_ELEM = px.raw; + + if (top) + GPU_FB_TOP_COL_LUT_ELEM = px.raw; + else + GPU_FB_BOTTOM_COL_LUT_ELEM = px.raw; } } -static void ScreenFiltersMenu_ApplyColorSettings(void) +static void ScreenFiltersMenu_ApplyColorSettings(bool top) { - GPU_FB_TOP_COL_LUT_INDEX = 0; - GPU_FB_BOTTOM_COL_LUT_INDEX = 0; + const ScreenFilter *filter = top ? &topScreenFilter : &bottomScreenFilter; float wp[3]; - colorramp_get_white_point(wp, screenFiltersCurrentTemperature); - float a = screenFiltersCurrentContrast; - float g = screenFiltersCurrentGamma; - float b = screenFiltersCurrentBrightness; - bool inv = screenFiltersCurrentInvert; + colorramp_get_white_point(wp, filter->cct); + float a = filter->contrast; + float b = filter->brightness; + float g = filter->gamma; + bool inv = filter->invert; float poly[][3] = { { b, b, b }, // x^0 { a * wp[0], a * wp[1], a * wp[2] }, // x^1 }; - ScreenFilterMenu_WritePolynomialColorLut(poly, inv, g, 1); + ScreenFilterMenu_WritePolynomialColorLut(top, poly, inv, g, 1); } -static void ScreenFiltersMenu_SetCct(int cct) +static void ScreenFiltersMenu_SetCct(u16 cct) { - screenFiltersCurrentTemperature = cct; - ScreenFiltersMenu_ApplyColorSettings(); + topScreenFilter.cct = cct; + bottomScreenFilter.cct = cct; + ScreenFiltersMenu_ApplyColorSettings(true); + ScreenFiltersMenu_ApplyColorSettings(false); } Menu screenFiltersMenu = { @@ -168,13 +170,67 @@ void ScreenFiltersMenu_RestoreSettings(void) svcKernelSetState(0x10000, 2); svcSleepThread(5 * 1000 * 100LL); - ScreenFiltersMenu_ApplyColorSettings(); + ScreenFiltersMenu_ApplyColorSettings(true); + ScreenFiltersMenu_ApplyColorSettings(false); // Unpause GSP svcKernelSetState(0x10000, 2); svcSleepThread(5 * 1000 * 100LL); } +void ScreenFiltersMenu_LoadConfig(void) +{ + s64 out = 0; + + svcGetSystemInfo(&out, 0x10000, 0x102); + topScreenFilter.cct = (u16)out; + if (topScreenFilter.cct < 1000 || topScreenFilter.cct > 25100) + topScreenFilter.cct = 6500; + + svcGetSystemInfo(&out, 0x10000, 0x104); + topScreenFilter.gamma = (float)(out / FLOAT_CONV_MULT); + if (topScreenFilter.gamma < 0.0f || topScreenFilter.gamma > 1411.0f) + topScreenFilter.gamma = 1.0f; + + svcGetSystemInfo(&out, 0x10000, 0x105); + topScreenFilter.contrast = (float)(out / FLOAT_CONV_MULT); + if (topScreenFilter.contrast < 0.0f || topScreenFilter.contrast > 255.0f) + topScreenFilter.contrast = 1.0f; + + svcGetSystemInfo(&out, 0x10000, 0x106); + topScreenFilter.brightness = (float)(out / FLOAT_CONV_MULT); + if (topScreenFilter.brightness < -1.0f || topScreenFilter.brightness > 1.0f) + topScreenFilter.brightness = 0.0f; + + svcGetSystemInfo(&out, 0x10000, 0x107); + topScreenFilter.invert = (bool)out; + + svcGetSystemInfo(&out, 0x10000, 0x108); + bottomScreenFilter.cct = (u16)out; + if (bottomScreenFilter.cct < 1000 || bottomScreenFilter.cct > 25100) + bottomScreenFilter.cct = 6500; + + svcGetSystemInfo(&out, 0x10000, 0x109); + bottomScreenFilter.gamma = (float)(out / FLOAT_CONV_MULT); + if (bottomScreenFilter.gamma < 0.0f || bottomScreenFilter.gamma > 1411.0f) + bottomScreenFilter.gamma = 1.0f; + + svcGetSystemInfo(&out, 0x10000, 0x10A); + bottomScreenFilter.contrast = (float)(out / FLOAT_CONV_MULT); + if (bottomScreenFilter.contrast < 0.0f || bottomScreenFilter.contrast > 255.0f) + bottomScreenFilter.contrast = 1.0f; + + svcGetSystemInfo(&out, 0x10000, 0x10B); + bottomScreenFilter.brightness = (float)(out / FLOAT_CONV_MULT); + if (bottomScreenFilter.brightness < -1.0f || bottomScreenFilter.brightness > 1.0f) + bottomScreenFilter.brightness = 0.0f; + + svcGetSystemInfo(&out, 0x10000, 0x10C); + bottomScreenFilter.invert = (bool)out; + + ScreenFiltersMenu_RestoreSettings(); +} + DEF_CCT_SETTER(6500, Default) DEF_CCT_SETTER(10000, Aquarium) @@ -187,35 +243,77 @@ DEF_CCT_SETTER(2300, WarmIncandescent) DEF_CCT_SETTER(1900, Candle) DEF_CCT_SETTER(1200, Ember) -static void ScreenFiltersMenu_AdvancedConfigurationChangeValue(int pos, int mult) +static void ScreenFiltersMenu_ClampFilter(ScreenFilter *filter) { - switch (pos) + filter->cct = CLAMP(filter->cct, 1000, 25100); + filter->gamma = CLAMP(filter->gamma, 0.0f, 1411.0f); // ln(255) / ln(254/255): (254/255)^1411 <= 1/255 + filter->contrast = CLAMP(filter->contrast, 0.0f, 255.0f); + filter->brightness = CLAMP(filter->brightness, -1.0f, 1.0f); +} + +static void ScreenFiltersMenu_AdvancedConfigurationChangeValue(int pos, int mult, bool sync) +{ + ScreenFilter *filter = pos >= 5 ? &bottomScreenFilter : &topScreenFilter; + ScreenFilter *otherFilter = pos >= 5 ? &topScreenFilter : &bottomScreenFilter; + + int otherMult = sync ? mult : 0; + + switch (pos % 5) { case 0: - screenFiltersCurrentTemperature += 100 * mult; + filter->cct += 100 * mult; + otherFilter->cct += 100 * otherMult; break; case 1: - screenFiltersCurrentGamma += 0.01f * mult; + filter->gamma += 0.01f * mult; + otherFilter->gamma += 0.01f * otherMult; break; case 2: - screenFiltersCurrentContrast += 0.01f * mult; + filter->contrast += 0.01f * mult; + otherFilter->contrast += 0.01f * otherMult; break; case 3: - screenFiltersCurrentBrightness += 0.01f * mult; + filter->brightness += 0.01f * mult; + otherFilter->brightness += 0.01f * otherMult; break; case 4: - screenFiltersCurrentInvert = !screenFiltersCurrentInvert; + filter->invert = !filter->invert; + otherFilter->invert = sync ? !otherFilter->invert : otherFilter->invert; break; } // Clamp - screenFiltersCurrentTemperature = CLAMP(screenFiltersCurrentTemperature, 1000, 25100); - screenFiltersCurrentGamma = CLAMP(screenFiltersCurrentGamma, 0.0f, 1411.0f); // ln(255) / ln(254/255): (254/255)^1411 <= 1/255 - screenFiltersCurrentContrast = CLAMP(screenFiltersCurrentContrast, 0.0f, 255.0f); - screenFiltersCurrentBrightness = CLAMP(screenFiltersCurrentBrightness, -1.0f, 1.0f); + ScreenFiltersMenu_ClampFilter(&topScreenFilter); + ScreenFiltersMenu_ClampFilter(&bottomScreenFilter); // Update the LUT - ScreenFiltersMenu_ApplyColorSettings(); + ScreenFiltersMenu_ApplyColorSettings(true); + ScreenFiltersMenu_ApplyColorSettings(false); +} + +static u32 ScreenFiltersMenu_AdvancedConfigurationHelper(const ScreenFilter *filter, int offset, int pos, u32 posY) +{ + char buf[64]; + + Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == offset++ ? '>' : ' '); + posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Temperature: %12dK \n", filter->cct); + + floatToString(buf, filter->gamma, 2, true); + Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == offset++ ? '>' : ' '); + posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Gamma: %13s \n", buf); + + floatToString(buf, filter->contrast, 2, true); + Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == offset++ ? '>' : ' '); + posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Contrast: %13s \n", buf); + + floatToString(buf, filter->brightness, 2, true); + Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == offset++ ? '>' : ' '); + posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Brightness: %13s \n", buf); + + Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == offset++ ? '>' : ' '); + posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Invert: %13s \n", filter->invert ? "true" : "false"); + + return posY; } void ScreenFiltersMenu_AdvancedConfiguration(void) @@ -224,48 +322,40 @@ void ScreenFiltersMenu_AdvancedConfiguration(void) u32 input = 0; u32 held = 0; - char buf[64]; int pos = 0; int mult = 1; + bool sync = true; + do { Draw_Lock(); Draw_DrawString(10, 10, COLOR_TITLE, "Screen filters menu"); posY = 30; - posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Use left/right to increase/decrease the sel. value.\n"); - posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Hold R to change the value faster.\n") + SPACING_Y; + posY = Draw_DrawString(10, posY, COLOR_WHITE, "Use left/right to increase/decrease the sel. value.\n"); + posY = Draw_DrawString(10, posY, COLOR_WHITE, "Hold R to change the value faster.\n"); + posY = Draw_DrawFormattedString(10, posY, COLOR_WHITE, "Update both screens: %s (L to toggle) \n", sync ? "yes" : "no") + SPACING_Y; - Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == 0 ? '>' : ' '); - posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Temperature: %12dK \n", screenFiltersCurrentTemperature); + posY = Draw_DrawString(10, posY, COLOR_WHITE, "Top screen:\n"); + posY = ScreenFiltersMenu_AdvancedConfigurationHelper(&topScreenFilter, 0, pos, posY) + SPACING_Y; - floatToString(buf, screenFiltersCurrentGamma, 2, true); - Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == 1 ? '>' : ' '); - posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Gamma: %13s \n", buf); - - floatToString(buf, screenFiltersCurrentContrast, 2, true); - Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == 2 ? '>' : ' '); - posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Contrast: %13s \n", buf); - - floatToString(buf, screenFiltersCurrentBrightness, 2, true); - Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == 3 ? '>' : ' '); - posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Brightness: %13s \n", buf); - - Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == 4 ? '>' : ' '); - posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Invert: %13s \n", screenFiltersCurrentInvert ? "true" : "false"); + posY = Draw_DrawString(10, posY, COLOR_WHITE, "Bottom screen:\n"); + posY = ScreenFiltersMenu_AdvancedConfigurationHelper(&bottomScreenFilter, 5, pos, posY) + SPACING_Y; input = waitInputWithTimeoutEx(&held, -1); mult = (held & KEY_R) ? 10 : 1; + if (input & KEY_L) + sync = !sync; if (input & KEY_LEFT) - ScreenFiltersMenu_AdvancedConfigurationChangeValue(pos, -mult); + ScreenFiltersMenu_AdvancedConfigurationChangeValue(pos, -mult, sync); if (input & KEY_RIGHT) - ScreenFiltersMenu_AdvancedConfigurationChangeValue(pos, mult); + ScreenFiltersMenu_AdvancedConfigurationChangeValue(pos, mult, sync); if (input & KEY_UP) - pos = (5 + pos - 1) % 5; + pos = (10 + pos - 1) % 10; if (input & KEY_DOWN) - pos = (pos + 1) % 5; + pos = (pos + 1) % 10; Draw_FlushFramebuffer(); Draw_Unlock();