From 5356e5c89a8f85b708fa498a2ead70b3a8368021 Mon Sep 17 00:00:00 2001 From: profi200 Date: Tue, 30 Jul 2024 16:37:05 +0200 Subject: [PATCH] Implemented full gamma correction for top LCDs which improves colors noticeably without crushing details in shadows. The disadvantage is that the gbaGamma, lcdGamma, brightness and contrast settings don't work anymore for now. They will be reimplemented with color profile settings later. --- source/arm11/oaf_video.c | 52 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/source/arm11/oaf_video.c b/source/arm11/oaf_video.c index b03a162..130670d 100644 --- a/source/arm11/oaf_video.c +++ b/source/arm11/oaf_video.c @@ -43,13 +43,39 @@ static KHandle g_convFinishedEvent = 0; +static const u32 g_topLcdCurveCorrect[73] = +{ + // Curve correction from 3DS top LCD gamma to 2.2 gamma for all channels. + // Unfortunately this doesn't fix color temperature but that varies wildly + // for all 2/3DS consoles on the market anyway. + 0x01000000, 0x03020102, 0x00060406, 0x01060507, + 0x03080608, 0x020B090C, 0x010E0B0F, 0x010F0D10, + 0x01110E12, 0x01121014, 0x00141116, 0x00151216, + 0x01151317, 0x01171419, 0x0118161B, 0x011A171C, + 0x021B191E, 0x001E1B21, 0x011E1C22, 0x01201E23, + 0x03211F25, 0x01242329, 0x0226242B, 0x0028272E, + 0x0229282E, 0x002B2B31, 0x042C2B32, 0x04303037, + 0x0034353C, 0x0535353D, 0x073A3B43, 0x0A41434B, + 0x034B4E56, 0x084F525B, 0x0D575B64, 0x03656973, + 0x12686D77, 0x017B818A, 0x167C838C, 0x03939AA4, + 0x0E979FA8, 0x01A6AFB7, 0x06A9B1B9, 0x01B0B9C0, + 0x00B2BBC3, 0x04B4BCC4, 0x00B9C2C9, 0x04BBC3CA, + 0x00C1C8CF, 0x00C2CAD0, 0x02C3CBD2, 0x01C7CED5, + 0x00C9D1D7, 0x03CBD2D8, 0x00D0D7DC, 0x01D1D8DE, + 0x01D4DAE0, 0x00D6DDE2, 0x02D8DEE3, 0x00DCE1E6, + 0x01DDE3E7, 0x02E0E5EA, 0x01E4E9ED, 0x02E7EBEF, + 0x01EBEFF2, 0x01EEF1F4, 0x00F1F3F6, 0x01F2F5F7, + 0x01F5F7F9, 0x01F8F9FB, 0x00FAFCFD, 0x01FCFDFD, + 0x00FFFFFF +}; +// TODO: Reimplement contrast and brightness in color lut below. static void adjustGammaTableForGba(void) { // Credits for this algo go to Extrems. - const float targetGamma = g_oafConfig.gbaGamma; + /*const float targetGamma = g_oafConfig.gbaGamma; const float lcdGamma = 1.f / g_oafConfig.lcdGamma; const float contrast = g_oafConfig.contrast; const float brightness = g_oafConfig.brightness / contrast; @@ -65,7 +91,29 @@ static void adjustGammaTableForGba(void) // Same adjustment for red/green/blue. *color_lut_data = res<<16 | res<<8 | res; - } + }*/ + + // Very simple gamma table expansion code. + // Code + hardcoded tables are way smaller than hardcoding the uncompressed tables. + const u32 *encTable = g_topLcdCurveCorrect; + vu32 *const color_lut_data = &getGxRegs()->pdc0.color_lut_data; + u32 decoded = 0; + do + { + // Get table entry and extract the number of linearly increasing entries. + u32 entry = *encTable++; + u32 steps = (entry>>24) + 1; + + // Keep track of how many table entries we generated. + decoded += steps; + do + { + // Set gamma table entry and increment. + // Note: Bits 24-31 don't matter so we don't need to mask. + *color_lut_data = entry; + entry += 0x010101; + } while(--steps != 0); + } while(decoded < 256); } typedef struct