diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index 71571bcff0..307e3802e7 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -451,11 +451,41 @@ static uint16_t argb32_to_abgr1555(uint32_t col) static uint16_t argb32_to_rgb5a3(uint32_t col) { - unsigned a = ((col >> 24) & 0xff) >> 5; - unsigned r = ((col >> 16) & 0xff) >> 4; - unsigned g = ((col >> 8) & 0xff) >> 4; - unsigned b = ((col & 0xff) ) >> 4; - return (a << 12) | (r << 8) | (g << 4) | b; + /* Extract colour components */ + unsigned a = (col >> 24) & 0xff; + unsigned r = (col >> 16) & 0xff; + unsigned g = (col >> 8) & 0xff; + unsigned b = col & 0xff; + /* Gekko platforms only have a 3 bit alpha channel, which + * is one bit less than all 'standard' target platforms. + * As a result, Gekko colours are effectively ~6-7% less + * transparent than expected, which causes backgrounds and + * borders to appear too bright. We therefore have to darken + * each RGB component according to the difference between Gekko + * alpha and normal 4 bit alpha values... */ + unsigned a4 = a >> 4; + unsigned a3 = a >> 5; + float a_factor = 1.0; + if (a3 > 0) + { + /* Avoid divide by zero errors... */ + a_factor = ((float)a4 * (1.0 / 15.0)) / ((float)a3 * (1.0 / 7.0)); + } + r = (unsigned)(((float)r * a_factor) + 0.5); + g = (unsigned)(((float)g * a_factor) + 0.5); + b = (unsigned)(((float)b * a_factor) + 0.5); + /* a_factor can actually be greater than 1. This will never happen + * with the current preset theme colour values, but users can set + * any custom values they like, so we have to play it safe... */ + r = (r <= 0xff) ? r : 0xff; + g = (g <= 0xff) ? g : 0xff; + b = (b <= 0xff) ? b : 0xff; + /* Convert RGB from 8 bit to 4 bit */ + r = r >> 4; + g = g >> 4; + b = b >> 4; + /* Return final value */ + return (a3 << 12) | (r << 8) | (g << 4) | b; } #define argb32_to_pixel_platform_format(color) argb32_to_rgb5a3(color)