SGB and AGB color correction
This commit is contained in:
parent
4fcc921b46
commit
851dbd3ccd
@ -162,9 +162,20 @@ static inline uint8_t scale_channel(uint8_t x)
|
|||||||
|
|
||||||
static inline uint8_t scale_channel_with_curve(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)
|
uint32_t GB_convert_rgb15(GB_gameboy_t *gb, uint16_t color)
|
||||||
{
|
{
|
||||||
uint8_t r = (color) & 0x1F;
|
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);
|
b = scale_channel(b);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
r = scale_channel_with_curve(r);
|
if (GB_is_sgb(gb)) {
|
||||||
g = scale_channel_with_curve(g);
|
return gb->rgb_encode_callback(gb,
|
||||||
b = scale_channel_with_curve(b);
|
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) {
|
if (gb->color_correction_mode != GB_COLOR_CORRECTION_CORRECT_CURVES) {
|
||||||
uint8_t new_g = (g * 3 + b) / 4;
|
uint8_t new_r, new_g, new_b;
|
||||||
uint8_t new_r = r, new_b = 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) {
|
if (gb->color_correction_mode == GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS) {
|
||||||
uint8_t old_max = MAX(r, MAX(g, b));
|
uint8_t old_max = MAX(r, MAX(g, b));
|
||||||
uint8_t new_max = MAX(new_r, MAX(new_g, new_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) {
|
if (new_min != 0xff) {
|
||||||
new_r = 0xff - (0xff - new_r) * (0xff - old_min) / (0xff - new_min);
|
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_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;
|
r = new_r;
|
||||||
|
21
Core/sgb.c
21
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)
|
static uint32_t convert_rgb15(GB_gameboy_t *gb, uint16_t color)
|
||||||
{
|
{
|
||||||
uint8_t r = (color) & 0x1F;
|
return GB_convert_rgb15(gb, color);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t convert_rgb15_with_fade(GB_gameboy_t *gb, uint16_t color, uint8_t fade)
|
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 (g >= 0x20) g = 0;
|
||||||
if (b >= 0x20) b = 0;
|
if (b >= 0x20) b = 0;
|
||||||
|
|
||||||
r = scale_channel(r);
|
color = r | (g << 5) | (b << 10);
|
||||||
g = scale_channel(g);
|
|
||||||
b = scale_channel(b);
|
|
||||||
|
|
||||||
return gb->rgb_encode_callback(gb, r, g, b);
|
return GB_convert_rgb15(gb, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user