diff --git a/src/main.c b/src/main.c index ba440214..d8070972 100644 --- a/src/main.c +++ b/src/main.c @@ -658,7 +658,10 @@ int Init_program(int argc,char * argv[]) // Gfx->Default_palette[MC_Dark] =Config.Fav_menu_colors[1]; // Gfx->Default_palette[MC_Light]=Config.Fav_menu_colors[2]; // Gfx->Default_palette[MC_White]=Config.Fav_menu_colors[3]; -// Compute_optimal_menu_colors(Gfx->Default_palette); + + // Even when using the skin's palette, if RGB range is small + // the colors will be unusable. + Compute_optimal_menu_colors(Gfx->Default_palette); // Infos sur les trames (Sieve) Sieve_mode=0; diff --git a/src/palette.c b/src/palette.c index d9bbb986..22657a72 100644 --- a/src/palette.c +++ b/src/palette.c @@ -67,6 +67,11 @@ void Set_palette_RGB_scale(int scale) RGB_scale = scale; } +int Get_palette_RGB_scale(void) +{ + return RGB_scale; +} + byte Round_palette_component(byte comp) { return ((comp+128/RGB_scale)*(RGB_scale-1)/255*255+(RGB_scale&1?1:0))/(RGB_scale-1); @@ -391,6 +396,13 @@ void Set_nice_menu_colors(dword * color_usage,int not_picture) byte color; byte replace_table[256]; T_Components rgb[4]; + const T_Components * target_rgb[4]; + const T_Components cpc_colors[4] = { + { 0, 0, 0}, + {128,128,128}, // Grey + { 0,255,128}, // Soft light green + {255,255,255} + }; short new_colors[4]={255,254,253,252}; // On initialise la table de remplacement @@ -425,6 +437,15 @@ void Set_nice_menu_colors(dword * color_usage,int not_picture) } } while (color); + if (RGB_scale==3) + // Specialized colors for CPC palette + for (index=0; index<4; index++) + target_rgb[index] = &cpc_colors[index]; + else + // Should be Config.Fav_menu_colors[index] if using user colors + for (index=0; index<4; index++) + target_rgb[index]=&(Gfx->Default_palette[Gfx->Color[index]]); + // On sauvegarde dans rgb les teintes qu'on va remplacer et on met les // couleurs du menu par défaut for (index=0; index<4; index++) @@ -434,9 +455,9 @@ void Set_nice_menu_colors(dword * color_usage,int not_picture) rgb[index].G=Main_palette[color].G; rgb[index].B=Main_palette[color].B; // Should be Config.Fav_menu_colors[index] if using user colors - Main_palette[color].R=Gfx->Default_palette[Gfx->Color[index]].R; - Main_palette[color].G=Gfx->Default_palette[Gfx->Color[index]].G; - Main_palette[color].B=Gfx->Default_palette[Gfx->Color[index]].B; + Main_palette[color].R=Round_palette_component(target_rgb[index]->R); + Main_palette[color].G=Round_palette_component(target_rgb[index]->G); + Main_palette[color].B=Round_palette_component(target_rgb[index]->B); } // Maintenant qu'on a placé notre nouvelle palette, on va chercher quelles @@ -2772,6 +2793,7 @@ void Button_Secondary_palette(void) { Set_palette_RGB_scale(rgb_scale); Set_palette(Main_palette); + Compute_optimal_menu_colors(Main_palette); } if (clicked_button==1) diff --git a/src/palette.h b/src/palette.h index fa7c9c0f..9f724a0e 100644 --- a/src/palette.h +++ b/src/palette.h @@ -31,6 +31,8 @@ void Button_Secondary_palette(void); /// Choose the number of graduations for RGB components, from 2 to 256. void Set_palette_RGB_scale(int); +int Get_palette_RGB_scale(void); + /// /// Scale a component (R, G or B) according to the current RGB graduations. /// Returns the resulting value, in the [0-255] range. diff --git a/src/windows.c b/src/windows.c index 35c8b67c..abd82669 100644 --- a/src/windows.c +++ b/src/windows.c @@ -39,6 +39,8 @@ #include "op_c.h" #include "readline.h" #include "sdlscreen.h" +#include "palette.h" + /// Width of one layer button, in pixels before scaling word Layer_button_width = 1; @@ -2757,6 +2759,13 @@ void Compute_optimal_menu_colors(T_Components * palette) int low_l, hi_l; int delta_low = 999999; int delta_high = 999999; + const int tolerence=16; + const T_Components cpc_colors[4] = { + { 0, 0, 0}, + {128,128,128}, // Grey + { 0,255,128}, // Soft light green + {255,255,255} + }; Old_black =MC_Black; Old_dark = MC_Dark; @@ -2765,34 +2774,34 @@ void Compute_optimal_menu_colors(T_Components * palette) Old_trans = MC_Trans; // First method: - // If all exact match for the ideal colors exist, pick them. + // If all close matches for the ideal colors exist, pick them. for (i=255; i>=0; i--) { - if (palette[i].R==Gfx->Default_palette[Gfx->Color[3]].R - && palette[i].G==Gfx->Default_palette[Gfx->Color[3]].G - && palette[i].B==Gfx->Default_palette[Gfx->Color[3]].B) + if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[3]].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[3]].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[3]].B/tolerence) { MC_White=i; for (i=255; i>=0; i--) { - if (palette[i].R==Gfx->Default_palette[Gfx->Color[2]].R - && palette[i].G==Gfx->Default_palette[Gfx->Color[2]].G - && palette[i].B==Gfx->Default_palette[Gfx->Color[2]].B) + if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[2]].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[2]].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[2]].B/tolerence) { MC_Light=i; for (i=255; i>=0; i--) { - if (palette[i].R==Gfx->Default_palette[Gfx->Color[1]].R - && palette[i].G==Gfx->Default_palette[Gfx->Color[1]].G - && palette[i].B==Gfx->Default_palette[Gfx->Color[1]].B) + if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[1]].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[1]].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[1]].B/tolerence) { MC_Dark=i; for (i=255; i>=0; i--) { - if (palette[i].R==Gfx->Default_palette[Gfx->Color[0]].R - && palette[i].G==Gfx->Default_palette[Gfx->Color[0]].G - && palette[i].B==Gfx->Default_palette[Gfx->Color[0]].B) + if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[0]].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[0]].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[0]].B/tolerence) { MC_Black=i; // On cherche une couleur de transparence différente des 4 autres. @@ -2813,13 +2822,66 @@ void Compute_optimal_menu_colors(T_Components * palette) } } } - // Second method: + // Second method: For CPC 27-color modes only + // Try to find colors that just work + if (Get_palette_RGB_scale()==3) + for (i=255; i>=0; i--) + { + + if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[3].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==cpc_colors[3].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==cpc_colors[3].B/tolerence) + { + MC_White=i; + for (i=255; i>=0; i--) + { + if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[2].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==cpc_colors[2].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==cpc_colors[2].B/tolerence) + { + MC_Light=i; + for (i=255; i>=0; i--) + { + if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[1].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==cpc_colors[1].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==cpc_colors[1].B/tolerence) + { + MC_Dark=i; + for (i=255; i>=0; i--) + { + if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[0].R/tolerence + && Round_palette_component(palette[i].G)/tolerence==cpc_colors[0].G/tolerence + && Round_palette_component(palette[i].B)/tolerence==cpc_colors[0].B/tolerence) + { + MC_Black=i; + // On cherche une couleur de transparence différente des 4 autres. + for (MC_Trans=0; ((MC_Trans==MC_Black) || (MC_Trans==MC_Dark) || + (MC_Trans==MC_Light) || (MC_Trans==MC_White)); MC_Trans++); + // Easy case + MC_OnBlack=MC_Dark; + MC_Window=MC_Light; + MC_Lighter=MC_White; + MC_Darker=MC_Dark; + Remap_menu_sprites(); + return; + } + } + } + } + } + } + } + } + + // Third method: // Compute luminance for whole palette // Take the darkest as black, the brightest white for(i = 0; i < 256; i++) { RGB_to_HSL(palette[i].R, palette[i].G, palette[i].B, &h, &s[i], &l[i]); + // Another formula for lightness, in 0-255 range + //l[i]=Perceptual_lightness(&palette[i])/4062/255; if (l[i] > max_l) { max_l = l[i]; @@ -2841,9 +2903,9 @@ void Compute_optimal_menu_colors(T_Components * palette) { s[i]=s[i]*(max_l-min_l)/255; } - // Adjust (reduce) perceived saturation at both ends of L spectrum for(i = 0; i < 256; i++) { + // Adjust (reduce) perceived saturation at both ends of L spectrum if (l[i]>192) s[i]=s[i]*(255-l[i])/64; else if (l[i]<64) @@ -2858,9 +2920,9 @@ void Compute_optimal_menu_colors(T_Components * palette) for (i = 0; i < 256; i++) { - if ( abs(l[i] - hi_l) + s[i]/6 < delta_high && i!=MC_White && i!=MC_Black) + if ( abs(l[i] - hi_l) + s[i]/2 < delta_high && i!=MC_White && i!=MC_Black) { - delta_high = abs(l[i] - hi_l) + s[i]/6; + delta_high = abs(l[i] - hi_l) + s[i]/2; MC_Light = i; } }