2189 lines
78 KiB
C
2189 lines
78 KiB
C
/* Grafx2 - The Ultimate 256-color bitmap paint program
|
|
|
|
Copyright 2007 Adrien Destugues
|
|
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
|
|
|
|
Grafx2 is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; version 2
|
|
of the License.
|
|
|
|
Grafx2 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Grafx2; if not, see <http://www.gnu.org/licenses/> or
|
|
write to the Free Software Foundation, Inc.,
|
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "const.h"
|
|
#include "struct.h"
|
|
#include "global.h"
|
|
#include "misc.h"
|
|
#include "engine.h"
|
|
#include "readline.h"
|
|
#include "buttons.h"
|
|
#include "pages.h"
|
|
#include "help.h"
|
|
#include "sdlscreen.h"
|
|
#include "errors.h"
|
|
#include "op_c.h"
|
|
#include "windows.h"
|
|
#include "input.h"
|
|
|
|
byte Palette_view_is_RGB = 1; // Indique si on est en HSL ou en RGB
|
|
|
|
// --------------------------- Menu des palettes -----------------------------
|
|
char * Palette_reduce_label[7]=
|
|
{
|
|
"128"," 64"," 32"," 16"," 8"," 4"," 2"
|
|
};
|
|
|
|
// Nombre de graduations pour une composante RGB
|
|
int RGB_scale = 256; // 24bit
|
|
//int RGB_scale = 64; // VGA
|
|
//int RGB_scale = 16; // Amiga
|
|
//int RGB_scale = 4; // MSX2
|
|
//int RGB_scale = 3; // Amstrad CPC
|
|
|
|
// Nombre de graduations pour une composante dans le mode actuel
|
|
int Color_count=256;
|
|
// Les composantes vont de 0 à (Color_count-1)
|
|
int Color_max=255;
|
|
// Le demi-pas est une quantité que l'on ajoute à une composante
|
|
// avant de faire un arrondi par division.
|
|
int Color_halfstep=0;
|
|
|
|
|
|
void Set_palette_RGB_scale(int scale)
|
|
{
|
|
if (scale>= 2 && scale <= 256)
|
|
RGB_scale = 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);
|
|
}
|
|
|
|
// Définir les unités pour les graduationss R G B ou H S V
|
|
void Componant_unit(int count)
|
|
{
|
|
Color_count = count;
|
|
Color_max = count-1;
|
|
Color_halfstep = 256/count/2;
|
|
}
|
|
|
|
void Set_HSL(T_Palette start_palette, T_Palette end_palette, byte color, short diff_h, short diff_s, short diff_l)
|
|
{
|
|
byte h, s, l;
|
|
RGB_to_HSL(start_palette[color].R,start_palette[color].G,start_palette[color].B,&h,&s,&l);
|
|
// La teinte (Hue) est cyclique
|
|
h=(diff_h+256+h);
|
|
// Pour les autres (Saturation, Lightness), au lieu d'additionner,
|
|
// on va faire un ratio, cela utilise mieux la plage de valeurs 0-255
|
|
if (diff_s<0)
|
|
s=(255+diff_s)*s/255;
|
|
else if (diff_s>0)
|
|
s=255-(255-diff_s)*(255-s)/255;
|
|
if (diff_l<0)
|
|
l=(255+diff_l)*l/255;
|
|
else if (diff_l>0)
|
|
l=255-(255-diff_l)*(255-l)/255;
|
|
HSL_to_RGB(h,s,l,&end_palette[color].R,&end_palette[color].G,&end_palette[color].B);
|
|
}
|
|
|
|
void Set_red(byte color, short new_color, T_Palette palette)
|
|
{
|
|
if (new_color< 0)
|
|
new_color= 0;
|
|
if (new_color>255)
|
|
new_color=255;
|
|
// Arrondi
|
|
new_color=Round_palette_component(new_color);
|
|
|
|
palette[color].R=new_color;
|
|
Set_color(color,palette[color].R,palette[color].G,palette[color].B);
|
|
}
|
|
|
|
|
|
void Set_green(byte color, short new_color, T_Palette palette)
|
|
{
|
|
if (new_color< 0)
|
|
new_color= 0;
|
|
if (new_color>255)
|
|
new_color=255;
|
|
// Arrondi
|
|
new_color=Round_palette_component(new_color);
|
|
|
|
palette[color].G=new_color;
|
|
Set_color(color,palette[color].R,palette[color].G,palette[color].B);
|
|
}
|
|
|
|
|
|
void Set_blue(byte color, short new_color, T_Palette palette)
|
|
{
|
|
if (new_color< 0)
|
|
new_color= 0;
|
|
if (new_color>255)
|
|
new_color=255;
|
|
// Arrondi
|
|
new_color=Round_palette_component(new_color);
|
|
|
|
palette[color].B=new_color;
|
|
Set_color(color,palette[color].R,palette[color].G,palette[color].B);
|
|
}
|
|
|
|
void Format_componant(byte value, char *str)
|
|
// Formate une chaine de 4 caractères+\0 : "nnn "
|
|
{
|
|
Num2str(value,str,3);
|
|
str[3]=' ';
|
|
str[4]='\0';
|
|
}
|
|
|
|
void Spread_colors(short start,short end,T_Palette palette)
|
|
// Modifie la palette pour obtenir un dégradé de couleur entre les deux bornes
|
|
// passées en paramètre
|
|
{
|
|
short start_red;
|
|
short start_green;
|
|
short start_blue;
|
|
short end_red;
|
|
short end_green;
|
|
short end_blue;
|
|
short index;
|
|
|
|
// On vérifie qu'il y ait assez de couleurs entre le début et la fin pour
|
|
// pouvoir faire un dégradé:
|
|
if ( (start!=end) && (start+1!=end) )
|
|
{
|
|
start_red=palette[start].R;
|
|
start_green =palette[start].G;
|
|
start_blue =palette[start].B;
|
|
|
|
end_red =palette[end ].R;
|
|
end_green =palette[end ].G;
|
|
end_blue =palette[end ].B;
|
|
|
|
for (index=start+1;index<end;index++)
|
|
{
|
|
Set_red(index, ((end_red-start_red) * (index-start))/(end-start) + start_red,palette);
|
|
Set_green (index, ((end_green -start_green ) * (index-start))/(end-start) + start_green ,palette);
|
|
Set_blue (index, ((end_blue -start_blue ) * (index-start))/(end-start) + start_blue ,palette);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Update_color_count(short * used_colors, dword * color_usage)
|
|
{
|
|
char str[10];
|
|
|
|
Hide_cursor();
|
|
Cursor_shape=CURSOR_SHAPE_HOURGLASS;
|
|
Display_cursor();
|
|
*used_colors=Count_used_colors(color_usage);
|
|
strcpy(str,"Used: ");
|
|
Num2str(*used_colors,str+6,3);
|
|
Hide_cursor();
|
|
Window_draw_normal_bouton(132,20,83,14,str,4,1);
|
|
Cursor_shape=CURSOR_SHAPE_ARROW;
|
|
Display_cursor();
|
|
}
|
|
|
|
|
|
void Remap_zone_highlevel(short x1, short y1, short x2, short y2,
|
|
byte * conversion_table)
|
|
// Attention: Remappe une zone de coins x1,y1 et x2-1,y2-1 !!!
|
|
{
|
|
short x_pos;
|
|
short y_pos;
|
|
|
|
for (y_pos=y1;y_pos<y2;y_pos++)
|
|
for (x_pos=x1;x_pos<x2;x_pos++)
|
|
{
|
|
if ((y_pos>=Window_pos_Y) && (y_pos<Window_pos_Y+(Window_height*Menu_factor_Y)) &&
|
|
(x_pos>=Window_pos_X) && (x_pos<Window_pos_X+(Window_width*Menu_factor_X)) )
|
|
x_pos=Window_pos_X+(Window_width*Menu_factor_X)-1;
|
|
else
|
|
Pixel(x_pos,y_pos,conversion_table[Read_pixel(x_pos,y_pos)]);
|
|
}
|
|
}
|
|
|
|
void Remap_image_highlevel(byte * conversion_table)
|
|
{
|
|
short end_x;
|
|
short end_y;
|
|
short end_x_mag=0;
|
|
short end_y_mag=0;
|
|
|
|
// On s'occupe de faire la traduction dans l'image
|
|
Remap_general_lowlevel(conversion_table,Main_screen,
|
|
Main_image_width,Main_image_height,Main_image_width);
|
|
|
|
// On calcule les limites à l'écran de l'image
|
|
if (Main_image_height>=Menu_Y_before_window)
|
|
end_y=Menu_Y_before_window;
|
|
else
|
|
end_y=Main_image_height;
|
|
|
|
if (!Main_magnifier_mode)
|
|
{
|
|
if (Main_image_width>=Screen_width)
|
|
end_x=Screen_width;
|
|
else
|
|
end_x=Main_image_width;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (Main_image_width>=Main_separator_position)
|
|
end_x=Main_separator_position;
|
|
else
|
|
end_x=Main_image_width;
|
|
|
|
if ((Main_X_zoom+(Main_image_width*Main_magnifier_factor))>=Screen_width)
|
|
end_x_mag=Screen_width;
|
|
else
|
|
end_x_mag=(Main_X_zoom+(Main_image_width*Main_magnifier_factor));
|
|
|
|
if (Main_image_height*Main_magnifier_factor>=Menu_Y_before_window)
|
|
end_y_mag=Menu_Y_before_window;
|
|
else
|
|
end_y_mag=Main_image_height*Main_magnifier_factor;
|
|
}
|
|
|
|
// On doit maintenant faire la traduction à l'écran
|
|
Remap_zone_highlevel(0,0,end_x,end_y,conversion_table);
|
|
|
|
if (Main_magnifier_mode)
|
|
{
|
|
Remap_zone_highlevel(Main_separator_position,0,end_x_mag,end_y_mag,conversion_table);
|
|
// Il peut encore rester le bas de la barre de split à remapper si la
|
|
// partie zoomée ne descend pas jusqu'en bas...
|
|
Remap_zone_highlevel(Main_separator_position,end_y_mag,
|
|
(Main_separator_position+(SEPARATOR_WIDTH*Menu_factor_X)),
|
|
Menu_Y_before_window,conversion_table);
|
|
}
|
|
// Remappe tous les fonds de fenetre (qui doivent contenir un bout d'écran)
|
|
Remap_window_backgrounds(conversion_table, 0, Menu_Y_before_window);
|
|
}
|
|
|
|
|
|
void Swap(int with_remap,short block_1_start,short block_2_start,short block_size,T_Palette palette, dword * color_usage)
|
|
{
|
|
short pos_1;
|
|
short pos_2;
|
|
short end_1;
|
|
short end_2;
|
|
dword temp;
|
|
byte conversion_table[256];
|
|
|
|
T_Components temp_palette[256];
|
|
dword Utilisation_temporaire[256];
|
|
|
|
// On fait une copie de la palette
|
|
memcpy(temp_palette, palette, sizeof(T_Palette));
|
|
|
|
// On fait une copie de la table d'utilisation des couleurs
|
|
memcpy(Utilisation_temporaire, color_usage, sizeof(dword) * 256);
|
|
|
|
// On commence à initialiser la table de conversion à un état où elle ne
|
|
// fera aucune conversion.
|
|
for (pos_1=0;pos_1<=255;pos_1++)
|
|
conversion_table[pos_1]=pos_1;
|
|
|
|
// On calcul les dernières couleurs de chaque bloc.
|
|
end_1=block_1_start+block_size-1;
|
|
end_2=block_2_start+block_size-1;
|
|
|
|
if ((block_2_start>=block_1_start) && (block_2_start<=end_1))
|
|
{
|
|
// Le bloc destination commence dans le bloc source.
|
|
|
|
for (pos_1=block_1_start,pos_2=end_1+1;pos_1<=end_2;pos_1++)
|
|
{
|
|
// Il faut transformer la couleur pos_1 en pos_2:
|
|
|
|
conversion_table[pos_2]=pos_1;
|
|
color_usage[pos_1]=Utilisation_temporaire[pos_2];
|
|
palette[pos_1].R=temp_palette[pos_2].R;
|
|
palette[pos_1].G=temp_palette[pos_2].G;
|
|
palette[pos_1].B=temp_palette[pos_2].B;
|
|
|
|
// On gère la mise à jour de pos_2
|
|
if (pos_2==end_2)
|
|
pos_2=block_1_start;
|
|
else
|
|
pos_2++;
|
|
}
|
|
}
|
|
else
|
|
if ((block_2_start<block_1_start) && (end_2>=block_1_start))
|
|
{
|
|
// Le bloc destination déborde dans le bloc source.
|
|
|
|
for (pos_1=block_2_start,pos_2=block_1_start;pos_1<=end_1;pos_1++)
|
|
{
|
|
// Il faut transformer la couleur pos_1 en pos_2:
|
|
|
|
conversion_table[pos_2]=pos_1;
|
|
color_usage[pos_1]=Utilisation_temporaire[pos_2];
|
|
palette[pos_1].R=temp_palette[pos_2].R;
|
|
palette[pos_1].G=temp_palette[pos_2].G;
|
|
palette[pos_1].B=temp_palette[pos_2].B;
|
|
|
|
// On gère la mise à jour de pos_2
|
|
if (pos_2==end_1)
|
|
pos_2=block_2_start;
|
|
else
|
|
pos_2++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Le bloc source et le bloc destination sont distincts.
|
|
|
|
for (pos_1=block_1_start,pos_2=block_2_start;pos_1<=end_1;pos_1++,pos_2++)
|
|
{
|
|
// Il va falloir permutter la couleur pos_1 avec la couleur pos_2
|
|
conversion_table[pos_1]=pos_2;
|
|
conversion_table[pos_2]=pos_1;
|
|
|
|
// On intervertit le nombre d'utilisation des couleurs pour garder une
|
|
// cohérence lors d'un éventuel "Zap unused".
|
|
temp =color_usage[pos_1];
|
|
color_usage[pos_1]=color_usage[pos_2];
|
|
color_usage[pos_2]=temp;
|
|
|
|
// On fait un changement de teinte:
|
|
temp =palette[pos_1].R;
|
|
palette[pos_1].R=palette[pos_2].R;
|
|
palette[pos_2].R=temp;
|
|
|
|
temp =palette[pos_1].G;
|
|
palette[pos_1].G=palette[pos_2].G;
|
|
palette[pos_2].G=temp;
|
|
|
|
temp =palette[pos_1].B;
|
|
palette[pos_1].B=palette[pos_2].B;
|
|
palette[pos_2].B=temp;
|
|
}
|
|
}
|
|
|
|
if (with_remap)
|
|
{
|
|
Remap_image_highlevel(conversion_table);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Set_nice_menu_colors(dword * color_usage)
|
|
{
|
|
short index,index2;
|
|
byte color;
|
|
byte replace_table[256];
|
|
T_Components rgb[4];
|
|
short new_colors[4]={255,254,253,252};
|
|
|
|
// On initialise la table de remplacement
|
|
for (index=0; index<256; index++)
|
|
replace_table[index]=index;
|
|
|
|
// On recherche les 4 couleurs les moins utilisées dans l'image pour pouvoir
|
|
// les remplacer par les nouvelles couleurs.
|
|
for (index2=0; index2<4; index2++)
|
|
for (index=255; index>=0; index--)
|
|
{
|
|
if ((index!=new_colors[0]) && (index!=new_colors[1])
|
|
&& (index!=new_colors[2]) && (index!=new_colors[3])
|
|
&& (color_usage[index]<color_usage[new_colors[index2]]))
|
|
new_colors[index2]=index;
|
|
}
|
|
|
|
// On trie maintenant la table dans le sens décroissant.
|
|
// (Ce n'est pas indispensable, mais ça fera plus joli dans la palette).
|
|
do
|
|
{
|
|
color=0; // Booléen qui dit si le tri n'est pas terminé.
|
|
for (index=0; index<3; index++)
|
|
{
|
|
if (new_colors[index]>new_colors[index+1])
|
|
{
|
|
index2 =new_colors[index];
|
|
new_colors[index] =new_colors[index+1];
|
|
new_colors[index+1]=index2;
|
|
color=1;
|
|
}
|
|
}
|
|
} while (color);
|
|
|
|
// 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++)
|
|
{
|
|
color=new_colors[index];
|
|
rgb[index].R=Main_palette[color].R;
|
|
rgb[index].G=Main_palette[color].G;
|
|
rgb[index].B=Main_palette[color].B;
|
|
Main_palette[color].R=Fav_menu_colors[index].R;
|
|
Main_palette[color].G=Fav_menu_colors[index].G;
|
|
Main_palette[color].B=Fav_menu_colors[index].B;
|
|
}
|
|
|
|
// Maintenant qu'on a placé notre nouvelle palette, on va chercher quelles
|
|
// sont les couleurs qui peuvent remplacer les anciennes
|
|
Hide_cursor();
|
|
for (index=0; index<4; index++)
|
|
replace_table[new_colors[index]]=Best_color_nonexcluded
|
|
(rgb[index].R,rgb[index].G,rgb[index].B);
|
|
|
|
// On fait un changement des couleurs visibles à l'écran et dans l'image
|
|
Remap_image_highlevel(replace_table);
|
|
Display_cursor();
|
|
}
|
|
|
|
|
|
|
|
void Reduce_palette(short * used_colors,int nb_colors_asked,T_Palette palette,dword * color_usage)
|
|
{
|
|
char str[5]; // buffer d'affichage du compteur
|
|
byte conversion_table[256]; // Table de conversion
|
|
int color_1; // |_ Variables de balayages
|
|
int color_2; // | de la palette
|
|
int best_color_1=0;
|
|
int best_color_2=0;
|
|
int difference;
|
|
int best_difference;
|
|
dword Utilisation;
|
|
dword Meilleure_utilisation;
|
|
|
|
// On commence par initialiser la table de conversion dans un état où
|
|
// aucune conversion ne sera effectuée.
|
|
for (color_1=0; color_1<=255; color_1++)
|
|
conversion_table[color_1]=color_1;
|
|
|
|
// Si on ne connait pas encore le nombre de couleurs utilisées, on le
|
|
// calcule! (!!! La fonction appelée Efface puis Affiche le curseur !!!)
|
|
if ((*used_colors)<0)
|
|
Update_color_count(used_colors,color_usage);
|
|
|
|
Hide_cursor();
|
|
|
|
// On tasse la palette vers le début parce qu'elle doit ressembler à
|
|
// du Gruyère (et comme Papouille il aime pas le fromage...)
|
|
|
|
// Pour cela, on va scruter la couleur color_1 et se servir de l'indice
|
|
// color_2 comme position de destination.
|
|
for (color_1=color_2=0;color_1<=255;color_1++)
|
|
{
|
|
if (color_usage[color_1])
|
|
{
|
|
// On commence par s'occuper des teintes de la palette
|
|
palette[color_2].R=palette[color_1].R;
|
|
palette[color_2].G=palette[color_1].G;
|
|
palette[color_2].B=palette[color_1].B;
|
|
|
|
// Ensuite, on met à jour le tableau d'occupation des couleurs.
|
|
color_usage[color_2]=color_usage[color_1];
|
|
|
|
// On va maintenant s'occuper de la table de conversion:
|
|
conversion_table[color_1]=color_2;
|
|
|
|
// Maintenant, la place désignée par color_2 est occupée, alors on
|
|
// doit passer à un indice de destination suivant.
|
|
color_2++;
|
|
}
|
|
}
|
|
|
|
// On met toutes les couleurs inutilisées en noir
|
|
for (;color_2<256;color_2++)
|
|
{
|
|
palette[color_2].R=0;
|
|
palette[color_2].G=0;
|
|
palette[color_2].B=0;
|
|
color_usage[color_2]=0;
|
|
}
|
|
|
|
// Maintenant qu'on a une palette clean, on va boucler en réduisant
|
|
// le nombre de couleurs jusqu'à ce qu'on atteigne le nombre désiré.
|
|
while ((*used_colors)>nb_colors_asked)
|
|
{
|
|
// Il s'agit de trouver les 2 couleurs qui se ressemblent le plus
|
|
// parmis celles qui sont utilisées (bien sûr) et de les remplacer par
|
|
// une seule couleur qui est la moyenne pondérée de ces 2 couleurs
|
|
// en fonction de leur utilisation dans l'image.
|
|
|
|
best_difference =0x7FFF;
|
|
Meilleure_utilisation=0x7FFFFFFF;
|
|
|
|
for (color_1=0;color_1<(*used_colors);color_1++)
|
|
for (color_2=color_1+1;color_2<(*used_colors);color_2++)
|
|
if (color_1!=color_2)
|
|
{
|
|
difference =abs((short)palette[color_1].R-palette[color_2].R)+
|
|
abs((short)palette[color_1].G-palette[color_2].G)+
|
|
abs((short)palette[color_1].B-palette[color_2].B);
|
|
|
|
if (difference<=best_difference)
|
|
{
|
|
Utilisation=color_usage[color_1]+color_usage[color_2];
|
|
if ((difference<best_difference) || (Utilisation<Meilleure_utilisation))
|
|
{
|
|
best_difference =difference;
|
|
Meilleure_utilisation=Utilisation;
|
|
best_color_1 =color_1;
|
|
best_color_2 =color_2;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Maintenant qu'on les a trouvées, on va pouvoir mettre à jour nos
|
|
// données pour que le remplacement se fasse sans encombres.
|
|
|
|
// En somme, on va remplacer best_color_2 par best_color_1,
|
|
// mais attention, on ne remplace pas best_color_1 par
|
|
// best_color_2 !
|
|
|
|
// On met à jour la palette.
|
|
palette[best_color_1].R=Round_div((color_usage[best_color_1]*palette[best_color_1].R)+
|
|
(color_usage[best_color_2]*palette[best_color_2].R),
|
|
Meilleure_utilisation);
|
|
palette[best_color_1].G=Round_div((color_usage[best_color_1]*palette[best_color_1].G)+
|
|
(color_usage[best_color_2]*palette[best_color_2].G),
|
|
Meilleure_utilisation);
|
|
palette[best_color_1].B=Round_div((color_usage[best_color_1]*palette[best_color_1].B)+
|
|
(color_usage[best_color_2]*palette[best_color_2].B),
|
|
Meilleure_utilisation);
|
|
|
|
// On met à jour la table d'utilisation.
|
|
color_usage[best_color_1]+=color_usage[best_color_2];
|
|
color_usage[best_color_2]=0;
|
|
|
|
// On met à jour la table de conversion.
|
|
for (color_1=0;color_1<=255;color_1++)
|
|
{
|
|
if (conversion_table[color_1]==best_color_2)
|
|
{
|
|
// La color_1 avait déjà prévue de se faire remplacer par la
|
|
// couleur que l'on veut maintenant éliminer. On va maintenant
|
|
// demander à ce que la color_1 se fasse remplacer par la
|
|
// best_color_1.
|
|
conversion_table[color_1]=best_color_1;
|
|
}
|
|
}
|
|
|
|
// Bon, maintenant que l'on a fait bouger nos petites choses concernants
|
|
// la couleur à éliminer, on va s'occuper de faire bouger les couleurs
|
|
// situées après la couleur à éliminer pour qu'elles se déplaçent d'une
|
|
// couleur en arrière.
|
|
for (color_1=0;color_1<=255;color_1++)
|
|
{
|
|
// Commençons par nous occuper des tables d'utilisation et de la
|
|
// palette.
|
|
|
|
if (color_1>best_color_2)
|
|
{
|
|
// La color_1 va scroller en arrière.
|
|
|
|
// Donc on transfère son utilisation dans l'utilisation de la
|
|
// couleur qui la précède.
|
|
color_usage[color_1-1]=color_usage[color_1];
|
|
|
|
// Et on transfère ses teintes dans les teintes de la couleur qui
|
|
// la précède.
|
|
palette[color_1-1].R=palette[color_1].R;
|
|
palette[color_1-1].G=palette[color_1].G;
|
|
palette[color_1-1].B=palette[color_1].B;
|
|
}
|
|
|
|
// Une fois la palette et la table d'utilisation gérées, on peut
|
|
// s'occuper de notre table de conversion.
|
|
if (conversion_table[color_1]>best_color_2)
|
|
// La color_1 avait l'intention de se faire remplacer par une
|
|
// couleur que l'on va (ou que l'on a déjà) bouger en arrière.
|
|
conversion_table[color_1]--;
|
|
}
|
|
|
|
// On vient d'éjecter une couleur, donc on peut mettre à jour le nombre
|
|
// de couleurs utilisées.
|
|
(*used_colors)--;
|
|
|
|
// A la fin, on doit passer (dans la palette) les teintes du dernier
|
|
// élément de notre ensemble en noir.
|
|
palette[*used_colors].R=0;
|
|
palette[*used_colors].G=0;
|
|
palette[*used_colors].B=0;
|
|
|
|
// Au passage, on va s'assurer que l'on a pas oublié de la mettre à une
|
|
// utilisation nulle.
|
|
color_usage[*used_colors]=0;
|
|
|
|
// Après avoir éjecté une couleur, on le fait savoir à l'utilisateur par
|
|
// l'intermédiaire du compteur de nombre utilisées.
|
|
Num2str(*used_colors,str,3);
|
|
Print_in_window(186,23,str,MC_Black,MC_Light);
|
|
}
|
|
|
|
// Maintenant, tous ces calculs doivent êtres pris en compte dans la
|
|
// palette, l'image et à l'écran.
|
|
Remap_image_highlevel(conversion_table); // Et voila pour l'image et l'écran
|
|
Display_cursor();
|
|
}
|
|
|
|
|
|
|
|
void Set_palette_slider(T_Scroller_button * slider,
|
|
word nb_elements, word position,
|
|
char * value, short x_pos)
|
|
{
|
|
slider->Nb_elements=nb_elements;
|
|
slider->Position=position;
|
|
Compute_slider_cursor_height(slider);
|
|
Window_draw_slider(slider);
|
|
Print_counter(x_pos,172,value,MC_Black,MC_Light);
|
|
}
|
|
|
|
|
|
|
|
void Display_sliders(T_Scroller_button * red_slider,
|
|
T_Scroller_button * green_slider,
|
|
T_Scroller_button * blue_slider,
|
|
byte block_is_selected, T_Components * palette)
|
|
{
|
|
char str[5];
|
|
|
|
if (block_is_selected)
|
|
{
|
|
Set_palette_slider(red_slider,Color_max*2+1,Color_max,"± 0",176);
|
|
Set_palette_slider(green_slider,Color_max*2+1,Color_max,"± 0",203);
|
|
Set_palette_slider(blue_slider,Color_max*2+1,Color_max,"± 0",230);
|
|
}
|
|
else
|
|
{
|
|
byte j1, j2, j3;
|
|
j1= palette[Fore_color].R;
|
|
j2= palette[Fore_color].G;
|
|
j3= palette[Fore_color].B;
|
|
if (!Palette_view_is_RGB)
|
|
{
|
|
RGB_to_HSL(j1,j2,j3,&j1,&j2,&j3);
|
|
}
|
|
|
|
Format_componant(j1*Color_max/255,str);
|
|
Set_palette_slider(red_slider,Color_count,Color_max-j1*Color_max/255,str,176);
|
|
Format_componant(j2*Color_max/255,str);
|
|
Set_palette_slider(green_slider,Color_count,Color_max-j2*Color_max/255,str,203);
|
|
Format_componant(j3*Color_max/255,str);
|
|
Set_palette_slider(blue_slider,Color_count,Color_max-j3*Color_max/255,str,230);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Draw_all_palette_sliders(T_Scroller_button * red_slider,
|
|
T_Scroller_button * green_slider,
|
|
T_Scroller_button * blue_slider,
|
|
T_Palette palette,byte start,byte end)
|
|
{
|
|
char str[5];
|
|
|
|
Hide_cursor();
|
|
// Réaffichage des jauges:
|
|
if (start!=end)
|
|
{
|
|
// Dans le cas d'un bloc, tout à 0.
|
|
red_slider->Position =Color_max;
|
|
Window_draw_slider(red_slider);
|
|
Print_counter(176,172,"± 0",MC_Black,MC_Light);
|
|
|
|
green_slider->Position =Color_max;
|
|
Window_draw_slider(green_slider);
|
|
Print_counter(203,172,"± 0",MC_Black,MC_Light);
|
|
|
|
blue_slider->Position =Color_max;
|
|
Window_draw_slider(blue_slider);
|
|
Print_counter(230,172,"± 0",MC_Black,MC_Light);
|
|
}
|
|
else
|
|
{
|
|
// Dans le cas d'une seule couleur, composantes.
|
|
byte j1, j2, j3;
|
|
j1= palette[start].R;
|
|
j2= palette[start].G;
|
|
j3= palette[start].B;
|
|
if (!Palette_view_is_RGB)
|
|
{
|
|
RGB_to_HSL(j1,j2,j3,&j1,&j2,&j3);
|
|
}
|
|
Format_componant(j1*Color_max/255,str);
|
|
red_slider->Position=Color_max-j1*Color_max/255;
|
|
Window_draw_slider(red_slider);
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
|
|
Format_componant(j2*Color_max/255,str);
|
|
green_slider->Position=Color_max-j2*Color_max/255;
|
|
Window_draw_slider(green_slider);
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
|
|
Format_componant(j3*Color_max/255,str);
|
|
blue_slider->Position=Color_max-j3*Color_max/255;
|
|
Window_draw_slider(blue_slider);
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
Display_cursor();
|
|
}
|
|
|
|
|
|
void Button_Palette(void)
|
|
{
|
|
static short reducer_index=0;
|
|
static short reduce_colors_number=256;
|
|
short temp_color; // Variable pouvant reservir pour différents calculs intermédiaires
|
|
dword temp;
|
|
byte color,click; // Variables pouvant reservir pour différents calculs intermédiaires
|
|
short clicked_button;
|
|
word old_mouse_x;
|
|
word old_mouse_y;
|
|
byte old_mouse_k;
|
|
byte block_start;
|
|
byte block_end;
|
|
byte first_color;
|
|
byte last_color;
|
|
char str[10];
|
|
word i;
|
|
//short x_pos,y_pos;
|
|
T_Normal_button * button_used;
|
|
T_Scroller_button * red_slider;
|
|
T_Scroller_button * green_slider;
|
|
T_Scroller_button * blue_slider;
|
|
T_Scroller_button * reduce_slider;
|
|
byte image_is_backed_up=0;
|
|
byte need_to_remp=0;
|
|
|
|
dword color_usage[256];
|
|
short used_colors=-1; // -1 <=> Inconnu
|
|
byte conversion_table[256];
|
|
|
|
T_Components * backup_palette;
|
|
T_Components * temp_palette;
|
|
T_Components * working_palette;
|
|
|
|
backup_palette =(T_Components *)malloc(sizeof(T_Palette));
|
|
temp_palette=(T_Components *)malloc(sizeof(T_Palette));
|
|
working_palette=(T_Components *)malloc(sizeof(T_Palette));
|
|
|
|
Componant_unit(RGB_scale);
|
|
|
|
Open_window(299,188,"Palette");
|
|
|
|
memcpy(working_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(backup_palette ,Main_palette,sizeof(T_Palette));
|
|
memcpy(temp_palette,Main_palette,sizeof(T_Palette));
|
|
|
|
Window_set_palette_button(5,79); // 1
|
|
|
|
Window_display_frame (173, 67,121,116);
|
|
Window_display_frame (128, 16, 91, 39);
|
|
Window_display_frame (221, 16, 73, 39);
|
|
// Frame creux destiné à l'affichage de la(les) couleur(s) sélectionnée(s)
|
|
Window_display_frame_in(259, 88, 26, 74);
|
|
|
|
// Graduation des jauges de couleur
|
|
Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*109),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*125),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*179),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*206),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
Block(Window_pos_X+(Menu_factor_X*233),Window_pos_Y+(Menu_factor_Y*141),Menu_factor_X*17,Menu_factor_Y,MC_Dark);
|
|
// Jauges de couleur
|
|
Palette_view_is_RGB=1;
|
|
red_slider = Window_set_scroller_button(182, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].R*Color_max/255);// 2
|
|
green_slider = Window_set_scroller_button(209, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].G*Color_max/255);// 3
|
|
blue_slider = Window_set_scroller_button(236, 81, 88,Color_count,1,Color_max-working_palette[Fore_color].B*Color_max/255);// 4
|
|
Print_in_window(184,71,"R",MC_Dark,MC_Light);
|
|
Print_in_window(211,71,"G",MC_Dark,MC_Light);
|
|
Print_in_window(238,71,"B",MC_Dark,MC_Light);
|
|
|
|
first_color=last_color=block_start=block_end=Fore_color;
|
|
Tag_color_range(block_start,block_end);
|
|
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*89),Menu_factor_X*24,Menu_factor_Y*72,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
|
|
// Affichage des valeurs de la couleur courante (pour 1 couleur)
|
|
Format_componant(Main_palette[Fore_color].R*Color_max/255,str);
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
Format_componant(Main_palette[Fore_color].G*Color_max/255,str);
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
Format_componant(Main_palette[Fore_color].B*Color_max/255,str);
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
|
|
Print_in_window(129,58,"Color number:",MC_Dark,MC_Light);
|
|
Num2str(Fore_color,str,3);
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
|
|
|
|
Window_set_normal_button( 6,17,59,14,"Default",3,1,SDLK_f); // 5
|
|
Window_set_normal_button(66,17,29,14,"Gry" ,1,1,SDLK_g); // 6
|
|
Window_set_normal_button(66,47,29,14,"Swp" ,0,1,KEY_NONE); // 7
|
|
Window_set_normal_button( 6,47,59,14,"X-Swap" ,1,1,SDLK_x); // 8
|
|
Window_set_normal_button(66,32,29,14,"Cpy" ,1,1,SDLK_c); // 9
|
|
Window_set_normal_button( 6,32,59,14,"Spread" ,4,1,SDLK_e); // 10
|
|
|
|
Window_set_normal_button(239,20,51,14,"Reduce" ,1,1,SDLK_r); // 11
|
|
Print_in_window(241,41,"to",MC_Dark,MC_Light);
|
|
|
|
Window_set_normal_button( 6,168,35,14,"Undo" ,1,1,SDLK_u); // 12
|
|
Window_set_normal_button( 62,168,51,14,"Cancel",0,1,KEY_ESC); // 13
|
|
Window_set_normal_button(117,168,51,14,"OK" ,0,1,SDLK_RETURN); // 14
|
|
|
|
button_used = Window_set_normal_button(132,20,83,14,"Used: ???",4,1,SDLK_d);// 15
|
|
Window_set_normal_button(132,37,83,14,"Zap unused",0,1,SDLK_DELETE);//16
|
|
|
|
// Jauge de réduction de palette
|
|
reduce_slider = Window_set_scroller_button(225,20,31,7,1,reducer_index);// 17
|
|
|
|
Window_set_repeatable_button(266, 74,12,11,"+",0,1,SDLK_KP_PLUS); // 18
|
|
Window_set_repeatable_button(266,165,12,11,"-",0,1,SDLK_KP_MINUS); // 19
|
|
|
|
Window_set_normal_button(96,17,29,14,"Neg" ,1,1,SDLK_n); // 20
|
|
Window_set_normal_button(66,62,29,14,"Inv" ,1,1,SDLK_i); // 21
|
|
Window_set_normal_button( 6,62,59,14,"X-Inv." ,5,1,SDLK_v); // 22
|
|
|
|
Window_set_input_button(263,39,3); // 23
|
|
|
|
Window_set_normal_button(96,32,29,14,"HSL" ,1,1,SDLK_h); // 24
|
|
Window_set_normal_button(96,47,29,14,"Srt" ,1,1,SDLK_s); // 25
|
|
// Affichage du facteur de réduction de la palette
|
|
Num2str(reduce_colors_number,str,3);
|
|
Print_in_window(265,41,str,MC_Black,MC_Light);
|
|
|
|
// Dessin des petits effets spéciaux pour les boutons [+] et [-]
|
|
Draw_thingumajig(263, 74,MC_White,-1);
|
|
Draw_thingumajig(280, 74,MC_White,+1);
|
|
Draw_thingumajig(263,165,MC_Dark,-1);
|
|
Draw_thingumajig(280,165,MC_Dark,+1);
|
|
|
|
Update_rect(Window_pos_X,Window_pos_Y,299*Menu_factor_X,188*Menu_factor_Y);
|
|
|
|
Display_cursor();
|
|
|
|
if (Config.Auto_nb_used)
|
|
Update_color_count(&used_colors,color_usage);
|
|
|
|
do
|
|
{
|
|
old_mouse_x=Mouse_X;
|
|
old_mouse_y=Mouse_Y;
|
|
old_mouse_k=Mouse_K;
|
|
clicked_button=Window_clicked_button();
|
|
|
|
switch (clicked_button)
|
|
{
|
|
case 0 : // Nulle part
|
|
break;
|
|
case -1 : // Hors de la fenêtre
|
|
case 1 : // palette
|
|
if ( (Mouse_X!=old_mouse_x) || (Mouse_Y!=old_mouse_y) || (Mouse_K!=old_mouse_k) )
|
|
{
|
|
Hide_cursor();
|
|
temp_color=(clicked_button==1) ? Window_attribute2 : Read_pixel(Mouse_X,Mouse_Y);
|
|
if (Mouse_K==RIGHT_SIDE)
|
|
{
|
|
if (Back_color!=temp_color)
|
|
{
|
|
Back_color=temp_color;
|
|
// 4 blocks de back_color entourant la fore_color
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!old_mouse_k)
|
|
{
|
|
// On vient de clicker sur une couleur (et une seule)
|
|
if ( (Fore_color!=temp_color) || (block_start!=block_end) )
|
|
{
|
|
// La couleur en question est nouvelle ou elle annule un
|
|
// ancien bloc. Il faut donc sélectionner cette couleur comme
|
|
// unique couleur choisie.
|
|
|
|
Fore_color=first_color=last_color=block_start=block_end=temp_color;
|
|
Tag_color_range(block_start,block_end);
|
|
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y*7,MC_Light);
|
|
Num2str(Fore_color,str,3);
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y*7);
|
|
|
|
// Affichage des jauges
|
|
Block(Window_pos_X+(Menu_factor_X*176),Window_pos_Y+(Menu_factor_Y*172),Menu_factor_X*84,Menu_factor_Y*7,MC_Light);
|
|
Display_sliders(red_slider,green_slider,blue_slider,0,working_palette);
|
|
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64);
|
|
|
|
memcpy(backup_palette ,working_palette,sizeof(T_Palette));
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// On maintient le click, on va donc tester si le curseur bouge
|
|
if (temp_color!=last_color)
|
|
{
|
|
// On commence par ordonner la 1ère et dernière couleur du bloc
|
|
if (first_color<temp_color)
|
|
{
|
|
block_start=first_color;
|
|
block_end=temp_color;
|
|
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Num2str(block_start,str ,3);
|
|
Num2str(block_end ,str+4,3);
|
|
str[3]=26; // Flèche vers la droite
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
|
|
// Affichage des jauges
|
|
Display_sliders(red_slider,green_slider,blue_slider,1,NULL);
|
|
|
|
// Affichage dans le block de visu du bloc (dégradé) en cours
|
|
Display_grad_block_in_window(264,93,block_start,block_end);
|
|
}
|
|
else if (first_color>temp_color)
|
|
{
|
|
block_start=temp_color;
|
|
block_end=first_color;
|
|
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Num2str(block_start,str ,3);
|
|
Num2str(block_end ,str+4,3);
|
|
str[3]=26; // Flèche vers la droite
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
|
|
// Affichage des jauges
|
|
Display_sliders(red_slider,green_slider,blue_slider,1,NULL);
|
|
|
|
// Affichage dans le block de visu du bloc (dégradé) en cours
|
|
Display_grad_block_in_window(264,93,block_start,block_end);
|
|
}
|
|
else
|
|
{
|
|
block_start=block_end=first_color;
|
|
Block(Window_pos_X+(Menu_factor_X*176),Window_pos_Y+(Menu_factor_Y*172),Menu_factor_X*84,Menu_factor_Y*7,MC_Light);
|
|
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Block(Window_pos_X+(Menu_factor_X*261),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*32,Menu_factor_Y*7,MC_Light);
|
|
Num2str(Fore_color,str,3);
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
|
|
// Affichage des jauges
|
|
Display_sliders(red_slider,green_slider,blue_slider,0,working_palette);
|
|
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64);
|
|
}
|
|
|
|
// On tagge le bloc (ou la couleur)
|
|
Tag_color_range(block_start,block_end);
|
|
}
|
|
|
|
last_color=temp_color;
|
|
}
|
|
}
|
|
Display_cursor();
|
|
}
|
|
break;
|
|
case 2 : // Jauge rouge
|
|
Hide_cursor();
|
|
if (block_start==block_end)
|
|
{
|
|
if(Palette_view_is_RGB)
|
|
{
|
|
Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].R*Color_max/255,str);
|
|
}
|
|
else
|
|
{
|
|
HSL_to_RGB(
|
|
255-red_slider->Position,
|
|
255-green_slider->Position,
|
|
255-blue_slider->Position,
|
|
&working_palette[Fore_color].R,
|
|
&working_palette[Fore_color].G,
|
|
&working_palette[Fore_color].B);
|
|
Format_componant((int)255-red_slider->Position,str);
|
|
}
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
}
|
|
else
|
|
{
|
|
if(Palette_view_is_RGB)
|
|
{
|
|
for (i=block_start; i<=block_end; i++)
|
|
Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette);
|
|
}
|
|
else
|
|
{
|
|
for (i=block_start; i<=block_end; i++)
|
|
Set_HSL(
|
|
temp_palette,
|
|
working_palette,
|
|
i,
|
|
Color_max-red_slider->Position,
|
|
Color_max-green_slider->Position,
|
|
Color_max-blue_slider->Position
|
|
);
|
|
}
|
|
|
|
if (red_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-red_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (red_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-red_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
|
|
}
|
|
|
|
need_to_remp=1;
|
|
|
|
Display_cursor();
|
|
Set_palette(working_palette);
|
|
break;
|
|
case 3 : // Jauge verte
|
|
Hide_cursor();
|
|
if (block_start==block_end)
|
|
{
|
|
if(Palette_view_is_RGB)
|
|
{
|
|
Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].G*Color_max/255,str);
|
|
}
|
|
else
|
|
{
|
|
HSL_to_RGB(
|
|
255-red_slider->Position,
|
|
255-green_slider->Position,
|
|
255-blue_slider->Position,
|
|
&working_palette[Fore_color].R,
|
|
&working_palette[Fore_color].G,
|
|
&working_palette[Fore_color].B);
|
|
Format_componant((int)255-green_slider->Position,str);
|
|
}
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
}
|
|
else
|
|
{
|
|
if(Palette_view_is_RGB)
|
|
{
|
|
for (i=block_start; i<=block_end; i++)
|
|
Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette);
|
|
}
|
|
else
|
|
{
|
|
for (i=block_start; i<=block_end; i++)
|
|
Set_HSL(
|
|
temp_palette,
|
|
working_palette,
|
|
i,
|
|
Color_max-red_slider->Position,
|
|
Color_max-green_slider->Position,
|
|
Color_max-blue_slider->Position
|
|
);
|
|
}
|
|
|
|
if (green_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-green_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (green_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-green_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
}
|
|
|
|
need_to_remp=1;
|
|
|
|
Display_cursor();
|
|
Set_palette(working_palette);
|
|
break;
|
|
|
|
case 4 : // Jauge bleue
|
|
Hide_cursor();
|
|
if (block_start==block_end)
|
|
{
|
|
if(Palette_view_is_RGB)
|
|
{
|
|
Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].B*Color_max/255,str);
|
|
}
|
|
else
|
|
{
|
|
HSL_to_RGB(
|
|
255-red_slider->Position,
|
|
255-green_slider->Position,
|
|
255-blue_slider->Position,
|
|
&working_palette[Fore_color].R,
|
|
&working_palette[Fore_color].G,
|
|
&working_palette[Fore_color].B);
|
|
Format_componant((int)255-blue_slider->Position,str);
|
|
}
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
else
|
|
{
|
|
if(Palette_view_is_RGB)
|
|
{
|
|
for (i=block_start; i<=block_end; i++)
|
|
Set_blue(i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette);
|
|
}
|
|
else
|
|
{
|
|
for (i=block_start; i<=block_end; i++)
|
|
Set_HSL(
|
|
temp_palette,
|
|
working_palette,
|
|
i,
|
|
Color_max-red_slider->Position,
|
|
Color_max-green_slider->Position,
|
|
Color_max-blue_slider->Position
|
|
);
|
|
}
|
|
|
|
if (blue_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-blue_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (blue_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-blue_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
|
|
need_to_remp=1;
|
|
|
|
Display_cursor();
|
|
Set_palette(working_palette);
|
|
break;
|
|
|
|
case 5 : // Default
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
memcpy(working_palette,Default_palette,sizeof(T_Palette));
|
|
memcpy(temp_palette,Default_palette,sizeof(T_Palette));
|
|
Set_palette(Default_palette);
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
// On prépare la "modifiabilité" des nouvelles couleurs
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 6 : // Grey scale
|
|
// Backup
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
// Grey Scale
|
|
for (i=block_start;i<=block_end;i++)
|
|
{
|
|
temp_color=(dword)( ((dword)working_palette[i].R*30) + ((dword)working_palette[i].G*59) + ((dword)working_palette[i].B*11) )/100;
|
|
Set_red(i,temp_color,working_palette);
|
|
Set_green (i,temp_color,working_palette);
|
|
Set_blue (i,temp_color,working_palette);
|
|
}
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
// On prépare la "modifiabilité" des nouvelles couleurs
|
|
Set_palette(working_palette);
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 7 : // Swap
|
|
case 8 : // X-Swap
|
|
temp_color=Wait_click_in_palette(Window_palette_button_list);
|
|
if ((temp_color>=0)
|
|
&& (temp_color!=block_start))
|
|
{
|
|
Hide_cursor();
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
|
|
// On calcule le nombre de couleurs a swapper sans risquer de sortir
|
|
// de la palette (La var. first_color est utilisée pour économiser 1 var; c'est tout)
|
|
first_color=(temp_color+block_end-block_start<=255)?block_end+1-block_start:256-temp_color;
|
|
|
|
if (clicked_button==8) // On ne fait de backup de l'image que si on
|
|
// est en mode X-SWAP.
|
|
if (!image_is_backed_up)
|
|
{
|
|
Backup();
|
|
image_is_backed_up=1;
|
|
}
|
|
|
|
Swap(clicked_button==8,block_start,temp_color,first_color,working_palette,color_usage);
|
|
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
// On déplace le bloc vers les modifs:
|
|
last_color=block_end=temp_color+first_color-1;
|
|
Fore_color=first_color=block_start=temp_color;
|
|
// On raffiche le n° des bornes du bloc:
|
|
if (block_start!=block_end)
|
|
{
|
|
// Cas d'un bloc multi-couleur
|
|
Num2str(block_start,str ,3);
|
|
Num2str(block_end ,str+4,3);
|
|
str[3]=26; // Flèche vers la droite
|
|
// Affichage dans le block de visu du bloc (dégradé) en cours
|
|
Display_grad_block_in_window(264,93,block_start,block_end);
|
|
}
|
|
else
|
|
{
|
|
// Cas d'une seule couleur
|
|
Num2str(Fore_color,str,3);
|
|
Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y* 7,MC_Light);
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
}
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
// On tag le bloc (ou la couleur)
|
|
Tag_color_range(block_start,block_end);
|
|
|
|
need_to_remp=1;
|
|
|
|
Set_palette(working_palette);
|
|
|
|
Display_cursor();
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
|
|
// En cas de X-Swap, tout l'ecran a pu changer de couleur.
|
|
if (clicked_button==8)
|
|
Update_rect(0, 0, Screen_width, Menu_Y_before_window);
|
|
Wait_end_of_click();
|
|
}
|
|
break;
|
|
|
|
case 9 : // Copy
|
|
temp_color=Wait_click_in_palette(Window_palette_button_list);
|
|
if ((temp_color>=0) && (temp_color!=block_start))
|
|
{
|
|
Hide_cursor();
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
memcpy(working_palette+temp_color,backup_palette+block_start,
|
|
((temp_color+block_end-block_start<=255)?block_end+1-block_start:256-temp_color)*3);
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
Set_palette(working_palette);
|
|
// On déplace le bloc vers les modifs:
|
|
last_color=block_end=((temp_color+block_end-block_start<=255)?(temp_color+block_end-block_start):255);
|
|
Fore_color=first_color=block_start=temp_color;
|
|
// On raffiche le n° des bornes du bloc:
|
|
if (block_start!=block_end)
|
|
{
|
|
// Cas d'un bloc multi-couleur
|
|
Num2str(block_start,str ,3);
|
|
Num2str(block_end ,str+4,3);
|
|
str[3]=26; // Flèche vers la droite
|
|
// Affichage dans le block de visu du bloc (dégradé) en cours
|
|
Display_grad_block_in_window(264,93,block_start,block_end);
|
|
}
|
|
else
|
|
{
|
|
// Cas d'une seule couleur
|
|
Num2str(Fore_color,str,3);
|
|
Block(Window_pos_X+(Menu_factor_X*237),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*56,Menu_factor_Y* 7,MC_Light);
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
}
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
// On tag le bloc (ou la couleur)
|
|
Tag_color_range(block_start,block_end);
|
|
|
|
need_to_remp=1;
|
|
|
|
Display_cursor();
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
Wait_end_of_click();
|
|
}
|
|
break;
|
|
|
|
case 10 : // Spread
|
|
if (block_start!=block_end)
|
|
{
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
Spread_colors(block_start,block_end,working_palette);
|
|
}
|
|
else
|
|
{
|
|
temp_color=Wait_click_in_palette(Window_palette_button_list);
|
|
if (temp_color>=0)
|
|
{
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
if (temp_color<Fore_color)
|
|
Spread_colors(temp_color,Fore_color,working_palette);
|
|
else
|
|
Spread_colors(Fore_color,temp_color,working_palette);
|
|
Wait_end_of_click();
|
|
}
|
|
}
|
|
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
// On prépare la "modifiabilité" des nouvelles couleurs
|
|
|
|
Set_palette(working_palette);
|
|
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 11: // Reduce
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
if (!image_is_backed_up)
|
|
{
|
|
Backup();
|
|
image_is_backed_up=1;
|
|
}
|
|
Reduce_palette(&used_colors,reduce_colors_number,working_palette,color_usage);
|
|
|
|
if ((Config.Safety_colors) && (used_colors<4))
|
|
{
|
|
memcpy(temp_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(Main_palette,working_palette,sizeof(T_Palette));
|
|
Set_nice_menu_colors(color_usage);
|
|
memcpy(working_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(Main_palette,temp_palette,sizeof(T_Palette));
|
|
}
|
|
|
|
Set_palette(working_palette); // On définit la nouvelle palette
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 12: // Undo
|
|
memcpy(temp_palette,backup_palette ,sizeof(T_Palette));
|
|
memcpy(backup_palette ,working_palette,sizeof(T_Palette));
|
|
memcpy(working_palette,temp_palette,sizeof(T_Palette));
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
Set_palette(working_palette);
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 15 : // Used
|
|
if (used_colors==-1)
|
|
Update_color_count(&used_colors,color_usage);
|
|
break;
|
|
|
|
case 16 : // Zap unused
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
if (used_colors==-1)
|
|
Update_color_count(&used_colors,color_usage);
|
|
for (i=0; i<256; i++)
|
|
{
|
|
if (!color_usage[i])
|
|
{
|
|
temp_color=block_start+(i % (block_end+1-block_start));
|
|
working_palette[i].R=backup_palette[temp_color].R;
|
|
working_palette[i].G=backup_palette[temp_color].G;
|
|
working_palette[i].B=backup_palette[temp_color].B;
|
|
}
|
|
}
|
|
|
|
if ((Config.Safety_colors) && (used_colors<4) && (block_end==block_start))
|
|
{
|
|
memcpy(temp_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(Main_palette,working_palette,sizeof(T_Palette));
|
|
Set_nice_menu_colors(color_usage);
|
|
memcpy(working_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(Main_palette,temp_palette,sizeof(T_Palette));
|
|
}
|
|
|
|
Set_palette(working_palette);
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 17 : // Jauge de réduction de palette
|
|
if (reducer_index!=reduce_slider->Position)
|
|
{
|
|
reducer_index=reduce_slider->Position;
|
|
// Affichage du facteur de réduction de la palette
|
|
Hide_cursor();
|
|
Print_in_window(265,41,Palette_reduce_label[reducer_index],MC_Black,MC_Light);
|
|
Display_cursor();
|
|
reduce_colors_number=atoi(Palette_reduce_label[reducer_index]);
|
|
}
|
|
break;
|
|
|
|
case 18 : // [+]
|
|
if (!Palette_view_is_RGB)
|
|
break;
|
|
Hide_cursor();
|
|
if (block_start==block_end)
|
|
{
|
|
if (red_slider->Position)
|
|
{
|
|
(red_slider->Position)--;
|
|
Window_draw_slider(red_slider);
|
|
Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].R*Color_max/255,str);
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
}
|
|
if (green_slider->Position)
|
|
{
|
|
(green_slider->Position)--;
|
|
Window_draw_slider(green_slider);
|
|
Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].G*Color_max/255,str);
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
}
|
|
if (blue_slider->Position)
|
|
{
|
|
(blue_slider->Position)--;
|
|
Window_draw_slider(blue_slider);
|
|
Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].B*Color_max/255,str);
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (red_slider->Position)
|
|
{
|
|
(red_slider->Position)--;
|
|
Window_draw_slider(red_slider);
|
|
}
|
|
if (green_slider->Position)
|
|
{
|
|
(green_slider->Position)--;
|
|
Window_draw_slider(green_slider);
|
|
}
|
|
if (blue_slider->Position)
|
|
{
|
|
(blue_slider->Position)--;
|
|
Window_draw_slider(blue_slider);
|
|
}
|
|
|
|
for (i=block_start; i<=block_end; i++)
|
|
{
|
|
Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette);
|
|
Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette);
|
|
Set_blue (i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette);
|
|
}
|
|
|
|
// -- red --
|
|
if (red_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-red_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (red_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-red_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
|
|
|
|
// -- green --
|
|
if (green_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-green_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (green_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-green_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
|
|
|
|
// -- blue --
|
|
if (blue_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-blue_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (blue_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-blue_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
|
|
need_to_remp=1;
|
|
|
|
Display_cursor();
|
|
Set_palette(working_palette);
|
|
break;
|
|
|
|
case 19 : // [-]
|
|
if (!Palette_view_is_RGB)
|
|
break;
|
|
Hide_cursor();
|
|
if (block_start==block_end)
|
|
{
|
|
if (red_slider->Position<Color_max)
|
|
{
|
|
(red_slider->Position)++;
|
|
Window_draw_slider(red_slider);
|
|
Set_red(Fore_color,(Color_max-red_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].R*Color_max/255,str);
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
}
|
|
if (green_slider->Position<Color_max)
|
|
{
|
|
(green_slider->Position)++;
|
|
Window_draw_slider(green_slider);
|
|
Set_green (Fore_color,(Color_max-green_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].G*Color_max/255,str);
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
}
|
|
if (blue_slider->Position<Color_max)
|
|
{
|
|
(blue_slider->Position)++;
|
|
Window_draw_slider(blue_slider);
|
|
Set_blue (Fore_color,(Color_max-blue_slider->Position)*255/Color_max,working_palette);
|
|
Format_componant(working_palette[Fore_color].B*Color_max/255,str);
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (red_slider->Position<(Color_max*2))
|
|
{
|
|
(red_slider->Position)++;
|
|
Window_draw_slider(red_slider);
|
|
}
|
|
if (green_slider->Position<(Color_max*2))
|
|
{
|
|
(green_slider->Position)++;
|
|
Window_draw_slider(green_slider);
|
|
}
|
|
if (blue_slider->Position<(Color_max*2))
|
|
{
|
|
(blue_slider->Position)++;
|
|
Window_draw_slider(blue_slider);
|
|
}
|
|
|
|
for (i=block_start; i<=block_end; i++)
|
|
{
|
|
Set_red(i,temp_palette[i].R+(Color_max-red_slider->Position)*255/Color_max,working_palette);
|
|
Set_green (i,temp_palette[i].G+(Color_max-green_slider->Position)*255/Color_max,working_palette);
|
|
Set_blue (i,temp_palette[i].B+(Color_max-blue_slider->Position)*255/Color_max,working_palette);
|
|
}
|
|
|
|
// -- red --
|
|
if (red_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-red_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (red_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-red_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(176,172,str,MC_Black,MC_Light);
|
|
|
|
|
|
// -- green --
|
|
if (green_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-green_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (green_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-green_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(203,172,str,MC_Black,MC_Light);
|
|
|
|
|
|
// -- blue --
|
|
if (blue_slider->Position>Color_max)
|
|
{
|
|
// Jauge dans les négatifs:
|
|
Num2str(-(Color_max-blue_slider->Position),str,4);
|
|
str[0]='-';
|
|
}
|
|
else if (blue_slider->Position<Color_max)
|
|
{
|
|
// Jauge dans les positifs:
|
|
Num2str( Color_max-blue_slider->Position ,str,4);
|
|
str[0]='+';
|
|
}
|
|
else
|
|
{
|
|
// Jauge nulle:
|
|
strcpy(str,"± 0");
|
|
}
|
|
Print_counter(230,172,str,MC_Black,MC_Light);
|
|
}
|
|
|
|
need_to_remp=1;
|
|
|
|
Display_cursor();
|
|
Set_palette(working_palette);
|
|
break;
|
|
|
|
case 20 : // Negative
|
|
// Backup
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
// Negative
|
|
for (i=block_start;i<=block_end;i++)
|
|
{
|
|
Set_red(i,255-working_palette[i].R,working_palette);
|
|
Set_green (i,255-working_palette[i].G,working_palette);
|
|
Set_blue (i,255-working_palette[i].B,working_palette);
|
|
}
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
Set_palette(working_palette);
|
|
// On prépare la "modifiabilité" des nouvelles couleurs
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 21 : // Inversion
|
|
case 22 : // X-Inversion
|
|
// Backup
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
// On initialise la table de conversion
|
|
for (i=0; i<=255; i++)
|
|
conversion_table[i]=i;
|
|
// Inversion
|
|
for (i=block_start;i<=block_end;i++)
|
|
{
|
|
temp_color=block_end-(i-block_start);
|
|
Set_red(i,backup_palette[temp_color].R,working_palette);
|
|
Set_green (i,backup_palette[temp_color].G,working_palette);
|
|
Set_blue (i,backup_palette[temp_color].B,working_palette);
|
|
if (clicked_button==22)
|
|
{
|
|
conversion_table[i]=temp_color;
|
|
conversion_table[temp_color]=i;
|
|
|
|
temp=color_usage[i];
|
|
color_usage[i]=color_usage[temp_color];
|
|
color_usage[temp_color]=temp;
|
|
}
|
|
}
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
// Si on est en X-Invert, on remap l'image (=> on fait aussi 1 backup)
|
|
if (clicked_button==22)
|
|
{
|
|
if (!image_is_backed_up)
|
|
{
|
|
Backup();
|
|
image_is_backed_up=1;
|
|
}
|
|
Hide_cursor();
|
|
Remap_image_highlevel(conversion_table);
|
|
Display_cursor();
|
|
}
|
|
// On prépare la "modifiabilité" des nouvelles couleurs
|
|
Set_palette(working_palette);
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
|
|
need_to_remp=1;
|
|
break;
|
|
|
|
case 23 : // Saisie du nombre de couleurs pour la réduction de palette
|
|
Num2str(reduce_colors_number,str,3);
|
|
|
|
if (Readline(265,41,str,3,1))
|
|
{
|
|
temp_color=atoi(str);
|
|
// Correction de la valeur lue
|
|
if ( (temp_color>256) || (temp_color<2) )
|
|
{
|
|
if (temp_color>256)
|
|
temp_color=256;
|
|
else
|
|
temp_color=2;
|
|
|
|
Num2str(temp_color,str,3);
|
|
Window_input_content(Window_special_button_list,str);
|
|
}
|
|
|
|
reduce_colors_number=temp_color;
|
|
}
|
|
Display_cursor();
|
|
break;
|
|
|
|
case 24 : // HSL <> RGB
|
|
|
|
// Acte les changements en cours sur une ou plusieurs couleurs
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
memcpy(backup_palette ,working_palette,sizeof(T_Palette));
|
|
|
|
Palette_view_is_RGB = !Palette_view_is_RGB;
|
|
|
|
if(! Palette_view_is_RGB)
|
|
{
|
|
// On passe en HSL
|
|
Print_in_window(184,71,"H",MC_Dark,MC_Light);
|
|
Print_in_window(211,71,"S",MC_Dark,MC_Light);
|
|
Print_in_window(238,71,"L",MC_Dark,MC_Light);
|
|
Componant_unit(256);
|
|
}
|
|
else
|
|
{
|
|
// On passe en RGB
|
|
Print_in_window(184,71,"R",MC_Dark,MC_Light);
|
|
Print_in_window(211,71,"G",MC_Dark,MC_Light);
|
|
Print_in_window(238,71,"B",MC_Dark,MC_Light);
|
|
Componant_unit(RGB_scale);
|
|
}
|
|
Display_sliders(red_slider,green_slider,blue_slider,(block_start!=block_end),working_palette);
|
|
break;
|
|
|
|
case 25 : // Sort palette
|
|
{
|
|
byte h = 0, l = 0, s=0;
|
|
byte oh=0,ol=0,os=0; // Valeur pour la couleur précédente
|
|
int swap=1;
|
|
|
|
while(swap==1)
|
|
{
|
|
swap=0;
|
|
h=0;l=0;s=0;
|
|
for(temp_color=0;temp_color<256;temp_color++)
|
|
{
|
|
oh=h; ol=l; os=s;
|
|
// On trie par Chrominance (H) et Luminance (L)
|
|
RGB_to_HSL(working_palette[temp_color].R,
|
|
working_palette[temp_color].G,
|
|
working_palette[temp_color].B,&h,&s,&l);
|
|
|
|
if(
|
|
((s==0) && (os>0)) // Un gris passe devant une couleur saturée
|
|
|| (((s>0 && os > 0) || (s==os && s==0)) // Deux couleurs saturées ou deux gris...
|
|
&& (h<oh || (h==oh && l<ol)))) // Dans ce cas on décide avec chroma puis lumi
|
|
{
|
|
// On échange la couleur avec la précédente
|
|
Swap(0,temp_color,temp_color-1,1,working_palette,color_usage);
|
|
swap=1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Maintenant, tous ces calculs doivent êtres pris en compte dans la
|
|
// palette, l'image et à l'écran.
|
|
Set_palette(working_palette);
|
|
|
|
need_to_remp=1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
if (!Mouse_K)
|
|
{
|
|
switch (Key)
|
|
{
|
|
case SDLK_LEFTBRACKET : // Décaler Forecolor vers la gauche
|
|
if (block_start==block_end)
|
|
{
|
|
Fore_color--;
|
|
first_color--;
|
|
last_color--;
|
|
block_start--;
|
|
block_end--;
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
Hide_cursor();
|
|
Tag_color_range(block_start,block_end);
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Num2str(Fore_color,str,3);
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64);
|
|
Display_cursor();
|
|
}
|
|
Key=0;
|
|
break;
|
|
|
|
case SDLK_RIGHTBRACKET : // Décaler Forecolor vers la droite
|
|
if (block_start==block_end)
|
|
{
|
|
Fore_color++;
|
|
first_color++;
|
|
last_color++;
|
|
block_start++;
|
|
block_end++;
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
Hide_cursor();
|
|
Tag_color_range(block_start,block_end);
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Num2str(Fore_color,str,3);
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64);
|
|
Display_cursor();
|
|
}
|
|
Key=0;
|
|
break;
|
|
|
|
case (SDLK_LEFTBRACKET|MOD_SHIFT) : // Decaler Backcolor vers la gauche
|
|
Back_color--;
|
|
case (SDLK_RIGHTBRACKET|MOD_SHIFT) : // Decaler Backcolor vers la droite
|
|
// attention: pas de break ci-dessus
|
|
if (Key==(SDLK_RIGHTBRACKET|MOD_SHIFT))
|
|
Back_color++;
|
|
Hide_cursor();
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72);
|
|
Display_cursor();
|
|
Key=0;
|
|
break;
|
|
|
|
case SDLK_BACKSPACE : // Remise des couleurs du menu à l'état normal en essayant
|
|
// de ne pas trop modifier l'image.
|
|
if (!image_is_backed_up)
|
|
{
|
|
Backup();
|
|
image_is_backed_up=1;
|
|
}
|
|
if (used_colors==-1)
|
|
Update_color_count(&used_colors,color_usage);
|
|
|
|
memcpy(backup_palette,working_palette,sizeof(T_Palette));
|
|
memcpy(temp_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(Main_palette,working_palette,sizeof(T_Palette));
|
|
Set_nice_menu_colors(color_usage);
|
|
memcpy(working_palette,Main_palette,sizeof(T_Palette));
|
|
memcpy(Main_palette,temp_palette,sizeof(T_Palette));
|
|
Set_palette(working_palette);
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
Draw_all_palette_sliders(red_slider,green_slider,blue_slider,working_palette,block_start,block_end);
|
|
Update_color_count(&used_colors,color_usage);
|
|
need_to_remp=1;
|
|
Key=0;
|
|
break;
|
|
|
|
case SDLK_BACKQUOTE : // Récupération d'une couleur derrière le menu
|
|
case SDLK_COMMA :
|
|
Get_color_behind_window(&color,&click);
|
|
if (click)
|
|
{
|
|
Hide_cursor();
|
|
if (click==RIGHT_SIDE)
|
|
{
|
|
if (Back_color!=color)
|
|
{
|
|
Back_color=color;
|
|
// 4 blocks de back_color entourant la fore_color
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*24,Menu_factor_Y<<2,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*157),Menu_factor_X*24,Menu_factor_Y<<2,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color);
|
|
Block(Window_pos_X+(Menu_factor_X*280),Window_pos_Y+(Menu_factor_Y* 93),Menu_factor_X<<2,Menu_factor_Y<<6,Back_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y* 89),Menu_factor_X*32,Menu_factor_Y*72);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Fore_color=first_color=last_color=block_start=block_end=color;
|
|
Tag_color_range(block_start,block_end);
|
|
|
|
// Affichage du n° de la couleur sélectionnée
|
|
Block(Window_pos_X+(Menu_factor_X*261),Window_pos_Y+(Menu_factor_Y*58),Menu_factor_X*32,Menu_factor_Y*7,MC_Light);
|
|
Num2str(Fore_color,str,3);
|
|
Print_in_window(237,58,str,MC_Black,MC_Light);
|
|
|
|
// Affichage des jauges
|
|
Display_sliders(red_slider,green_slider,blue_slider,0,working_palette);
|
|
|
|
// Affichage dans le block de visu de la couleur en cours
|
|
Block(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64,Fore_color);
|
|
Update_rect(Window_pos_X+(Menu_factor_X*264),Window_pos_Y+(Menu_factor_Y*93),Menu_factor_X<<4,Menu_factor_Y*64);
|
|
|
|
memcpy(backup_palette ,working_palette,sizeof(T_Palette));
|
|
memcpy(temp_palette,working_palette,sizeof(T_Palette));
|
|
}
|
|
Display_cursor();
|
|
Wait_end_of_click();
|
|
}
|
|
Key=0;
|
|
break;
|
|
default:
|
|
if (Is_shortcut(Key,0x100+BUTTON_HELP))
|
|
{
|
|
Key=0;
|
|
Window_help(BUTTON_PALETTE, NULL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (need_to_remp)
|
|
{
|
|
Hide_cursor();
|
|
Compute_optimal_menu_colors(working_palette);
|
|
|
|
// On remappe brutalement
|
|
Remap_screen_after_menu_colors_change();
|
|
// Puis on remet les trucs qui ne devaient pas changer
|
|
Window_draw_palette_bouton(5,79);
|
|
Block(Window_pos_X+(Menu_factor_X*260),Window_pos_Y+(Menu_factor_Y*89),Menu_factor_X*24,Menu_factor_Y*72,Back_color);
|
|
Display_grad_block_in_window(264,93,block_start,block_end);
|
|
|
|
Update_rect(Window_pos_X+8*Menu_factor_X,Window_pos_Y+82*Menu_factor_Y,Menu_factor_X*16*10,Menu_factor_Y*5*16);
|
|
|
|
Display_cursor();
|
|
need_to_remp=0;
|
|
}
|
|
}
|
|
}
|
|
while ((clicked_button!=13) && (clicked_button!=14));
|
|
|
|
if (clicked_button==14) // Sortie par OK
|
|
{
|
|
if ( (!image_is_backed_up)
|
|
&& memcmp(Main_palette,working_palette,sizeof(T_Palette)) )
|
|
Backup();
|
|
memcpy(Main_palette,working_palette,sizeof(T_Palette));
|
|
}
|
|
|
|
Compute_optimal_menu_colors(Main_palette);
|
|
|
|
// La variable employée ici n'a pas vraiment de rapport avec son nom...
|
|
need_to_remp=(Window_pos_Y+(Window_height*Menu_factor_Y)<Menu_Y_before_window);
|
|
|
|
Close_window();
|
|
Unselect_bouton(BUTTON_PALETTE);
|
|
|
|
Reposition_palette();
|
|
|
|
// On affiche les "ForeBack" car le menu n'est raffiché que si la fenêtre
|
|
// empiétait sur le menu. Mais si les couleurs on été modifiées, il faut
|
|
// rafficher tout le menu remappé.
|
|
if (need_to_remp)
|
|
Display_menu();
|
|
|
|
Display_cursor();
|
|
|
|
if (clicked_button==13) // Sortie par CANCEL
|
|
{
|
|
Set_palette(Main_palette);
|
|
if (image_is_backed_up)
|
|
Unselect_button(BUTTON_UNDO,LEFT_SIDE);
|
|
}
|
|
|
|
free(backup_palette);
|
|
free(temp_palette);
|
|
free(working_palette);
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------- Menu de palettes secondaires ------------------------
|
|
|
|
void Button_Secondary_palette(void)
|
|
{
|
|
short clicked_button;
|
|
byte dummy;
|
|
T_Scroller_button * columns_slider;
|
|
T_Scroller_button * lines_slider;
|
|
T_Scroller_button * rgb_scale_slider;
|
|
char str[4];
|
|
byte palette_vertical = Config.Palette_vertical;
|
|
byte palette_needs_redraw=0;
|
|
|
|
Open_window(200,146,"Palettes");
|
|
|
|
Window_set_normal_button(10,20,180,14,"Colors for best match",12,1,SDLK_b); // 1
|
|
Window_set_normal_button(10,37,180,14,"User's color series" ,14,0,SDLK_s); // 2
|
|
Window_set_normal_button(139,126,53,14,"OK" , 0,1,SDLK_RETURN); // 3
|
|
Window_set_normal_button( 80,126,53,14,"Cancel" , 0,1,KEY_ESC); // 4
|
|
Window_display_frame(10,55,122,66);
|
|
Print_in_window(18,59,"Palette layout",MC_Dark,MC_Light);
|
|
Print_in_window(35,77,"Cols",MC_Dark,MC_Light);
|
|
Print_in_window(84,77,"Lines",MC_Dark,MC_Light);
|
|
Print_in_window(157,66,"RGB",MC_Dark,MC_Light);
|
|
Print_in_window(152,76,"Scale",MC_Dark,MC_Light);
|
|
|
|
columns_slider = Window_set_scroller_button(19,72,29,255,1,256-Config.Palette_cells_X);// 5
|
|
Num2str(Config.Palette_cells_X,str,3);
|
|
Print_in_window(38,89,str,MC_Black,MC_Light);
|
|
|
|
lines_slider = Window_set_scroller_button(70,72,29,15,1,16-Config.Palette_cells_Y);// 6
|
|
Num2str(Config.Palette_cells_Y,str,3);
|
|
Print_in_window(94,89,str,MC_Black,MC_Light);
|
|
|
|
rgb_scale_slider = Window_set_scroller_button(137,73,29,254,1,256-RGB_scale);// 7
|
|
Num2str(RGB_scale,str,3);
|
|
Print_in_window(157,89,str,MC_Black,MC_Light);
|
|
|
|
Window_set_normal_button(35,106,13,11,"",-1,1,SDLK_LAST); // 8
|
|
Print_in_window(38,108,(palette_vertical)?"X":" ",MC_Black,MC_Light);
|
|
Print_in_window(51,108,"Vertical",MC_Dark,MC_Light);
|
|
|
|
Update_rect(Window_pos_X,Window_pos_Y,Menu_factor_X*200,Menu_factor_Y*80);
|
|
|
|
Display_cursor();
|
|
|
|
do
|
|
{
|
|
clicked_button=Window_clicked_button();
|
|
if (Is_shortcut(Key,0x100+BUTTON_HELP))
|
|
{
|
|
Key=0;
|
|
Window_help(BUTTON_PALETTE, "PALETTE OPTIONS");
|
|
}
|
|
switch(clicked_button)
|
|
{
|
|
case 5:
|
|
Num2str(256-Window_attribute2,str,3);
|
|
Print_in_window(38,89,str,MC_Black,MC_Light);
|
|
break;
|
|
case 6:
|
|
Num2str(16-Window_attribute2,str,3);
|
|
Print_in_window(94,89,str,MC_Black,MC_Light);
|
|
break;
|
|
case 7:
|
|
Num2str(256-Window_attribute2,str,3);
|
|
Print_in_window(157,89,str,MC_Black,MC_Light);
|
|
break;
|
|
case 8:
|
|
palette_vertical = !palette_vertical;
|
|
Hide_cursor();
|
|
Print_in_window(38,108,(palette_vertical)?"X":" ",MC_Black,MC_Light);
|
|
Display_cursor();
|
|
break;
|
|
}
|
|
}
|
|
while (clicked_button!=1 && clicked_button!=3 && clicked_button!=4);
|
|
|
|
Close_window();
|
|
Unselect_bouton(BUTTON_PALETTE);
|
|
Display_cursor();
|
|
|
|
if (clicked_button==4) // Cancel
|
|
return;
|
|
|
|
if (palette_vertical != Config.Palette_vertical)
|
|
{
|
|
Config.Palette_vertical=palette_vertical;
|
|
palette_needs_redraw=1;
|
|
}
|
|
if (columns_slider->Position!=256-Config.Palette_cells_X ||
|
|
lines_slider->Position!=16-Config.Palette_cells_Y)
|
|
{
|
|
Config.Palette_cells_X = 256-columns_slider->Position;
|
|
Config.Palette_cells_Y = 16-lines_slider->Position;
|
|
palette_needs_redraw=1;
|
|
}
|
|
if (rgb_scale_slider->Position!=256-RGB_scale)
|
|
{
|
|
Set_palette_RGB_scale(256-rgb_scale_slider->Position);
|
|
Set_palette(Main_palette);
|
|
}
|
|
|
|
if (clicked_button==1)
|
|
{
|
|
Menu_tag_colors("Tag colors to exclude",Exclude_color,&dummy,1, NULL);
|
|
}
|
|
if (palette_needs_redraw)
|
|
{
|
|
Change_palette_cells();
|
|
Display_menu();
|
|
Display_sprite_in_menu(BUTTON_PAL_LEFT,18+(Config.Palette_vertical!=0));
|
|
}
|
|
}
|