From 851dbd3ccd5533f2140f11a182ea6ff61557cbc0 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 13 Sep 2019 17:13:21 +0300 Subject: [PATCH] SGB and AGB color correction --- Core/display.c | 41 ++++++++++++++++++++++++++++++++++------- Core/sgb.c | 21 +++------------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Core/display.c b/Core/display.c index 25e95e7e..5c1935c6 100644 --- a/Core/display.c +++ b/Core/display.c @@ -162,9 +162,20 @@ static inline uint8_t scale_channel(uint8_t x) static inline uint8_t scale_channel_with_curve(uint8_t x) { - return (uint8_t[]){0,2,4,7,12,18,25,34,42,52,62,73,85,97,109,121,134,146,158,170,182,193,203,213,221,230,237,243,248,251,253,255,}[x]; + return (uint8_t[]){0,2,4,7,12,18,25,34,42,52,62,73,85,97,109,121,134,146,158,170,182,193,203,213,221,230,237,243,248,251,253,255}[x]; } +static inline uint8_t scale_channel_with_curve_agb(uint8_t x) +{ + return (uint8_t[]){0,2,5,10,15,20,26,32,38,45,52,60,68,76,84,92,101,110,119,128,138,148,158,168,178,189,199,210,221,232,244,255}[x]; +} + +static inline uint8_t scale_channel_with_curve_sgb(uint8_t x) +{ + return (uint8_t[]){0,2,5,9,15,20,27,34,42,50,58,67,76,85,94,104,114,123,133,143,153,163,173,182,192,202,211,220,229,238,247,255}[x]; +} + + uint32_t GB_convert_rgb15(GB_gameboy_t *gb, uint16_t color) { uint8_t r = (color) & 0x1F; @@ -177,13 +188,29 @@ uint32_t GB_convert_rgb15(GB_gameboy_t *gb, uint16_t color) b = scale_channel(b); } else { - r = scale_channel_with_curve(r); - g = scale_channel_with_curve(g); - b = scale_channel_with_curve(b); + if (GB_is_sgb(gb)) { + return gb->rgb_encode_callback(gb, + scale_channel_with_curve_sgb(r), + scale_channel_with_curve_sgb(g), + scale_channel_with_curve_sgb(b)); + } + bool agb = gb->model == GB_MODEL_AGB; + r = agb? scale_channel_with_curve_agb(r) : scale_channel_with_curve(r); + g = agb? scale_channel_with_curve_agb(g) : scale_channel_with_curve(g); + b = agb? scale_channel_with_curve_agb(b) : scale_channel_with_curve(b); if (gb->color_correction_mode != GB_COLOR_CORRECTION_CORRECT_CURVES) { - uint8_t new_g = (g * 3 + b) / 4; - uint8_t new_r = r, new_b = b; + uint8_t new_r, new_g, new_b; + if (agb) { + new_r = (r * 7 + g * 1) / 8; + new_g = (g * 3 + b * 1) / 4; + new_b = (b * 7 + r * 1) / 8; + } + else { + new_g = (g * 3 + b) / 4; + new_r = r; + new_b = b; + } if (gb->color_correction_mode == GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS) { uint8_t old_max = MAX(r, MAX(g, b)); uint8_t new_max = MAX(new_r, MAX(new_g, new_b)); @@ -200,7 +227,7 @@ uint32_t GB_convert_rgb15(GB_gameboy_t *gb, uint16_t color) if (new_min != 0xff) { new_r = 0xff - (0xff - new_r) * (0xff - old_min) / (0xff - new_min); new_g = 0xff - (0xff - new_g) * (0xff - old_min) / (0xff - new_min); - new_b = 0xff - (0xff - new_b) * (0xff - old_min) / (0xff - new_min);; + new_b = 0xff - (0xff - new_b) * (0xff - old_min) / (0xff - new_min); } } r = new_r; diff --git a/Core/sgb.c b/Core/sgb.c index d0ac4727..18daa470 100644 --- a/Core/sgb.c +++ b/Core/sgb.c @@ -465,22 +465,9 @@ void GB_sgb_write(GB_gameboy_t *gb, uint8_t value) } } -static inline uint8_t scale_channel(uint8_t x) -{ - return (x << 3) | (x >> 2); -} - static uint32_t convert_rgb15(GB_gameboy_t *gb, uint16_t color) { - uint8_t r = (color) & 0x1F; - uint8_t g = (color >> 5) & 0x1F; - uint8_t b = (color >> 10) & 0x1F; - - r = scale_channel(r); - g = scale_channel(g); - b = scale_channel(b); - - return gb->rgb_encode_callback(gb, r, g, b); + return GB_convert_rgb15(gb, color); } static uint32_t convert_rgb15_with_fade(GB_gameboy_t *gb, uint16_t color, uint8_t fade) @@ -493,11 +480,9 @@ static uint32_t convert_rgb15_with_fade(GB_gameboy_t *gb, uint16_t color, uint8_ if (g >= 0x20) g = 0; if (b >= 0x20) b = 0; - r = scale_channel(r); - g = scale_channel(g); - b = scale_channel(b); + color = r | (g << 5) | (b << 10); - return gb->rgb_encode_callback(gb, r, g, b); + return GB_convert_rgb15(gb, color); } #include