rosalina: add color gamma control, and more
This commits adds an "Advanced configuration" option to screen filters, where CCT, color gamma, contrast and "brightness" can be fine-tuned, instead of just using a preset. Persistence in config.ini TBD in a later commit.
This commit is contained in:
parent
6592b516a4
commit
7397c85434
@ -75,6 +75,7 @@ extern bool preTerminationRequested;
|
|||||||
extern Handle preTerminationEvent;
|
extern Handle preTerminationEvent;
|
||||||
|
|
||||||
u32 waitInputWithTimeout(s32 msec);
|
u32 waitInputWithTimeout(s32 msec);
|
||||||
|
u32 waitInputWithTimeoutEx(u32 *outHeldKeys, s32 msec);
|
||||||
u32 waitInput(void);
|
u32 waitInput(void);
|
||||||
|
|
||||||
u32 waitComboWithTimeout(s32 msec);
|
u32 waitComboWithTimeout(s32 msec);
|
||||||
|
@ -49,3 +49,5 @@ void ScreenFiltersMenu_SetIncandescent(void); // 2700K
|
|||||||
void ScreenFiltersMenu_SetWarmIncandescent(void); // 2300K
|
void ScreenFiltersMenu_SetWarmIncandescent(void); // 2300K
|
||||||
void ScreenFiltersMenu_SetCandle(void); // 1900K
|
void ScreenFiltersMenu_SetCandle(void); // 1900K
|
||||||
void ScreenFiltersMenu_SetEmber(void); // 1200K
|
void ScreenFiltersMenu_SetEmber(void); // 1200K
|
||||||
|
|
||||||
|
void ScreenFiltersMenu_AdvancedConfiguration(void);
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#define REG32(addr) (*(vu32 *)(PA_PTR(addr)))
|
#define REG32(addr) (*(vu32 *)(PA_PTR(addr)))
|
||||||
|
|
||||||
|
#define CLAMP(v, m, M) ((v) <= (m) ? (m) : (v) >= (M) ? (M) : (v))
|
||||||
|
|
||||||
static inline u32 makeArmBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
static inline u32 makeArmBranch(const void *src, const void *dst, bool link) // the macros for those are ugly and buggy
|
||||||
{
|
{
|
||||||
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
u32 instrBase = link ? 0xEB000000 : 0xEA000000;
|
||||||
@ -68,3 +70,4 @@ void formatMemoryPermission(char *outbuf, MemPerm perm);
|
|||||||
void formatUserMemoryState(char *outbuf, MemState state);
|
void formatUserMemoryState(char *outbuf, MemState state);
|
||||||
u32 formatMemoryMapOfProcess(char *outbuf, u32 bufLen, Handle handle);
|
u32 formatMemoryMapOfProcess(char *outbuf, u32 bufLen, Handle handle);
|
||||||
int dateTimeToString(char *out, u64 msSince1900, bool filenameFormat);
|
int dateTimeToString(char *out, u64 msSince1900, bool filenameFormat);
|
||||||
|
int floatToString(char *out, float f, u32 precision, bool pad);
|
||||||
|
@ -81,6 +81,33 @@ u32 waitInputWithTimeout(s32 msec)
|
|||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 waitInputWithTimeoutEx(u32 *outHeldKeys, s32 msec)
|
||||||
|
{
|
||||||
|
s32 n = 0;
|
||||||
|
u32 keys;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
svcSleepThread(1 * 1000 * 1000LL);
|
||||||
|
Draw_Lock();
|
||||||
|
if (!isHidInitialized || menuShouldExit)
|
||||||
|
{
|
||||||
|
keys = 0;
|
||||||
|
Draw_Unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
|
||||||
|
hidScanInput();
|
||||||
|
keys = convertHidKeys(hidKeysDown()) | (convertHidKeys(hidKeysDownRepeat()) & DIRECTIONAL_KEYS);
|
||||||
|
*outHeldKeys = convertHidKeys(hidKeysHeld());
|
||||||
|
Draw_Unlock();
|
||||||
|
} while (keys == 0 && !menuShouldExit && isHidInitialized && (msec < 0 || n < msec));
|
||||||
|
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
u32 waitInput(void)
|
u32 waitInput(void)
|
||||||
{
|
{
|
||||||
return waitInputWithTimeout(-1);
|
return waitInputWithTimeout(-1);
|
||||||
|
@ -59,7 +59,8 @@ static inline bool ScreenFiltersMenu_IsDefaultSettings(void)
|
|||||||
static inline u8 ScreenFiltersMenu_GetColorLevel(int inLevel, float wp, float a, float b, float g)
|
static inline u8 ScreenFiltersMenu_GetColorLevel(int inLevel, float wp, float a, float b, float g)
|
||||||
{
|
{
|
||||||
float level = inLevel / 255.0f;
|
float level = inLevel / 255.0f;
|
||||||
level = powf(a * wp * level + b, g);
|
level = a * wp * level + b;
|
||||||
|
level = powf(CLAMP(level, 0.0f, 1.0f), g);
|
||||||
s32 levelInt = (s32)(255.0f * level + 0.5f); // round to nearest integer
|
s32 levelInt = (s32)(255.0f * level + 0.5f); // round to nearest integer
|
||||||
return levelInt <= 0 ? 0 : levelInt >= 255 ? 255 : (u8)levelInt; // clamp
|
return levelInt <= 0 ? 0 : levelInt >= 255 ? 255 : (u8)levelInt; // clamp
|
||||||
}
|
}
|
||||||
@ -105,6 +106,7 @@ Menu screenFiltersMenu = {
|
|||||||
{ "[2300K] Warm Incandescent", METHOD, .method = &ScreenFiltersMenu_SetWarmIncandescent },
|
{ "[2300K] Warm Incandescent", METHOD, .method = &ScreenFiltersMenu_SetWarmIncandescent },
|
||||||
{ "[1900K] Candle", METHOD, .method = &ScreenFiltersMenu_SetCandle },
|
{ "[1900K] Candle", METHOD, .method = &ScreenFiltersMenu_SetCandle },
|
||||||
{ "[1200K] Ember", METHOD, .method = &ScreenFiltersMenu_SetEmber },
|
{ "[1200K] Ember", METHOD, .method = &ScreenFiltersMenu_SetEmber },
|
||||||
|
{ "Advanced configuration", METHOD, .method = &ScreenFiltersMenu_AdvancedConfiguration },
|
||||||
{},
|
{},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -137,3 +139,83 @@ DEF_CCT_SETTER(2700, Incandescent)
|
|||||||
DEF_CCT_SETTER(2300, WarmIncandescent)
|
DEF_CCT_SETTER(2300, WarmIncandescent)
|
||||||
DEF_CCT_SETTER(1900, Candle)
|
DEF_CCT_SETTER(1900, Candle)
|
||||||
DEF_CCT_SETTER(1200, Ember)
|
DEF_CCT_SETTER(1200, Ember)
|
||||||
|
|
||||||
|
static void ScreenFiltersMenu_AdvancedConfigurationChangeValue(int pos, int mult)
|
||||||
|
{
|
||||||
|
switch (pos)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
screenFiltersCurrentTemperature += 100 * mult;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
screenFiltersCurrentGamma += 0.01f * mult;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
screenFiltersCurrentContrast += 0.01f * mult;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
screenFiltersCurrentBrightness += 0.01f * mult;
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Update the LUT
|
||||||
|
ScreenFiltersMenu_ApplyColorSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenFiltersMenu_AdvancedConfiguration(void)
|
||||||
|
{
|
||||||
|
u32 posY;
|
||||||
|
u32 input = 0;
|
||||||
|
u32 held = 0;
|
||||||
|
|
||||||
|
char buf[64];
|
||||||
|
int pos = 0;
|
||||||
|
int mult = 1;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Draw_DrawCharacter(10, posY, COLOR_TITLE, pos == 0 ? '>' : ' ');
|
||||||
|
posY = Draw_DrawFormattedString(30, posY, COLOR_WHITE, "Temperature: %12dK \n", screenFiltersCurrentTemperature);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
input = waitInputWithTimeoutEx(&held, -1);
|
||||||
|
mult = (held & KEY_R) ? 10 : 1;
|
||||||
|
|
||||||
|
if (input & KEY_LEFT)
|
||||||
|
ScreenFiltersMenu_AdvancedConfigurationChangeValue(pos, -mult);
|
||||||
|
if (input & KEY_RIGHT)
|
||||||
|
ScreenFiltersMenu_AdvancedConfigurationChangeValue(pos, mult);
|
||||||
|
if (input & KEY_UP)
|
||||||
|
pos = (4 + pos - 1) % 4;
|
||||||
|
if (input & KEY_DOWN)
|
||||||
|
pos = (pos + 1) % 4;
|
||||||
|
|
||||||
|
Draw_FlushFramebuffer();
|
||||||
|
Draw_Unlock();
|
||||||
|
}
|
||||||
|
while(!(input & (KEY_A | KEY_B)) && !menuShouldExit);
|
||||||
|
}
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "csvc.h"
|
#include "csvc.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
void formatMemoryPermission(char *outbuf, MemPerm perm)
|
void formatMemoryPermission(char *outbuf, MemPerm perm)
|
||||||
{
|
{
|
||||||
@ -161,3 +163,30 @@ int dateTimeToString(char *out, u64 msSince1900, bool filenameFormat)
|
|||||||
else
|
else
|
||||||
return sprintf(out, "%04lu-%02lu-%02lu %02lu:%02lu:%02lu", year, month, days, hours, minutes, seconds);
|
return sprintf(out, "%04lu-%02lu-%02lu %02lu:%02lu:%02lu", year, month, days, hours, minutes, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int floatToString(char *out, float f, u32 precision, bool pad)
|
||||||
|
{
|
||||||
|
// Floating point stuff is cringe
|
||||||
|
if (isnanf(f))
|
||||||
|
return sprintf(out, "NaN");
|
||||||
|
else if (isinff(f) && f >= -0.0f)
|
||||||
|
return sprintf(out, "inf");
|
||||||
|
else if (isinff(f))
|
||||||
|
return sprintf(out, "-inf");
|
||||||
|
|
||||||
|
static const u64 pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||||
|
precision = precision >= 10 ? 10 : precision;
|
||||||
|
|
||||||
|
u64 mult = pow10[precision];
|
||||||
|
double f2 = fabs((double)f) * mult + 0.5;
|
||||||
|
const char *sign = f2 >= 0.0f ? "" : "-";
|
||||||
|
u64 f3 = (u64)f2;
|
||||||
|
|
||||||
|
u64 intPart = f3 / mult;
|
||||||
|
u64 fracPart = f3 % mult;
|
||||||
|
|
||||||
|
if (pad)
|
||||||
|
return sprintf(out, "%s%llu.%0*llu", sign, intPart, (int)precision, fracPart);
|
||||||
|
else
|
||||||
|
return sprintf(out, "%s%llu.%llu", sign, intPart, fracPart);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user