1
/* vim:expandtab:ts=2 sw=2:
3
/* Grafx2 - The Ultimate 256-color bitmap paint program
5
Copyright 2008 Franck Charlet
6
Copyright 2007-2008 Adrien Destugues
7
Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
9
Grafx2 is free software; you can redistribute it and/or
10
modify it under the terms of the GNU General Public License
11
as published by the Free Software Foundation; version 2
14
Grafx2 is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with Grafx2; if not, see <http://www.gnu.org/licenses/>
22
********************************************************************************
24
Graphical interface management functions (windows, menu, cursor)
28
#include <stdlib.h> // atoi()
29
#include <string.h> // strncpy() strlen()
40
#include "sdlscreen.h"
42
/// Width of one layer button, in pixels before scaling
43
word Layer_button_width = 1;
45
// L'encapsulation tente une perc�e...ou un dernier combat.
47
// Nombre de cellules r�el dans la palette du menu
49
word Palette_cells_X()
54
word Palette_cells_Y()
59
// Affichage d'un pixel dans le menu (si visible)
60
void Pixel_in_menu(word bar, word x, word y, byte color)
62
if (Menu_is_visible && Menu_bars[bar].Visible)
63
Block(x*Menu_factor_X,(y+Menu_bars[bar].Top)*Menu_factor_Y+Menu_Y,Menu_factor_X,Menu_factor_Y,color);
66
// Affichage d'un pixel dans le menu et met a jour la bitmap de skin
67
void Pixel_in_menu_and_skin(word bar, word x, word y, byte color)
69
Pixel_in_menu(bar, x, y, color);
70
Menu_bars[bar].Skin[y*Menu_bars[bar].Skin_width + x] = color;
73
// Affichage d'un pixel dans la fen�tre (la fen�tre doit �tre visible)
74
void Pixel_in_window(word x,word y,byte color)
76
Block((x*Menu_factor_X)+Window_pos_X,(y*Menu_factor_Y)+Window_pos_Y,Menu_factor_X,Menu_factor_Y,color);
79
// Affichage d'un rectangle dans la fen�tre (la fen�tre doit �tre visible)
80
void Window_rectangle(word x_pos,word y_pos,word width,word height,byte color)
82
Block((x_pos*Menu_factor_X)+Window_pos_X,(y_pos*Menu_factor_Y)+Window_pos_Y,width*Menu_factor_X,height*Menu_factor_Y,color);
86
// -- Affichages de diff�rents cadres dans une fen�tre -----------------------
88
// -- Frame g�n�ral avec couleurs param�trables --
90
void Window_display_frame_generic(word x_pos,word y_pos,word width,word height,
91
byte color_tl,byte color_br,byte color_s,byte color_tlc,byte color_brc)
92
// Param�tres de couleurs:
93
// color_tl =Bords Haut et Gauche
94
// color_br =Bords Bas et Droite
95
// color_s =Coins Haut-Droite et Bas-Gauche
96
// color_tlc=Coin Haut-Gauche
97
// color_brc=Coin Bas-Droite
99
// Bord haut (sans les extr�mit�s)
100
Block(Window_pos_X+((x_pos+1)*Menu_factor_X),
101
Window_pos_Y+(y_pos*Menu_factor_Y),
102
(width-2)*Menu_factor_X,Menu_factor_Y,color_tl);
104
// Bord bas (sans les extr�mit�s)
105
Block(Window_pos_X+((x_pos+1)*Menu_factor_X),
106
Window_pos_Y+((y_pos+height-1)*Menu_factor_Y),
107
(width-2)*Menu_factor_X,Menu_factor_Y,color_br);
109
// Bord gauche (sans les extr�mit�s)
110
Block(Window_pos_X+(x_pos*Menu_factor_X),
111
Window_pos_Y+((y_pos+1)*Menu_factor_Y),
112
Menu_factor_X,(height-2)*Menu_factor_Y,color_tl);
114
// Bord droite (sans les extr�mit�s)
115
Block(Window_pos_X+((x_pos+width-1)*Menu_factor_X),
116
Window_pos_Y+((y_pos+1)*Menu_factor_Y),
117
Menu_factor_X,(height-2)*Menu_factor_Y,color_br);
120
Pixel_in_window(x_pos,y_pos,color_tlc);
122
Pixel_in_window(x_pos+width-1,y_pos,color_s);
124
Pixel_in_window(x_pos+width-1,y_pos+height-1,color_brc);
126
Pixel_in_window(x_pos,y_pos+height-1,color_s);
129
// -- Frame dont tout le contour est d'une seule couleur --
131
void Window_display_frame_mono(word x_pos,word y_pos,word width,word height,byte color)
133
Window_display_frame_generic(x_pos,y_pos,width,height,color,color,color,color,color);
136
// -- Frame creux: fonc� en haut-gauche et clair en bas-droite --
138
void Window_display_frame_in(word x_pos,word y_pos,word width,word height)
140
Window_display_frame_generic(x_pos,y_pos,width,height,MC_Dark,MC_White,MC_Light,MC_Dark,MC_White);
143
// -- Frame bomb�: clair en haut-gauche et fonc� en bas-droite --
145
void Window_display_frame_out(word x_pos,word y_pos,word width,word height)
147
Window_display_frame_generic(x_pos,y_pos,width,height,MC_White,MC_Dark,MC_Light,MC_White,MC_Dark);
150
// -- Frame de s�paration: un cadre bomb� dans un cadre creux (3D!!!) --
152
void Window_display_frame(word x_pos,word y_pos,word width,word height)
154
Window_display_frame_in(x_pos,y_pos,width,height);
155
Window_display_frame_out(x_pos+1,y_pos+1,width-2,height-2);
159
//-- Affichages relatifs � la palette dans le menu ---------------------------
161
// -- Affichage des couleurs courante (fore/back) de pinceau dans le menu --
163
void Display_foreback(void)
165
if (Menu_is_visible && Menu_bars[MENUBAR_TOOLS].Visible)
167
Block((MENU_WIDTH-17)*Menu_factor_X,Menu_Y+Menu_factor_Y,Menu_factor_X<<4,Menu_factor_Y*7,Back_color);
168
Block((MENU_WIDTH-13)*Menu_factor_X,Menu_Y+(Menu_factor_Y<<1),Menu_factor_X<<3,Menu_factor_Y*5,Fore_color);
170
Update_rect((MENU_WIDTH-17)*Menu_factor_X,Menu_Y+Menu_factor_Y,Menu_factor_X<<4,Menu_factor_Y*7);
174
/*! Get the top left corner for the palette cell of a color
175
@param index Index of the color, starting at 0 for the top left one. Limited to Menu_cells_X/Menu_cells_Y.
177
word Palette_cell_X(byte index)
179
if (Config.Palette_vertical)
181
return (MENU_WIDTH+1+((index-First_color_in_palette)%Menu_cells_X)*Menu_palette_cell_width)*Menu_factor_X;
185
return (MENU_WIDTH+1+((index-First_color_in_palette)/Menu_cells_Y)*Menu_palette_cell_width)*Menu_factor_X;
189
/*! Get the top left corner for the palette cell of a color
190
@param index Index of the color, starting at 0 for the top left one. Limited to Menu_cells_X/Menu_cells_Y.
192
word Palette_cell_Y(byte index)
194
if (Config.Palette_vertical)
196
return Menu_Y+((1+(((index-First_color_in_palette)/Menu_cells_X)*(Menu_bars[MENUBAR_TOOLS].Height/Menu_cells_Y)))*Menu_factor_Y);
200
return Menu_Y+((1+(((index-First_color_in_palette)%Menu_cells_Y)*(Menu_bars[MENUBAR_TOOLS].Height/Menu_cells_Y)))*Menu_factor_Y);
204
void Set_fore_color(byte color)
206
byte old_fore_color = Fore_color;
209
Reposition_palette();
211
Frame_menu_color(old_fore_color);
212
Frame_menu_color(Fore_color);
215
void Set_back_color(byte color)
217
byte old_back_color = Back_color;
221
Frame_menu_color(old_back_color);
222
Frame_menu_color(Back_color);
226
/// Redraw the cell in the menu palette for ::Fore_color.
227
/// This function checks bounds, it won't draw anything if Fore_color is not visible.
228
/// @param id: Color number to frame
229
void Frame_menu_color(byte id)
231
word start_x,start_y,end_x,end_y;
233
word cell_height=Menu_bars[MENUBAR_TOOLS].Height/Menu_cells_Y;
236
if (! Menu_bars[MENUBAR_TOOLS].Visible)
241
else if (id==Back_color)
246
if ((id>=First_color_in_palette) && (id<First_color_in_palette+Menu_cells_X*Menu_cells_Y) && (Menu_is_visible))
248
if (Config.Separate_colors)
250
start_x=Palette_cell_X(id)-1*Menu_factor_X;
251
start_y=Palette_cell_Y(id)-1*Menu_factor_Y;
253
// TODO: if color is black, we are unselecting a color. If another color next to it is selected, we
254
// will erase one edge of its selection square.
255
// We should check for that here.
256
// But we have to find which color is above and below (not so easy) and for the horizontal, check we
257
// are not at the edge of the palette. This makes a lot of cases to handle.
259
Block(start_x,start_y,(Menu_palette_cell_width+1)*Menu_factor_X,Menu_factor_Y,color);
261
Block(start_x,start_y+cell_height*Menu_factor_Y,(Menu_palette_cell_width+1)*Menu_factor_X,Menu_factor_Y,color);
264
Block(start_x,start_y+Menu_factor_Y,Menu_factor_X,(cell_height -1)* Menu_factor_Y,color);
266
Block(start_x+(Menu_palette_cell_width*Menu_factor_X),start_y+Menu_factor_Y,Menu_factor_X,(cell_height -1)* Menu_factor_Y,color);
268
Update_rect(start_x,start_y,(Menu_palette_cell_width+1)*Menu_factor_X,(cell_height+1)* Menu_factor_Y);
272
// Not separated colors
273
start_x=Palette_cell_X(id);
274
start_y=Palette_cell_Y(id);
278
// Color is not selected, no dotted lines
279
Block(start_x,start_y,Menu_palette_cell_width*Menu_factor_X,
280
cell_height*Menu_factor_Y,id);
282
Update_rect(start_x,start_y,Menu_palette_cell_width*Menu_factor_X,cell_height*Menu_factor_Y);
286
end_x=Menu_palette_cell_width-1;
292
for (index=0; index<=end_x; index++)
293
Block(start_x+index*Menu_factor_X,start_y,
294
Menu_factor_X,Menu_factor_Y,
295
((index)&1)?color:MC_Black);
297
for (index=1; index<end_y; index++)
298
Block(start_x,start_y+index*Menu_factor_Y,
299
Menu_factor_X,Menu_factor_Y,
300
((index)&1)?color:MC_Black);
302
for (index=1; index<end_y; index++)
303
Block(start_x+end_x*Menu_factor_X,start_y+index*Menu_factor_Y,
304
Menu_factor_X,Menu_factor_Y,
305
((index+end_x)&1)?color:MC_Black);
307
for (index=0; index<=end_x; index++)
308
Block(start_x+index*Menu_factor_X,start_y+end_y*Menu_factor_Y,
309
Menu_factor_X,Menu_factor_Y,
310
((index+end_y)&1)?color:MC_Black);
312
Update_rect(start_x*Menu_factor_X,start_y*Menu_factor_Y,Menu_palette_cell_width*Menu_factor_X,Menu_Y+cell_height*Menu_factor_Y);
318
// -- Afficher la palette dans le menu --
320
void Display_menu_palette(void)
323
byte cell_height=Menu_bars[MENUBAR_TOOLS].Height/Menu_cells_Y;
324
// width: Menu_palette_cell_width
326
if (Menu_is_visible && Menu_bars[MENUBAR_TOOLS].Visible)
329
Menu_bars[MENUBAR_TOOLS].Width*Menu_factor_X,
331
Screen_width-(Menu_bars[MENUBAR_TOOLS].Width*Menu_factor_X),
332
(Menu_bars[MENUBAR_TOOLS].Height)*Menu_factor_Y,
335
if (Config.Separate_colors)
336
for (color=First_color_in_palette;color<256&&(color-First_color_in_palette)<Menu_cells_X*Menu_cells_Y;color++)
337
Block(Palette_cell_X(color),
338
Palette_cell_Y(color),
339
(Menu_palette_cell_width-1)*Menu_factor_X,
340
(cell_height-1)*Menu_factor_Y,
343
for (color=First_color_in_palette;color<256&&color-First_color_in_palette<Menu_cells_X*Menu_cells_Y;color++)
344
Block(Palette_cell_X(color),
345
Palette_cell_Y(color),
346
Menu_palette_cell_width*Menu_factor_X,
347
cell_height * Menu_factor_Y,
350
Frame_menu_color(Back_color);
351
Frame_menu_color(Fore_color);
352
Update_rect(MENU_WIDTH*Menu_factor_X,Menu_Y,Screen_width-(MENU_WIDTH*Menu_factor_X),(Menu_height-11)*Menu_factor_Y);
356
// -- Recalculer l'origine de la palette dans le menu pour rendre la
357
// Fore_color visible --
359
void Reposition_palette(void)
361
byte old_color=First_color_in_palette;
363
if (Config.Palette_vertical)
369
if (Fore_color<First_color_in_palette)
371
while (Fore_color<First_color_in_palette)
372
First_color_in_palette-=cells;
376
while (Fore_color>=First_color_in_palette+Menu_cells_X*Menu_cells_Y)
377
First_color_in_palette+=cells;
379
if (old_color!=First_color_in_palette)
380
Display_menu_palette();
383
void Change_palette_cells()
385
// On initialise avec la configuration de l'utilisateur
386
Menu_cells_X=Config.Palette_cells_X;
387
Menu_cells_Y=Config.Palette_cells_Y;
388
// Mais on sait jamais
396
Menu_palette_cell_width = ((Screen_width/Menu_factor_X)-(MENU_WIDTH+2)) / Menu_cells_X;
398
// Si �a tient, c'est bon. Sinon, on retente avec une colonne de moins
399
if (Menu_palette_cell_width>2)
404
// Cale First_color_in_palette sur un multiple du nombre de cellules (arrondi inf�rieur)
405
if (Config.Palette_vertical)
406
First_color_in_palette=First_color_in_palette/Menu_cells_X*Menu_cells_X;
408
First_color_in_palette=First_color_in_palette/Menu_cells_Y*Menu_cells_Y;
410
// Si le nombre de cellules a beaucoup augment� et qu'on �tait pr�s de
411
// la fin, il faut reculer First_color_in_palette pour montrer plein
413
if ((int)First_color_in_palette+(Menu_cells_Y)*Menu_cells_X*2>=256)
414
First_color_in_palette=255/Menu_cells_Y*Menu_cells_Y-(Menu_cells_X-1)*Menu_cells_Y;
416
// Mise � jour de la taille du bouton dans le menu. C'est pour pas que
417
// la bordure noire soit active.
418
Buttons_Pool[BUTTON_CHOOSE_COL].Width=(Menu_palette_cell_width*Menu_cells_X)-1;
419
Buttons_Pool[BUTTON_CHOOSE_COL].Height=(Menu_height-11)/Menu_cells_Y*Menu_cells_Y-1;
422
// Retrouve la couleur sur laquelle pointe le curseur souris.
423
// Cette fonction suppose qu'on a d�ja v�rifi� que le curseur est dans
424
// la zone rectangulaire du BUTTON_CHOOSE_COL
425
// La fonction renvoie -1 si on est "trop � gauche" (pas possible)
426
// ou apr�s la couleur 255 (Ce qui peut arriver si la palette est affich�e
427
// avec un nombre de lignes qui n'est pas une puissance de deux.)
428
int Pick_color_in_palette()
434
line=(((Mouse_Y-Menu_Y)/Menu_factor_Y)-2)/((Menu_bars[MENUBAR_TOOLS].Height)/Menu_cells_Y);
435
column=(((Mouse_X/Menu_factor_X)-(MENU_WIDTH+1))/Menu_palette_cell_width);
436
if (Config.Palette_vertical)
438
color=First_color_in_palette+line*Menu_cells_X+column;
442
color=First_color_in_palette+line+column*Menu_cells_Y;
444
if (color<0 || color>255)
449
/// Draws a solid textured area, to the right of a toolbar.
450
void Draw_bar_remainder(word current_menu, word x_off)
455
for (y_pos=0;y_pos<Menu_bars[current_menu].Height;y_pos++)
456
for (x_pos=x_off;x_pos<Screen_width/Menu_factor_X;x_pos++)
457
Pixel_in_menu(current_menu, x_pos, y_pos, Menu_bars[current_menu].Skin[y_pos * Menu_bars[current_menu].Skin_width + Menu_bars[current_menu].Skin_width - 2 + (x_pos&1)]);
461
/// Display / update the layer menubar
462
void Display_layerbar(void)
465
word button_width = LAYER_SPRITE_WIDTH;
466
word button_number = Main_backups->Pages->Nb_layers;
471
if (! Menu_bars[MENUBAR_LAYERS].Visible)
474
// Available space in pixels
475
horiz_space = Screen_width / Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width;
477
// Don't display all buttons if not enough room
478
if (horiz_space/button_width < button_number)
479
button_number = horiz_space/button_width;
480
// Only 16 icons at the moment
481
if (button_number > 16) // can be different from MAX_NB_LAYERS
484
// Enlarge the buttons themselves if there's enough room
485
while (button_number*(button_width+2) < horiz_space && repeats < 20)
491
x_off=Menu_bars[MENUBAR_LAYERS].Skin_width;
492
for (current_button=0; current_button<button_number; current_button++)
498
if (Main_current_layer == current_button)
500
else if (Main_layers_visible & (1 << current_button))
506
for (y_pos=0;y_pos<LAYER_SPRITE_HEIGHT;y_pos++)
510
for (source_x=0;source_x<LAYER_SPRITE_WIDTH;source_x++)
514
// This stretches a button, by duplicating the 2nd from right column
515
// and 3rd column from left.
516
if (source_x == 1 || (source_x == LAYER_SPRITE_WIDTH-3))
521
Pixel_in_menu(MENUBAR_LAYERS, x_pos + x_off, y_pos, Gfx->Layer_sprite[sprite_index][current_button][y_pos][source_x]);
531
// Texture any remaining space to the right.
532
// This overwrites any junk like deleted buttons.
533
Draw_bar_remainder(MENUBAR_LAYERS, x_off);
535
// Update the active area of the layers pseudo-button
536
Buttons_Pool[BUTTON_LAYER_SELECT].Width = button_number * button_width;
538
// Required to determine which layer button is clicked
539
Layer_button_width = button_width;
541
// A screen refresh required by some callers
543
Menu_bars[MENUBAR_LAYERS].Skin_width,
544
Menu_Y+Menu_bars[MENUBAR_LAYERS].Top*Menu_factor_Y,
545
horiz_space*Menu_factor_X,
546
Menu_bars[MENUBAR_LAYERS].Height*Menu_factor_Y);
550
/// Display the whole menu
551
void Display_menu(void)
561
// display menu sprite
562
for (current_menu = MENUBAR_COUNT - 1; current_menu >= 0; current_menu --)
564
if(Menu_bars[current_menu].Visible)
567
for (y_pos=0;y_pos<Menu_bars[current_menu].Height;y_pos++)
568
for (x_pos=0;x_pos<Menu_bars[current_menu].Skin_width;x_pos++)
569
Pixel_in_menu(current_menu, x_pos, y_pos, Menu_bars[current_menu].Skin[y_pos * Menu_bars[current_menu].Skin_width + x_pos]);
571
if (current_menu == MENUBAR_LAYERS)
573
// The layerbar has its own display, for the whole length.
578
// If some area is remaining to the right, texture it with a copy of
579
// the last two columns
580
Draw_bar_remainder(current_menu, Menu_bars[current_menu].Skin_width);
588
Display_menu_palette();
590
// Display selected colors
596
if ((Mouse_Y<Menu_Y) && // Mouse in the picture area
597
( (!Main_magnifier_mode) || (Mouse_X<Main_separator_position) || (Mouse_X>=Main_X_zoom) ))
599
// Prepare display of XY coordinates even if in some cases they will be
600
// erased with some other text
601
if ( (Current_operation!=OPERATION_COLORPICK)
602
&& (Current_operation!=OPERATION_REPLACE) )
603
Print_in_menu("X: Y: ",0);
606
// The colorpicker display the color id between the parentheses
607
Print_in_menu("X: Y: ( )",0);
608
Num2str(Colorpicker_color,str,3);
609
Print_in_menu(str,20);
610
Print_general(170*Menu_factor_X,Menu_status_Y," ",0,Colorpicker_color);
616
// Now update the area: menu height and whole screen width (including palette)
617
Update_rect(0,Menu_Y,Screen_width,Menu_height*Menu_factor_Y);
621
// -- Affichage de texte -----------------------------------------------------
623
// -- Afficher une cha�ne n'importe o� � l'�cran --
625
void Print_general(short x,short y,const char * str,byte text_color,byte background_color)
633
byte repeat_menu_x_factor;
634
byte repeat_menu_y_factor;
637
for (y_pos=0;y_pos<8<<3;y_pos+=1<<3)
639
real_x=0; // Position dans le buffer
640
for (index=0;str[index]!='\0';index++)
642
// Pointeur sur le premier pixel du caract�re
643
font_pixel=Menu_font+(((unsigned char)str[index])<<6);
644
for (x_pos=0;x_pos<8;x_pos+=1)
645
for (repeat_menu_x_factor=0;repeat_menu_x_factor<Menu_factor_X*Pixel_width;repeat_menu_x_factor++)
646
Horizontal_line_buffer[real_x++]=*(font_pixel+x_pos+y_pos)?text_color:background_color;
648
for (repeat_menu_y_factor=0;repeat_menu_y_factor<Menu_factor_Y;repeat_menu_y_factor++)
649
Display_line_fast(x,real_y++,index*Menu_factor_X*8,Horizontal_line_buffer);
653
/// Draws a char in a window
654
void Print_char_in_window(short x_pos,short y_pos,const unsigned char c,byte text_color,byte background_color)
658
x_pos=(x_pos*Menu_factor_X)+Window_pos_X;
659
y_pos=(y_pos*Menu_factor_Y)+Window_pos_Y;
660
// Premier pixel du caract�re
661
pixel=Menu_font + (c<<6);
665
Block(x_pos+(x*Menu_factor_X), y_pos+(y*Menu_factor_Y),
666
Menu_factor_X, Menu_factor_Y,
667
(*(pixel++)?text_color:background_color));
670
///Draws a char in a window, checking for bounds
671
void Print_in_window_limited(short x,short y,const char * str,byte size,byte text_color,byte background_color)
673
char display_string[256];
674
strncpy(display_string, str, size);
675
display_string[size]='\0';
677
if (strlen(str) > size)
679
display_string[size-1]=ELLIPSIS_CHARACTER;
681
Print_in_window(x, y, display_string, text_color, background_color);
684
/// Draws a string in a window
685
void Print_in_window(short x,short y,const char * str,byte text_color,byte background_color)
687
Print_general((x*Menu_factor_X)+Window_pos_X,
688
(y*Menu_factor_Y)+Window_pos_Y,
689
str,text_color,background_color);
690
Update_rect(x*Menu_factor_X+Window_pos_X,y*Menu_factor_Y+Window_pos_Y,8*Menu_factor_X*strlen(str),8*Menu_factor_Y);
693
// Draws a string in the menu's status bar
694
void Print_in_menu(const char * str, short position)
696
Print_general((18+(position<<3))*Menu_factor_X,Menu_status_Y,str,MC_Black,MC_Light);
697
Update_rect((18+(position<<3))*Menu_factor_X,Menu_status_Y,strlen(str)*8*Menu_factor_X,8*Menu_factor_Y);
700
/// Draws the mouse coordinates on the menu
701
/// Only update the digits and doesn't refresh the "X: Y:" labels. This function needs to be fast as it is called each time the mouse moves.
702
void Print_coordinates(void)
706
if (Menu_is_visible && !Cursor_in_menu)
708
if ( (Current_operation==OPERATION_COLORPICK)
709
|| (Current_operation==OPERATION_REPLACE) )
711
if ( (Paintbrush_X>=0) && (Paintbrush_Y>=0)
712
&& (Paintbrush_X<Main_image_width)
713
&& (Paintbrush_Y<Main_image_height) )
714
Colorpicker_color=Read_pixel_from_current_screen(Paintbrush_X,Paintbrush_Y);
717
Colorpicker_X=Paintbrush_X;
718
Colorpicker_Y=Paintbrush_Y;
720
Num2str(Colorpicker_color,temp,3);
721
Print_in_menu(temp,20);
722
Print_general(170*Menu_factor_X,Menu_status_Y," ",0,Colorpicker_color);
723
Update_rect(170*Menu_factor_X,Menu_status_Y,8*Menu_factor_X,8*Menu_factor_Y);
726
Num2str((dword)Paintbrush_X,temp,4);
727
Print_in_menu(temp,2);
728
Num2str((dword)Paintbrush_Y,temp,4);
729
Print_in_menu(temp,11);
733
// -- Afficher le nom du fichier dans le menu --
735
void Print_filename(void)
739
char display_string[256];
741
// Determine maximum size, in characters
742
max_size = 12 + (Screen_width / Menu_factor_X - 320) / 8;
744
string_size = strlen(Main_backups->Pages->Filename);
746
// Partial copy of the name
747
strncpy(display_string, Main_backups->Pages->Filename, max_size);
748
display_string[max_size]='\0';
750
if (string_size > max_size)
752
string_size = max_size;
753
display_string[string_size-1]=ELLIPSIS_CHARACTER;
756
Block(Screen_width-max_size*8*Menu_factor_X,
757
Menu_status_Y,Menu_factor_X*max_size*8,Menu_factor_Y<<3,MC_Light);
759
Print_general(Screen_width-(string_size<<3)*Menu_factor_X,Menu_status_Y,display_string,MC_Black,MC_Light);
762
// Fonction d'affichage d'une chaine num�rique avec une fonte tr�s fine
763
// Sp�cialis�e pour les compteurs RGB
764
void Print_counter(short x,short y,const char * str,byte text_color,byte background_color)
766
// Macros pour �crire des litteraux binaires.
767
// Ex: Ob(11110000) == 0xF0
768
#define Ob(x) ((unsigned)Ob_(0 ## x ## uL))
769
#define Ob_(x) ((x & 1) | (x >> 2 & 2) | (x >> 4 & 4) | (x >> 6 & 8) | \
770
(x >> 8 & 16) | (x >> 10 & 32) | (x >> 12 & 64) | (x >> 14 & 128))
772
byte thin_font[14][8] = {
917
for (index=0;str[index]!='\0';index++)
932
char_number=str[index]-'0';
948
for (y_pos=0;y_pos<8;y_pos++)
950
for (x_pos=0;x_pos<6;x_pos++)
952
byte color = (thin_font[char_number][y_pos] & (1 << (6-x_pos))) ? text_color:background_color;
953
Pixel_in_window(x+(index*6+x_pos),y+y_pos,color);
957
Update_rect(Window_pos_X+x*Menu_factor_X,Window_pos_Y+y*Menu_factor_Y,strlen(str)*Menu_factor_X*6,8*Menu_factor_Y);
963
/// Window asking for confirmation before an action is performed.
964
/// This function is able to display multi-line messages and
965
/// center the lines, but the carriage returns have to be explicit.
966
/// The function will clip the message in case of problem.
967
/// @return 1 if user pressed OK, 0 if CANCEL
968
byte Confirmation_box(char * message)
970
short clicked_button;
971
word window_width = 120;
973
const char *c = message;
974
short current_length=0;
977
// Count lines, and measure max line length
978
for (c=message; *c != '\0'; c++)
988
window_width=Max(window_width, (current_length<<3)+20);
992
if (window_width>310)
995
Open_window(window_width,52+(nb_lines<<3),"Confirmation");
998
for (current_line=0; current_line < nb_lines; current_line++)
1001
char display_string[36+1];
1003
next_eol = strchr(c, '\n');
1004
if (next_eol==NULL) // last line
1005
current_length = strlen(c);
1007
current_length = next_eol-c;
1010
if (current_length>36)
1012
// Copy part of string in null-terminated buffer
1013
strncpy(display_string, c, current_length);
1014
display_string[current_length]='\0';
1016
Print_in_window((window_width>>1)-(current_length<<2), 20+(current_line<<3), display_string, MC_Black, MC_Light);
1018
c += current_length;
1023
Window_set_normal_button((window_width/3)-20 ,29+(nb_lines<<3),40,14,"Yes",1,1,SDLK_y); // 1
1024
Window_set_normal_button(((window_width<<1)/3)-20,29+(nb_lines<<3),40,14,"No" ,1,1,SDLK_n); // 2
1026
Update_rect(Window_pos_X, Window_pos_Y, Window_width*Menu_factor_X, Window_height*Menu_factor_Y);
1032
clicked_button=Window_clicked_button();
1033
if (Key==SDLK_RETURN) clicked_button=1;
1034
if (Key==KEY_ESC) clicked_button=2;
1036
while (clicked_button<=0);
1042
return (clicked_button==1)? 1 : 0;
1046
/// Window that allows you to enter a single value
1047
int Requester_window(char* message, int initial_value)
1049
short clicked_button = 0;
1053
window_width=(strlen(message)<<3)+20;
1055
if (window_width<120)
1058
Open_window(window_width, 60, "Request");
1060
Print_in_window((window_width>>1)-(strlen(message)<<2), 20, message,
1061
MC_Black, MC_Light);
1062
sprintf(str, "%d", initial_value);
1063
Window_set_input_button(10, 37, 4); // 1
1064
Print_in_window(11, 39, str, MC_Black, MC_Light);
1065
Window_set_normal_button(60 ,37,40,14,"OK",1,1,SDLK_y); // 2
1066
Window_set_normal_button(130,37,60,14,"Cancel" ,1,1,SDLK_n); // 3
1068
Update_rect(Window_pos_X, Window_pos_Y, Menu_factor_X * window_width,
1069
Menu_factor_Y * 60);
1074
clicked_button = Window_clicked_button();
1075
if (clicked_button == 1)
1076
Readline(11, 39, str, 4, 1);
1077
if (Key == SDLK_ESCAPE) clicked_button = 2;
1079
while (clicked_button <= 0);
1086
return clicked_button==2?-1:atoi(str);
1090
/// Window that show a warning message and wait for a click on the OK button
1091
void Warning_message(char * message)
1093
short clicked_button;
1096
window_width=(strlen(message)<<3)+20;
1097
if (window_width<120)
1100
Open_window(window_width,60,"Warning!");
1102
Print_in_window((window_width>>1)-(strlen(message)<<2),20,message,MC_Black,MC_Light);
1103
Window_set_normal_button((window_width>>1)-20 ,37,40,14,"OK",1,1,SDLK_RETURN); // 1
1104
Update_rect(Window_pos_X,Window_pos_Y,Menu_factor_X*window_width,Menu_factor_Y*60);
1108
clicked_button=Window_clicked_button();
1109
while ((clicked_button<=0) && (Key!=KEY_ESC) && (Key!=SDLK_o));
1116
/// Window that shows a big message (up to 34x12), and waits for a click on OK.
1117
/// On call: Cursor must be displayed
1118
/// On exit: Cursor is displayed
1119
void Verbose_message(const char *caption, const char * message )
1121
short clicked_button;
1126
byte original_cursor_shape = Cursor_shape;
1129
Open_window(300,160,caption);
1131
// Word-wrap the message
1132
for (line=0; line < 12 && *message!='\0'; line++)
1135
for (nb_char=0; nb_char<35 && message[nb_char]!='\0'; nb_char++)
1137
buffer[nb_char]=message[nb_char];
1138
if (message[nb_char] == ' ')
1140
last_space = nb_char;
1142
else if (message[nb_char] == '\n')
1144
last_space = nb_char;
1148
// Close line buffer
1149
if (message[nb_char]=='\0' || last_space == -1)
1150
last_space = nb_char;
1151
buffer[last_space]='\0';
1154
Print_in_window(10,20+line*8,buffer,MC_Black,MC_Light);
1157
message=message+last_space;
1158
// Strip at most one carriage return and any leading spaces
1159
if (*message == '\n')
1161
while (*message == ' ')
1165
Window_set_normal_button(300/2-20,160-23,40,14,"OK",1,1,SDLK_RETURN); // 1
1166
Update_window_area(0,0,Window_width,Window_height);
1167
Cursor_shape=CURSOR_SHAPE_ARROW;
1171
clicked_button=Window_clicked_button();
1172
while ((clicked_button<=0) && (Key!=KEY_ESC) && (Key!=SDLK_o));
1176
Cursor_shape=original_cursor_shape;
1180
// -- Redessiner le sprite d'un bouton dans le menu --
1182
void Display_sprite_in_menu(int btn_number,int sprite_number)
1190
menu_y_pos=Buttons_Pool[btn_number].Y_offset;
1191
menu_x_pos=Buttons_Pool[btn_number].X_offset;
1192
if (Buttons_Pool[btn_number].Shape != BUTTON_SHAPE_TRIANGLE_BOTTOM_RIGHT)
1198
for (y_pos=0;y_pos<MENU_SPRITE_HEIGHT;y_pos++)
1199
for (x_pos=0;x_pos<MENU_SPRITE_WIDTH;x_pos++)
1201
color=Gfx->Menu_sprite[sprite_number][y_pos][x_pos];
1202
Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos+x_pos, menu_y_pos+y_pos, color);
1204
if (Menu_is_visible && Menu_bars[MENUBAR_TOOLS].Visible)
1205
Update_rect(Menu_factor_X*(Buttons_Pool[btn_number].X_offset+1),
1206
(Buttons_Pool[btn_number].Y_offset+1+Menu_bars[MENUBAR_TOOLS].Top)*Menu_factor_Y+Menu_Y,
1207
MENU_SPRITE_WIDTH*Menu_factor_X,MENU_SPRITE_HEIGHT*Menu_factor_Y);
1210
// -- Redessiner la forme du pinceau dans le menu --
1212
void Display_paintbrush_in_menu(void)
1216
short menu_x_pos,menu_y_pos;
1220
switch (Paintbrush_shape)
1222
case PAINTBRUSH_SHAPE_COLOR_BRUSH : // Brush en couleur
1223
case PAINTBRUSH_SHAPE_MONO_BRUSH : // Brush monochrome
1224
for (menu_y_pos=2,y_pos=0;y_pos<MENU_SPRITE_HEIGHT;menu_y_pos++,y_pos++)
1225
for (menu_x_pos=1,x_pos=0;x_pos<MENU_SPRITE_WIDTH;menu_x_pos++,x_pos++)
1227
color=Gfx->Menu_sprite[4][y_pos][x_pos];
1228
Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos, menu_y_pos, color);
1231
default : // Pinceau
1232
// On efface le pinceau pr�c�dent
1233
for (menu_y_pos=2,y_pos=0;y_pos<MENU_SPRITE_HEIGHT;menu_y_pos++,y_pos++)
1234
for (menu_x_pos=1,x_pos=0;x_pos<MENU_SPRITE_WIDTH;menu_x_pos++,x_pos++)
1236
Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos, menu_y_pos, MC_Light);
1238
// On affiche le nouveau
1239
menu_start_x=8-Paintbrush_offset_X;
1242
start_x=Paintbrush_offset_X-7;
1248
menu_y_pos=9-Paintbrush_offset_Y;
1251
y_pos=Paintbrush_offset_Y-7;
1257
for (;((y_pos<Paintbrush_height) && (menu_y_pos<16));menu_y_pos++,y_pos++)
1258
for (menu_x_pos=menu_start_x,x_pos=start_x;((x_pos<Paintbrush_width) && (menu_x_pos<15));menu_x_pos++,x_pos++)
1260
color=(Paintbrush_sprite[(y_pos*MAX_PAINTBRUSH_SIZE)+x_pos])?MC_Black:MC_Light;
1261
Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos, menu_y_pos, color);
1264
if (Menu_is_visible && Menu_bars[MENUBAR_TOOLS].Visible)
1265
Update_rect(0,Menu_Y + Menu_bars[MENUBAR_TOOLS].Top*Menu_factor_Y,MENU_SPRITE_WIDTH*Menu_factor_X+3,MENU_SPRITE_HEIGHT*Menu_factor_Y+3);
1268
// -- Dessiner un pinceau pr�d�fini dans la fen�tre --
1270
void Display_paintbrush_in_window(word x,word y,int number)
1271
// Pinceau = 0..NB_PAINTBRUSH_SPRITES-1 : Pinceau pr�d�fini
1282
x_size=Menu_factor_X/Pixel_height;
1285
y_size=Menu_factor_Y/Pixel_width;
1289
origin_x = (x + 8)*Menu_factor_X - (Gfx->Preset_paintbrush_offset_X[number])*x_size+Window_pos_X;
1290
origin_y = (y + 8)*Menu_factor_Y - (Gfx->Preset_paintbrush_offset_Y[number])*y_size+Window_pos_Y;
1292
for (window_y_pos=0,y_pos=0; y_pos<Gfx->Preset_paintbrush_height[number]; window_y_pos++,y_pos++)
1293
for (window_x_pos=0,x_pos=0; x_pos<Gfx->Preset_paintbrush_width[number]; window_x_pos++,x_pos++)
1294
Block(origin_x+window_x_pos*x_size,origin_y+window_y_pos*y_size,x_size,y_size,(Gfx->Paintbrush_sprite[number][y_pos][x_pos])?MC_Black:MC_Light);
1295
// On n'utilise pas Pixel_in_window() car on ne dessine pas
1296
// forc�ment avec la m�me taille de pixel.
1298
Update_rect( ToWinX(origin_x), ToWinY(origin_y),
1299
ToWinL(Gfx->Preset_paintbrush_width[number]),
1300
ToWinH(Gfx->Preset_paintbrush_height[number])
1304
// -- Dessiner des zigouigouis --
1306
void Draw_thingumajig(word x,word y, byte color, short direction)
1310
for (i=0; i<11; i++) Pixel_in_window(x,y+i,color);
1312
for (i=1; i<10; i++) Pixel_in_window(x,y+i,color);
1313
x+=direction+direction;
1314
for (i=3; i<8; i++) Pixel_in_window(x,y+i,color);
1315
x+=direction+direction;
1316
Pixel_in_window(x,y+5,color);
1319
// -- Dessiner un bloc de couleurs d�grad� verticalement
1321
void Display_grad_block_in_window(word x_pos,word y_pos,word block_start,word block_end)
1323
word total_lines =Menu_factor_Y<<6; // <=> � 64 lignes fct(Menu_Facteur)
1324
word nb_colors =(block_start<=block_end)?block_end-block_start+1:block_start-block_end+1;
1325
word Selected_line_mode=(block_start<=block_end)?0:total_lines-1;
1327
word start_x =Window_pos_X+(Menu_factor_X*x_pos);
1328
word line_width =Menu_factor_X<<4; // <=> � 16 pixels fct(Menu_Facteur)
1330
word start_y =Window_pos_Y+(Menu_factor_Y*y_pos);
1331
word end_y =start_y+total_lines;
1334
if (block_start>block_end)
1337
block_start=block_end;
1341
for (index=start_y;index<end_y;index++,Selected_line_mode++)
1342
Block(start_x,index,line_width,1,block_start+(nb_colors*Selected_line_mode)/total_lines);
1344
Update_rect(ToWinX(x_pos),ToWinY(y_pos),ToWinL(16),ToWinH(64));
1349
// -- Dessiner un petit sprite repr�sentant le type d'un drive --
1351
void Window_display_icon_sprite(word x_pos,word y_pos,byte type)
1355
for (j=0; j<ICON_SPRITE_HEIGHT; j++)
1356
for (i=0; i<ICON_SPRITE_WIDTH; i++)
1357
Pixel_in_window(x_pos+i,y_pos+j,Gfx->Icon_sprite[type][j][i]);
1358
Update_rect(ToWinX(x_pos),ToWinY(y_pos),ToWinL(ICON_SPRITE_WIDTH),ToWinH(ICON_SPRITE_HEIGHT));
1363
void Display_menu_palette_avoiding_window(byte * table)
1365
// On part du principe qu'il n'y a que le bas d'une fen�tre qui puisse
1366
// empi�ter sur la palette... Et c'est d�j� pas mal!
1367
word color,real_color;
1368
word start_x,start_y;
1372
word corner_x=Window_pos_X+Window_width*Menu_factor_X; // |_ Coin bas-droit
1373
word corner_y=Window_pos_Y+Window_height*Menu_factor_Y; // | de la fen�tre +1
1376
if (Config.Separate_colors)
1378
width=(Menu_palette_cell_width-1)*Menu_factor_X;
1379
height=Menu_factor_Y*((Menu_height-11)/Menu_cells_Y-1);
1383
width=Menu_palette_cell_width*Menu_factor_X;
1384
height=Menu_factor_Y*((Menu_height-11)/Menu_cells_Y);
1387
for (color=0,real_color=First_color_in_palette;color<Menu_cells_X*Menu_cells_Y;color++,real_color++)
1389
if (table[real_color]!=real_color)
1391
start_x=Palette_cell_X(real_color);
1392
start_y=Palette_cell_Y(real_color);
1393
end_x=start_x+width;
1394
end_y=start_y+height;
1396
// On affiche le bloc en entier si on peut, sinon on le d�coupe autour
1398
if ( (start_y>=corner_y) || (end_x<=Window_pos_X) || (start_x>=corner_x) )
1399
Block(start_x,start_y,width,height,real_color);
1403
if (start_x>=Window_pos_X)
1405
if ( (end_x>corner_x) || (end_y>corner_y) )
1407
if ( (end_x>corner_x) && (end_y>corner_y) )
1409
Block(corner_x,start_y,end_x-corner_x,corner_y-start_y,real_color);
1410
Block(start_x,corner_y,width,end_y-corner_y,real_color);
1415
Block(start_x,corner_y,width,end_y-corner_y,real_color);
1417
Block(corner_x,start_y,end_x-corner_x,height,real_color);
1427
Block(start_x,start_y,Window_pos_X-start_x,corner_y-start_y,real_color);
1428
Block(start_x,corner_y,width,end_y-corner_y,real_color);
1431
Block(start_x,start_y,Window_pos_X-start_x,height,real_color);
1437
Block(start_x,start_y,Window_pos_X-start_x,corner_y-start_y,real_color);
1438
Block(corner_x,start_y,end_x-corner_x,corner_y-start_y,real_color);
1439
Block(start_x,corner_y,width,end_y-corner_y,real_color);
1443
Block(start_x,start_y,Window_pos_X-start_x,height,real_color);
1444
Block(corner_x,start_y,end_x-corner_x,height,real_color);
1450
// Affichage du bloc directement dans le "buffer de fond" de la fenetre.
1451
// Cela permet au bloc de couleur d'apparaitre si on d�place la fenetre.
1454
short relative_x; // besoin d'une variable sign�e
1455
short relative_y; // besoin d'une variable sign�e
1456
// Attention aux unit�s
1457
relative_x = ((short)start_x - (short)Window_pos_X);
1458
relative_y = ((short)start_y - (short)Window_pos_Y);
1460
for (y_pos=relative_y;y_pos<(relative_y+height)&&y_pos<Window_height*Menu_factor_Y;y_pos++)
1461
for (x_pos=relative_x;x_pos<(relative_x+width)&&x_pos<Window_width*Menu_factor_X;x_pos++)
1462
if (x_pos>=0&&y_pos>=0)
1463
Pixel_background(x_pos,y_pos,real_color);
1467
Update_rect(MENU_WIDTH*Menu_factor_X,Menu_Y_before_window,Screen_width-(MENU_WIDTH*Menu_factor_X),(Menu_height-11)*Menu_factor_Y);
1470
// -------- Calcul des bornes de la partie d'image visible � l'�cran ---------
1471
void Compute_limits(void)
1473
Avant l'appel � cette fonction, les donn�es de la loupe doivent �tre � jour.
1476
if (Main_magnifier_mode)
1478
// -- Calcul des limites de la partie non zoom�e de l'image --
1479
Limit_top =Main_offset_Y;
1480
Limit_left=Main_offset_X;
1481
Limit_visible_bottom =Limit_top+Menu_Y-1;
1482
Limit_visible_right=Limit_left+Main_separator_position-1;
1484
if (Limit_visible_bottom>=Main_image_height)
1485
Limit_bottom=Main_image_height-1;
1487
Limit_bottom=Limit_visible_bottom;
1489
if (Limit_visible_right>=Main_image_width)
1490
Limit_right=Main_image_width-1;
1492
Limit_right=Limit_visible_right;
1494
// -- Calcul des limites de la partie zoom�e de l'image --
1495
Limit_top_zoom =Main_magnifier_offset_Y;
1496
Limit_left_zoom=Main_magnifier_offset_X;
1497
Limit_visible_bottom_zoom =Limit_top_zoom+Main_magnifier_height-1;
1498
Limit_visible_right_zoom=Limit_left_zoom+Main_magnifier_width-1;
1500
if (Limit_visible_bottom_zoom>=Main_image_height)
1501
Limit_bottom_zoom=Main_image_height-1;
1503
Limit_bottom_zoom=Limit_visible_bottom_zoom;
1505
if (Limit_visible_right_zoom>=Main_image_width)
1506
Limit_right_zoom=Main_image_width-1;
1508
Limit_right_zoom=Limit_visible_right_zoom;
1512
// -- Calcul des limites de la partie visible de l'image --
1513
Limit_top =Main_offset_Y;
1514
Limit_left=Main_offset_X;
1515
Limit_visible_bottom =Limit_top+(Menu_is_visible?Menu_Y:Screen_height)-1; // A REVOIR POUR SIMPLIFICATION
1516
Limit_visible_right=Limit_left+Screen_width-1;
1518
if (Limit_visible_bottom>=Main_image_height)
1519
Limit_bottom=Main_image_height-1;
1521
Limit_bottom=Limit_visible_bottom;
1523
if (Limit_visible_right>=Main_image_width)
1524
Limit_right=Main_image_width-1;
1526
Limit_right=Limit_visible_right;
1531
// -- Calculer les coordonn�es du pinceau en fonction du snap et de la loupe -
1532
void Compute_paintbrush_coordinates(void)
1534
if ((Main_magnifier_mode) && (Mouse_X>=Main_X_zoom))
1536
Paintbrush_X=((Mouse_X-Main_X_zoom)/Main_magnifier_factor)+Main_magnifier_offset_X;
1537
Paintbrush_Y=(Mouse_Y/Main_magnifier_factor)+Main_magnifier_offset_Y;
1541
Paintbrush_X=Mouse_X+Main_offset_X;
1542
Paintbrush_Y=Mouse_Y+Main_offset_Y;
1547
Paintbrush_X=(((Paintbrush_X+(Snap_width>>1)-Snap_offset_X)/Snap_width)*Snap_width)+Snap_offset_X;
1548
Paintbrush_Y=(((Paintbrush_Y+(Snap_height>>1)-Snap_offset_Y)/Snap_height)*Snap_height)+Snap_offset_Y;
1551
// Handling the snap axis mode, when shift is pressed.
1552
switch (Current_operation)
1554
// Operations that don't implement it
1555
case OPERATION_LINE:
1558
// Operations that implement it
1560
if (Snap_axis==0 && (SDL_GetModState() & KMOD_SHIFT))
1562
// Start "Snap axis" mode
1564
Snap_axis_origin_X=Paintbrush_X;
1565
Snap_axis_origin_Y=Paintbrush_Y;
1572
if (Paintbrush_X != Snap_axis_origin_X || Paintbrush_Y != Snap_axis_origin_Y)
1574
if ((Paintbrush_X-Snap_axis_origin_X)*(Paintbrush_X-Snap_axis_origin_X) >
1575
(Paintbrush_Y-Snap_axis_origin_Y)*(Paintbrush_Y-Snap_axis_origin_Y))
1576
// Displacement was bigger on X axis: lock Y
1584
Paintbrush_Y = Snap_axis_origin_Y;
1586
else if (Snap_axis==3)
1588
Paintbrush_X = Snap_axis_origin_X;
1594
// -- Affichage de la limite de l'image -------------------------------------
1595
void Display_image_limits(void)
1600
byte right_is_visible;
1601
byte bottom_is_visible;
1602
short old_zoom_limit;
1604
right_is_visible=Main_image_width<((Main_magnifier_mode)?Main_separator_position:Screen_width);
1605
bottom_is_visible =Main_image_height<Menu_Y;
1608
// On v�rifie que la limite � droite est visible:
1609
if (right_is_visible)
1612
end=(Limit_bottom<Main_image_height)?
1613
Limit_bottom:Main_image_height;
1615
if (bottom_is_visible)
1618
// Juste le temps d'afficher les limites, on �tend les limites de la loupe
1619
// aux limites visibles, car sinon Pixel_preview ne voudra pas afficher.
1620
old_zoom_limit=Limit_right_zoom;
1621
Limit_right_zoom=Limit_visible_right_zoom;
1623
for (pos=start;pos<=end;pos++)
1624
Pixel_preview(Main_image_width,pos,((pos+Main_image_height)&1)?MC_White:MC_Black);
1626
Update_rect(Main_image_width,start,1,end-start + 1);
1627
// On restaure la bonne valeur des limites
1628
Limit_right_zoom=old_zoom_limit;
1631
// On v�rifie que la limite en bas est visible:
1632
if (bottom_is_visible)
1635
end=(Limit_right<Main_image_width)?
1636
Limit_right:Main_image_width;
1638
// On �tend �galement les limites en bas (comme pour la limite droit)
1639
old_zoom_limit=Limit_bottom_zoom;
1640
Limit_bottom_zoom=Limit_visible_bottom_zoom;
1642
for (pos=start;pos<=end;pos++)
1643
Pixel_preview(pos,Main_image_height,((pos+Main_image_height)&1)?MC_White:MC_Black);
1645
Update_rect(start,Main_image_height,end-start + 1,1);
1647
// On restaure la bonne valeur des limites
1648
Limit_bottom_zoom=old_zoom_limit;
1654
// -- Recadrer la partie non-zoom�e de l'image par rapport � la partie zoom�e
1655
// lorsqu'on scrolle en mode Loupe --
1656
void Position_screen_according_to_zoom(void)
1659
if (Main_image_width>Main_separator_position)
1661
Main_offset_X=Main_magnifier_offset_X+(Main_magnifier_width>>1)
1662
-(Main_separator_position>>1);
1663
if (Main_offset_X<0)
1665
else if (Main_image_width<Main_offset_X+Main_separator_position)
1666
Main_offset_X=Main_image_width-Main_separator_position;
1672
if (Main_image_height>Menu_Y)
1674
Main_offset_Y=Main_magnifier_offset_Y+(Main_magnifier_height>>1)
1676
if (Main_offset_Y<0)
1678
else if (Main_image_height<Main_offset_Y+Menu_Y)
1679
Main_offset_Y=Main_image_height-Menu_Y;
1685
// -- Recenter the non-zoomed part of image around a precise pixel
1686
void Position_screen_according_to_position(int target_x, int target_y)
1689
if (Main_image_width>Main_separator_position)
1691
Main_offset_X=target_x-Mouse_X;
1692
// Do not allow the zoomed part to show something that the
1693
// non-zoomed part doesn't see. All clipping is computed according
1694
// to the non-zoomed part.
1695
if (Main_magnifier_offset_X<Main_offset_X)
1696
Main_offset_X=Main_magnifier_offset_X;
1697
else if (Main_magnifier_offset_X+Main_magnifier_width > Main_offset_X+Main_separator_position)
1698
Main_offset_X = Main_magnifier_offset_X+Main_magnifier_width-Main_separator_position;
1699
if (Main_offset_X<0)
1701
else if (Main_image_width<Main_offset_X+Main_separator_position)
1702
Main_offset_X=Main_image_width-Main_separator_position;
1710
if (Main_image_height>Menu_Y)
1712
Main_offset_Y=target_y-Mouse_Y;
1713
// Do not allow the zoomed part to show something that the
1714
// non-zoomed part doesn't see. All clipping is computed according
1715
// to the non-zoomed part.
1716
if (Main_magnifier_offset_Y<Main_offset_Y)
1717
Main_offset_Y=Main_magnifier_offset_Y;
1718
else if (Main_magnifier_offset_Y+Main_magnifier_height > Main_offset_Y)
1719
Main_offset_Y = Main_magnifier_offset_Y+Main_magnifier_height;
1720
if (Main_offset_Y<0)
1722
else if (Main_image_height<Main_offset_Y+Menu_Y)
1723
Main_offset_Y=Main_image_height-Menu_Y;
1730
// - Calcul des donn�es du split en fonction de la proportion de chaque zone -
1731
void Compute_separator_data(void)
1734
short theoric_X=Round(Main_separator_proportion*Screen_width);
1736
Main_X_zoom=Screen_width-(((Screen_width+(Main_magnifier_factor>>1)-theoric_X)/Main_magnifier_factor)*Main_magnifier_factor);
1737
Main_separator_position=Main_X_zoom-(Menu_factor_X*SEPARATOR_WIDTH);
1739
// Correction en cas de d�bordement sur la gauche
1740
while (Main_separator_position*(Main_magnifier_factor+1)<Screen_width-(Menu_factor_X*SEPARATOR_WIDTH))
1742
Main_separator_position+=Main_magnifier_factor;
1743
Main_X_zoom+=Main_magnifier_factor;
1745
// Correction en cas de d�bordement sur la droite
1746
theoric_X=Screen_width-((NB_ZOOMED_PIXELS_MIN-1)*Main_magnifier_factor);
1747
while (Main_X_zoom>=theoric_X)
1749
Main_separator_position-=Main_magnifier_factor;
1750
Main_X_zoom-=Main_magnifier_factor;
1756
// -------------------- Calcul des information de la loupe -------------------
1757
void Compute_magnifier_data(void)
1759
Apr�s modification des donn�es de la loupe, il faut recalculer les limites.
1762
Compute_separator_data();
1764
Main_magnifier_width=(Screen_width-Main_X_zoom)/Main_magnifier_factor;
1766
Main_magnifier_height=Menu_Y/Main_magnifier_factor;
1767
if (Menu_Y%Main_magnifier_factor)
1768
Main_magnifier_height++;
1770
if (Main_magnifier_mode && Main_magnifier_offset_X)
1772
if (Main_image_width<Main_magnifier_offset_X+Main_magnifier_width)
1773
Main_magnifier_offset_X=Main_image_width-Main_magnifier_width;
1774
if (Main_magnifier_offset_X<0) Main_magnifier_offset_X=0;
1776
if (Main_magnifier_mode && Main_magnifier_offset_Y)
1778
if (Main_image_height<Main_magnifier_offset_Y+Main_magnifier_height)
1779
Main_magnifier_offset_Y=Main_image_height-Main_magnifier_height;
1780
if (Main_magnifier_offset_Y<0) Main_magnifier_offset_Y=0;
1786
/// Changes magnifier factor and updates everything needed
1787
void Change_magnifier_factor(byte factor_index, byte point_at_mouse)
1789
int target_x,target_y; // These coordinates are in image space
1790
byte magnified_view_leads=1;
1792
// Values that need to be computed before switching to the new zoom factor
1793
if (!point_at_mouse || Cursor_in_menu || !Main_magnifier_mode)
1795
// Locate the pixel in center of the magnified area
1796
target_x = Main_magnifier_offset_X + (Main_magnifier_width >> 1);
1797
target_y = Main_magnifier_offset_Y + (Main_magnifier_height >> 1);
1800
else if (Mouse_X>=Main_X_zoom)
1802
// Locate the pixel under the cursor, in magnified area
1803
target_x=((Mouse_X-Main_X_zoom)/Main_magnifier_factor)+Main_magnifier_offset_X;
1804
target_y=(Mouse_Y/Main_magnifier_factor)+Main_magnifier_offset_Y;
1809
// Locate the pixel under the cursor, in normal area
1810
target_x=Mouse_X+Main_offset_X;
1811
target_y=Mouse_Y+Main_offset_Y;
1812
magnified_view_leads=0;
1816
Main_magnifier_factor=ZOOM_FACTOR[factor_index];
1817
Compute_magnifier_data();
1819
if (Main_magnifier_mode)
1821
// Recompute the magnifier offset (center its view)
1824
// Target pixel must be located under the mouse position.
1825
Main_magnifier_offset_X = target_x-((Mouse_X-Main_X_zoom)/Main_magnifier_factor);
1826
Main_magnifier_offset_Y = target_y-((Mouse_Y)/Main_magnifier_factor);
1830
// Target pixel must be positioned at new center
1831
Main_magnifier_offset_X = target_x-(Main_magnifier_width>>1);
1832
Main_magnifier_offset_Y = target_y-(Main_magnifier_height>>1);
1834
// Fix cases where the image would overflow on edges
1835
if (Main_magnifier_offset_X+Main_magnifier_width>Main_image_width)
1836
Main_magnifier_offset_X=Main_image_width-Main_magnifier_width;
1837
if (Main_magnifier_offset_Y+Main_magnifier_height>Main_image_height)
1838
Main_magnifier_offset_Y=Main_image_height-Main_magnifier_height;
1839
if (Main_magnifier_offset_X<0)
1840
Main_magnifier_offset_X=0;
1841
if (Main_magnifier_offset_Y<0)
1842
Main_magnifier_offset_Y=0;
1844
if (magnified_view_leads)
1845
Position_screen_according_to_zoom();
1847
Position_screen_according_to_position(target_x, target_y);
1849
Pixel_preview=Pixel_preview_magnifier;
1853
Pixel_preview=Pixel_preview_normal;
1856
Compute_paintbrush_coordinates();
1861
// -- Afficher la barre de s�paration entre les parties zoom�es ou non en
1864
void Display_separator(void)
1866
// Partie grise du milieu
1867
Block(Main_separator_position+(Menu_factor_X<<1),Menu_factor_Y,
1868
(SEPARATOR_WIDTH-4)*Menu_factor_X,
1869
Menu_Y-(Menu_factor_Y<<1),MC_Light);
1871
// Barre noire de gauche
1872
Block(Main_separator_position,0,Menu_factor_X,Menu_Y,MC_Black);
1874
// Barre noire de droite
1875
Block(Main_X_zoom-Menu_factor_X,0,Menu_factor_X,Menu_Y,MC_Black);
1877
// Bord haut (blanc)
1878
Block(Main_separator_position+Menu_factor_X,0,
1879
(SEPARATOR_WIDTH-3)*Menu_factor_X,Menu_factor_Y,MC_White);
1881
// Bord gauche (blanc)
1882
Block(Main_separator_position+Menu_factor_X,Menu_factor_Y,
1883
Menu_factor_X,(Menu_Y-(Menu_factor_Y<<1)),MC_White);
1885
// Bord droite (gris fonc�)
1886
Block(Main_X_zoom-(Menu_factor_X<<1),Menu_factor_Y,
1887
Menu_factor_X,(Menu_Y-(Menu_factor_Y<<1)),MC_Dark);
1889
// Bord bas (gris fonc�)
1890
Block(Main_separator_position+(Menu_factor_X<<1),Menu_Y-Menu_factor_Y,
1891
(SEPARATOR_WIDTH-3)*Menu_factor_X,Menu_factor_Y,MC_Dark);
1894
Block(Main_separator_position+Menu_factor_X,Menu_Y-Menu_factor_Y,
1895
Menu_factor_X,Menu_factor_Y,MC_Light);
1897
Block(Main_X_zoom-(Menu_factor_X<<1),0,
1898
Menu_factor_X,Menu_factor_Y,MC_Light);
1900
Update_rect(Main_separator_position,0,SEPARATOR_WIDTH*Menu_factor_X,Menu_Y); // On r�affiche toute la partie � gauche du split, ce qui permet d'effacer son ancienne position
1905
// -- Fonctions de manipulation du curseur -----------------------------------
1908
// -- Afficher une barre horizontale XOR zoom�e
1910
void Horizontal_XOR_line_zoom(short x_pos, short y_pos, short width)
1912
short real_x_pos=Main_X_zoom+(x_pos-Main_magnifier_offset_X)*Main_magnifier_factor;
1913
short real_y_pos=(y_pos-Main_magnifier_offset_Y)*Main_magnifier_factor;
1914
short real_width=width*Main_magnifier_factor;
1915
short end_y_pos=(real_y_pos+Main_magnifier_factor<Menu_Y)?real_y_pos+Main_magnifier_factor:Menu_Y;
1918
for (index=real_y_pos; index<end_y_pos; index++)
1919
Horizontal_XOR_line(real_x_pos,index,real_width);
1921
Update_rect(real_x_pos,real_y_pos,real_width,end_y_pos-real_y_pos);
1925
// -- Afficher une barre verticale XOR zoom�e
1927
void Vertical_XOR_line_zoom(short x_pos, short y_pos, short height)
1929
short real_x_pos=Main_X_zoom+(x_pos-Main_magnifier_offset_X)*Main_magnifier_factor;
1930
short real_y_pos=(y_pos-Main_magnifier_offset_Y)*Main_magnifier_factor;
1931
short end_y_pos=(real_y_pos+(height*Main_magnifier_factor<Menu_Y))?real_y_pos+(height*Main_magnifier_factor):Menu_Y;
1934
for (index=real_y_pos; index<end_y_pos; index++)
1935
Horizontal_XOR_line(real_x_pos,index,Main_magnifier_factor);
1937
Update_rect(real_x_pos,real_y_pos,Main_magnifier_factor,end_y_pos-real_y_pos);
1941
// -- Afficher le curseur --
1943
void Display_cursor(void)
1952
short counter_x = 0;
1957
short x1,y1,x2,y2,x3,y3,x4,y4;
1959
// Si le curseur est dans le menu ou sur la barre de split, on affiche toujours une fl�che.
1960
if ( ( (Mouse_Y<Menu_Y)
1961
&& ( (!Main_magnifier_mode) || (Mouse_X<Main_separator_position) || (Mouse_X>=Main_X_zoom) ) )
1962
|| (Windows_open) || (Cursor_shape==CURSOR_SHAPE_HOURGLASS) )
1965
shape=CURSOR_SHAPE_ARROW;
1969
case CURSOR_SHAPE_TARGET :
1970
if (!Paintbrush_hidden)
1971
Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,1);
1974
if (Config.Cursor==1)
1976
start_y=(Mouse_Y<6)?6-Mouse_Y:0;
1978
Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-6,4-start_y);
1980
start_x=(Mouse_X<6)?(short)6-Mouse_X:0;
1982
Horizontal_XOR_line(Mouse_X+start_x-6,Mouse_Y,4-start_x);
1984
end_x=(Mouse_X+7>Screen_width)?Mouse_X+7-Screen_width:0;
1986
Horizontal_XOR_line(Mouse_X+3,Mouse_Y,4-end_x);
1988
end_y=(Mouse_Y+7>Screen_height)?Mouse_Y+7-Screen_height:0;
1990
Vertical_XOR_line (Mouse_X,Mouse_Y+3,4-end_y);
1992
Update_rect(Mouse_X+start_x-6,Mouse_Y+start_y-6,13-end_x,13-end_y);
1996
temp=(Config.Cursor)?CURSOR_SHAPE_THIN_TARGET:CURSOR_SHAPE_TARGET;
1997
start_x=Mouse_X-Gfx->Cursor_offset_X[temp];
1998
start_y=Mouse_Y-Gfx->Cursor_offset_Y[temp];
2000
for (y_pos=start_y,counter_y=0; counter_y<15 && y_pos < Screen_height;
2001
y_pos++,counter_y++)
2003
if( y_pos < 0 ) continue;
2004
for (x_pos=start_x,counter_x=0;
2005
counter_x<15 && x_pos < Screen_width; x_pos++,counter_x++)
2007
if( x_pos < 0 ) continue;
2008
color=Gfx->Cursor_sprite[temp][counter_y][counter_x];
2009
Cursor_background[counter_y][counter_x]=Read_pixel(x_pos,y_pos);
2010
if (color!=MC_Trans)
2011
Pixel(x_pos,y_pos,color);
2015
Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y);
2020
case CURSOR_SHAPE_COLORPICKER:
2021
if (!Paintbrush_hidden)
2022
Display_paintbrush(Paintbrush_X,Paintbrush_Y,Fore_color,1);
2025
if (Config.Cursor==1)
2027
// Barres formant la croix principale
2029
start_y=(Mouse_Y<5)?5-Mouse_Y:0;
2031
Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-5,3-start_y);
2033
start_x=(Mouse_X<5)?(short)5-Mouse_X:0;
2035
Horizontal_XOR_line(Mouse_X+start_x-5,Mouse_Y,3-start_x);
2037
end_x=(Mouse_X+6>Screen_width)?Mouse_X+6-Screen_width:0;
2039
Horizontal_XOR_line(Mouse_X+3,Mouse_Y,3-end_x);
2041
end_y=(Mouse_Y+6>Menu_Y/*Screen_height*/)?Mouse_Y+6-Menu_Y/*Screen_height*/:0;
2043
Vertical_XOR_line (Mouse_X,Mouse_Y+3,3-end_y);
2045
// Petites barres aux extr�mit�s
2049
end_x=(Mouse_X>=Screen_width-1);
2050
end_y=(Mouse_Y>=Menu_Y-1);
2053
Horizontal_XOR_line(start_x+Mouse_X-1,Mouse_Y-6,3-(start_x+end_x));
2056
Vertical_XOR_line (Mouse_X-6,start_y+Mouse_Y-1,3-(start_y+end_y));
2058
if (Mouse_X<Screen_width-6)
2059
Vertical_XOR_line (Mouse_X+6,start_y+Mouse_Y-1,3-(start_y+end_y));
2061
if (Mouse_Y<Menu_Y-6)
2062
Horizontal_XOR_line(start_x+Mouse_X-1,Mouse_Y+6,3-(start_x+end_x));
2066
temp=(Config.Cursor)?CURSOR_SHAPE_THIN_COLORPICKER:CURSOR_SHAPE_COLORPICKER;
2067
start_x=Mouse_X-Gfx->Cursor_offset_X[temp];
2068
start_y=Mouse_Y-Gfx->Cursor_offset_Y[temp];
2070
for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++)
2072
if(y_pos<0) continue;
2073
if(y_pos>=Screen_height) break;
2074
for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++)
2076
if(x_pos<0) continue;
2077
if(x_pos>=Screen_width) break;
2078
color=Gfx->Cursor_sprite[temp][counter_y][counter_x];
2079
// On sauvegarde dans Cursor_background pour restaurer plus tard
2080
Cursor_background[counter_y][counter_x]=Read_pixel(x_pos,y_pos);
2081
if (color!=MC_Trans)
2082
Pixel(x_pos,y_pos,color);
2085
Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y);
2090
case CURSOR_SHAPE_MULTIDIRECTIONAL :
2091
case CURSOR_SHAPE_HORIZONTAL :
2095
case CURSOR_SHAPE_ARROW :
2096
case CURSOR_SHAPE_HOURGLASS :
2097
start_x=Mouse_X-Gfx->Cursor_offset_X[shape];
2098
start_y=Mouse_Y-Gfx->Cursor_offset_Y[shape];
2099
for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++)
2101
if(y_pos<0) continue;
2102
if(y_pos>=Screen_height) break;
2103
for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++)
2105
if(x_pos<0) continue;
2106
if(x_pos>=Screen_width) break;
2107
color=Gfx->Cursor_sprite[shape][counter_y][counter_x];
2108
// On sauvegarde dans Cursor_background pour restaurer plus tard
2109
Cursor_background[counter_y][counter_x]=Read_pixel(x_pos,y_pos);
2110
if (color!=MC_Trans)
2111
Pixel(x_pos,y_pos,color);
2114
Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y);
2117
case CURSOR_SHAPE_XOR_TARGET :
2118
x_pos=Paintbrush_X-Main_offset_X;
2119
y_pos=Paintbrush_Y-Main_offset_Y;
2121
counter_x=(Main_magnifier_mode)?Main_separator_position:Screen_width; // width de la barre XOR
2122
if ((y_pos<Menu_Y) && (Paintbrush_Y>=Limit_top))
2124
Horizontal_XOR_line(0,Paintbrush_Y-Main_offset_Y,counter_x);
2125
Update_rect(0,Paintbrush_Y-Main_offset_Y,counter_x,1);
2128
if ((x_pos<counter_x) && (Paintbrush_X>=Limit_left))
2130
Vertical_XOR_line(Paintbrush_X-Main_offset_X,0,Menu_Y);
2131
Update_rect(Paintbrush_X-Main_offset_X,0,1,Menu_Y);
2134
if (Main_magnifier_mode)
2137
if ((Paintbrush_Y>=Limit_top_zoom) && (Paintbrush_Y<=Limit_visible_bottom_zoom))
2138
Horizontal_XOR_line_zoom(Limit_left_zoom,Paintbrush_Y,Main_magnifier_width);
2139
if ((Paintbrush_X>=Limit_left_zoom) && (Paintbrush_X<=Limit_visible_right_zoom))
2140
Vertical_XOR_line_zoom(Paintbrush_X,Limit_top_zoom,Main_magnifier_height);
2143
case CURSOR_SHAPE_XOR_RECTANGLE :
2144
// !!! Cette forme ne peut pas �tre utilis�e en mode Loupe !!!
2146
// Petite croix au centre
2147
start_x=(Mouse_X-3);
2148
start_y=(Mouse_Y-3);
2155
if (end_x>Screen_width)
2160
Horizontal_XOR_line(start_x,Mouse_Y,end_x-start_x);
2161
Vertical_XOR_line (Mouse_X,start_y,end_y-start_y);
2163
// Grand rectangle autour
2164
start_x=Mouse_X-(Main_magnifier_width>>1);
2165
start_y=Mouse_Y-(Main_magnifier_height>>1);
2166
if (start_x+Main_magnifier_width>=Limit_right-Main_offset_X)
2167
start_x=Limit_right-Main_magnifier_width-Main_offset_X+1;
2168
if (start_y+Main_magnifier_height>=Limit_bottom-Main_offset_Y)
2169
start_y=Limit_bottom-Main_magnifier_height-Main_offset_Y+1;
2174
end_x=start_x+Main_magnifier_width-1;
2175
end_y=start_y+Main_magnifier_height-1;
2177
Horizontal_XOR_line(start_x,start_y,Main_magnifier_width);
2178
Vertical_XOR_line(start_x,start_y+1,Main_magnifier_height-2);
2179
Vertical_XOR_line( end_x,start_y+1,Main_magnifier_height-2);
2180
Horizontal_XOR_line(start_x, end_y,Main_magnifier_width);
2182
Update_rect(start_x,start_y,end_x+1-start_x,end_y+1-start_y);
2185
default: //case CURSOR_SHAPE_XOR_ROTATION :
2186
start_x=1-(Brush_width>>1);
2187
start_y=1-(Brush_height>>1);
2188
end_x=start_x+Brush_width-1;
2189
end_y=start_y+Brush_height-1;
2191
if (Brush_rotation_center_is_defined)
2193
if ( (Brush_rotation_center_X==Paintbrush_X)
2194
&& (Brush_rotation_center_Y==Paintbrush_Y) )
2201
x_pos=Paintbrush_X-Brush_rotation_center_X;
2202
y_pos=Paintbrush_Y-Brush_rotation_center_Y;
2203
cos_a=(float)x_pos/sqrt((x_pos*x_pos)+(y_pos*y_pos));
2204
sin_a=sin(acos(cos_a));
2205
if (y_pos>0) sin_a=-sin_a;
2208
Transform_point(start_x,start_y, cos_a,sin_a, &x1,&y1);
2209
Transform_point(end_x ,start_y, cos_a,sin_a, &x2,&y2);
2210
Transform_point(start_x,end_y , cos_a,sin_a, &x3,&y3);
2211
Transform_point(end_x ,end_y , cos_a,sin_a, &x4,&y4);
2213
x1+=Brush_rotation_center_X;
2214
y1+=Brush_rotation_center_Y;
2215
x2+=Brush_rotation_center_X;
2216
y2+=Brush_rotation_center_Y;
2217
x3+=Brush_rotation_center_X;
2218
y3+=Brush_rotation_center_Y;
2219
x4+=Brush_rotation_center_X;
2220
y4+=Brush_rotation_center_Y;
2221
Pixel_figure_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,0);
2222
Draw_line_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,Paintbrush_X,Paintbrush_Y,0);
2226
x1=x3=1-Brush_width;
2237
Pixel_figure_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,0);
2238
Draw_line_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,Paintbrush_X,Paintbrush_Y,0);
2241
Draw_line_preview_xor(x1,y1,x2,y2,0);
2242
Draw_line_preview_xor(x2,y2,x4,y4,0);
2243
Draw_line_preview_xor(x4,y4,x3,y3,0);
2244
Draw_line_preview_xor(x3,y3,x1,y1,0);
2248
// -- Effacer le curseur --
2250
void Hide_cursor(void)
2253
int start_x; // int car sont parfois n�gatifs ! (quand on dessine sur un bord)
2259
short counter_x = 0;
2263
short x1,y1,x2,y2,x3,y3,x4,y4;
2265
if ( ( (Mouse_Y<Menu_Y)
2266
&& ( (!Main_magnifier_mode) || (Mouse_X<Main_separator_position)
2267
|| (Mouse_X>=Main_X_zoom) ) )
2268
|| (Windows_open) || (Cursor_shape==CURSOR_SHAPE_HOURGLASS) )
2271
shape=CURSOR_SHAPE_ARROW;
2275
case CURSOR_SHAPE_TARGET :
2278
if (Config.Cursor==1)
2280
start_y=(Mouse_Y<6)?6-Mouse_Y:0;
2282
Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-6,4-start_y);
2284
start_x=(Mouse_X<6)?(short)6-Mouse_X:0;
2286
Horizontal_XOR_line(Mouse_X+start_x-6,Mouse_Y,4-start_x);
2288
end_x=(Mouse_X+7>Screen_width)?Mouse_X+7-Screen_width:0;
2290
Horizontal_XOR_line(Mouse_X+3,Mouse_Y,4-end_x);
2292
end_y=(Mouse_Y+7>Screen_height)?Mouse_Y+7-Screen_height:0;
2294
Vertical_XOR_line (Mouse_X,Mouse_Y+3,4-end_y);
2296
Update_rect(Mouse_X+start_x-6,Mouse_Y+start_y-6,13-end_x,13-end_y);
2300
temp=(Config.Cursor)?CURSOR_SHAPE_THIN_TARGET:CURSOR_SHAPE_TARGET;
2301
start_x=Mouse_X-Gfx->Cursor_offset_X[temp];
2302
start_y=Mouse_Y-Gfx->Cursor_offset_Y[temp];
2304
for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++)
2306
if(y_pos < 0) continue;
2307
if(y_pos>=Screen_height) break;
2308
for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++)
2310
if(x_pos < 0) continue;
2311
else if (x_pos>=Screen_width) break;
2312
Pixel(x_pos,y_pos,Cursor_background[counter_y][counter_x]);
2316
Update_rect(Max(start_x,0),Max(start_y,0),x_pos-start_x,y_pos-start_y);
2319
if (!Paintbrush_hidden)
2321
Hide_paintbrush(Paintbrush_X,Paintbrush_Y);
2325
case CURSOR_SHAPE_COLORPICKER:
2328
if (Config.Cursor==1)
2330
// Barres formant la croix principale
2332
start_y=(Mouse_Y<5)?5-Mouse_Y:0;
2334
Vertical_XOR_line (Mouse_X,Mouse_Y+start_y-5,3-start_y);
2336
start_x=(Mouse_X<5)?(short)5-Mouse_X:0;
2338
Horizontal_XOR_line(Mouse_X+start_x-5,Mouse_Y,3-start_x);
2340
end_x=(Mouse_X+6>Screen_width)?Mouse_X+6-Screen_width:0;
2342
Horizontal_XOR_line(Mouse_X+3,Mouse_Y,3-end_x);
2344
end_y=(Mouse_Y+6>Screen_height)?Mouse_Y+6-Screen_height:0;
2346
Vertical_XOR_line (Mouse_X,Mouse_Y+3,3-end_y);
2350
end_x=(Mouse_X>=Screen_width-1);
2351
end_y=(Mouse_Y>=Menu_Y-1);
2354
Horizontal_XOR_line(start_x+Mouse_X-1,Mouse_Y-6,3-(start_x+end_x));
2357
Vertical_XOR_line (Mouse_X-6,start_y+Mouse_Y-1,3-(start_y+end_y));
2359
if (Mouse_X<Screen_width-6)
2360
Vertical_XOR_line (Mouse_X+6,start_y+Mouse_Y-1,3-(start_y+end_y));
2362
if (Mouse_Y<Menu_Y-6)
2363
Horizontal_XOR_line(start_x+Mouse_X-1,Mouse_Y+6,3-(start_x+end_x));
2365
Update_rect(start_x,start_y,end_x-start_x,end_y-start_y);
2369
temp=(Config.Cursor)?CURSOR_SHAPE_THIN_COLORPICKER:CURSOR_SHAPE_COLORPICKER;
2370
start_x=Mouse_X-Gfx->Cursor_offset_X[temp];
2371
start_y=Mouse_Y-Gfx->Cursor_offset_Y[temp];
2373
for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++)
2375
if(y_pos<0) continue;
2376
if(y_pos>=Screen_height) break;
2377
for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++)
2379
if(x_pos<0) continue;
2380
if(x_pos>=Screen_width) break;
2381
Pixel(x_pos,y_pos,Cursor_background[counter_y][counter_x]);
2384
Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y);
2387
if (!Paintbrush_hidden)
2388
Hide_paintbrush(Paintbrush_X,Paintbrush_Y);
2391
case CURSOR_SHAPE_MULTIDIRECTIONAL :
2392
case CURSOR_SHAPE_HORIZONTAL :
2396
case CURSOR_SHAPE_ARROW :
2397
case CURSOR_SHAPE_HOURGLASS :
2398
start_x=Mouse_X-Gfx->Cursor_offset_X[shape];
2399
start_y=Mouse_Y-Gfx->Cursor_offset_Y[shape];
2401
for (y_pos=start_y,counter_y=0;counter_y<15;y_pos++,counter_y++)
2403
if(y_pos<0) continue;
2404
if(y_pos>=Screen_height) break;
2405
for (x_pos=start_x,counter_x=0;counter_x<15;x_pos++,counter_x++)
2407
if(x_pos<0) continue;
2408
if(x_pos>=Screen_width) break;
2409
Pixel(x_pos,y_pos,Cursor_background[counter_y][counter_x]);
2412
Update_rect(Max(start_x,0),Max(start_y,0),counter_x,counter_y);
2415
case CURSOR_SHAPE_XOR_TARGET :
2416
x_pos=Paintbrush_X-Main_offset_X;
2417
y_pos=Paintbrush_Y-Main_offset_Y;
2419
counter_x=(Main_magnifier_mode)?Main_separator_position:Screen_width; // width de la barre XOR
2420
if ((y_pos<Menu_Y) && (Paintbrush_Y>=Limit_top))
2422
Horizontal_XOR_line(0,Paintbrush_Y-Main_offset_Y,counter_x);
2423
Update_rect(0,Paintbrush_Y-Main_offset_Y,counter_x,1);
2426
if ((x_pos<counter_x) && (Paintbrush_X>=Limit_left))
2428
Vertical_XOR_line(Paintbrush_X-Main_offset_X,0,Menu_Y);
2429
Update_rect(Paintbrush_X-Main_offset_X,0,1,Menu_Y);
2432
if (Main_magnifier_mode)
2435
if ((Paintbrush_Y>=Limit_top_zoom) && (Paintbrush_Y<=Limit_visible_bottom_zoom))
2436
Horizontal_XOR_line_zoom(Limit_left_zoom,Paintbrush_Y,Main_magnifier_width);
2437
if ((Paintbrush_X>=Limit_left_zoom) && (Paintbrush_X<=Limit_visible_right_zoom))
2438
Vertical_XOR_line_zoom(Paintbrush_X,Limit_top_zoom,Main_magnifier_height);
2443
case CURSOR_SHAPE_XOR_RECTANGLE :
2444
// !!! Cette forme ne peut pas �tre utilis�e en mode Loupe !!!
2446
// Petite croix au centre
2447
start_x=(Mouse_X-3);
2448
start_y=(Mouse_Y-3);
2455
if (end_x>Screen_width)
2460
Horizontal_XOR_line(start_x,Mouse_Y,end_x-start_x);
2461
Vertical_XOR_line (Mouse_X,start_y,end_y-start_y);
2463
// Grand rectangle autour
2465
start_x=Mouse_X-(Main_magnifier_width>>1);
2466
start_y=Mouse_Y-(Main_magnifier_height>>1);
2467
if (start_x+Main_magnifier_width>=Limit_right-Main_offset_X)
2468
start_x=Limit_right-Main_magnifier_width-Main_offset_X+1;
2469
if (start_y+Main_magnifier_height>=Limit_bottom-Main_offset_Y)
2470
start_y=Limit_bottom-Main_magnifier_height-Main_offset_Y+1;
2475
end_x=start_x+Main_magnifier_width-1;
2476
end_y=start_y+Main_magnifier_height-1;
2478
Horizontal_XOR_line(start_x,start_y,Main_magnifier_width);
2479
Vertical_XOR_line(start_x,start_y+1,Main_magnifier_height-2);
2480
Vertical_XOR_line( end_x,start_y+1,Main_magnifier_height-2);
2481
Horizontal_XOR_line(start_x, end_y,Main_magnifier_width);
2483
Update_rect(start_x,start_y,end_x+1-start_x,end_y+1-start_y);
2486
default: //case CURSOR_SHAPE_XOR_ROTATION :
2487
start_x=1-(Brush_width>>1);
2488
start_y=1-(Brush_height>>1);
2489
end_x=start_x+Brush_width-1;
2490
end_y=start_y+Brush_height-1;
2492
if (Brush_rotation_center_is_defined)
2494
if ( (Brush_rotation_center_X==Paintbrush_X)
2495
&& (Brush_rotation_center_Y==Paintbrush_Y) )
2502
x_pos=Paintbrush_X-Brush_rotation_center_X;
2503
y_pos=Paintbrush_Y-Brush_rotation_center_Y;
2504
cos_a=(float)x_pos/sqrt((x_pos*x_pos)+(y_pos*y_pos));
2505
sin_a=sin(acos(cos_a));
2506
if (y_pos>0) sin_a=-sin_a;
2509
Transform_point(start_x,start_y, cos_a,sin_a, &x1,&y1);
2510
Transform_point(end_x ,start_y, cos_a,sin_a, &x2,&y2);
2511
Transform_point(start_x,end_y , cos_a,sin_a, &x3,&y3);
2512
Transform_point(end_x ,end_y , cos_a,sin_a, &x4,&y4);
2514
x1+=Brush_rotation_center_X;
2515
y1+=Brush_rotation_center_Y;
2516
x2+=Brush_rotation_center_X;
2517
y2+=Brush_rotation_center_Y;
2518
x3+=Brush_rotation_center_X;
2519
y3+=Brush_rotation_center_Y;
2520
x4+=Brush_rotation_center_X;
2521
y4+=Brush_rotation_center_Y;
2522
Pixel_figure_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,0);
2523
Draw_line_preview_xor(Brush_rotation_center_X,Brush_rotation_center_Y,Paintbrush_X,Paintbrush_Y,0);
2527
x1=x3=1-Brush_width;
2538
Pixel_figure_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,0);
2539
Draw_line_preview_xor(Paintbrush_X-end_x,Paintbrush_Y,Paintbrush_X,Paintbrush_Y,0);
2542
Draw_line_preview_xor(x1,y1,x2,y2,0);
2543
Draw_line_preview_xor(x2,y2,x4,y4,0);
2544
Draw_line_preview_xor(x4,y4,x3,y3,0);
2545
Draw_line_preview_xor(x3,y3,x1,y1,0);
2551
// -- Fonction diverses d'affichage ------------------------------------------
2553
// -- Reafficher toute l'image (en prenant en compte le facteur de zoom) --
2555
void Display_all_screen(void)
2560
// ---/\/\/\ Partie non zoom�e: /\/\/\---
2561
if (Main_magnifier_mode)
2563
if (Main_image_width<Main_separator_position)
2564
width=Main_image_width;
2566
width=Main_separator_position;
2570
if (Main_image_width<Screen_width)
2571
width=Main_image_width;
2575
if (Main_image_height<Menu_Y)
2576
height=Main_image_height;
2579
Display_screen(width,height,Main_image_width);
2581
// Effacement de la partie non-image dans la partie non zoom�e:
2582
if (Main_magnifier_mode)
2584
if (Main_image_width<Main_separator_position && Main_image_width < Screen_width)
2585
Block(Main_image_width,0,(Main_separator_position-Main_image_width),Menu_Y,Main_backups->Pages->Transparent_color);
2589
if (Main_image_width<Screen_width)
2590
Block(Main_image_width,0,(Screen_width-Main_image_width),Menu_Y,Main_backups->Pages->Transparent_color);
2592
if (Main_image_height<Menu_Y)
2593
Block(0,Main_image_height,width,(Menu_Y-height),Main_backups->Pages->Transparent_color);
2595
// ---/\/\/\ Partie zoom�e: /\/\/\---
2596
if (Main_magnifier_mode)
2598
// Affichage de la barre de split
2599
Display_separator();
2601
// Calcul de la largeur visible
2602
if (Main_image_width<Main_magnifier_width)
2603
width=Main_image_width;
2605
width=Main_magnifier_width;
2607
// Calcul du nombre de lignes visibles de l'image zoom�e
2608
if (Main_image_height<Main_magnifier_height)
2609
height=Main_image_height*Main_magnifier_factor;
2613
Display_zoomed_screen(width,height,Main_image_width,Horizontal_line_buffer);
2615
// Effacement de la partie non-image dans la partie zoom�e:
2616
if (Main_image_width<Main_magnifier_width)
2617
Block(Main_X_zoom+(Main_image_width*Main_magnifier_factor),0,
2618
(Main_magnifier_width-Main_image_width)*Main_magnifier_factor,
2619
Menu_Y,Main_backups->Pages->Transparent_color);
2620
if (Main_image_height<Main_magnifier_height)
2621
Block(Main_X_zoom,height,width*Main_magnifier_factor,(Menu_Y-height),Main_backups->Pages->Transparent_color);
2624
// ---/\/\/\ Affichage des limites /\/\/\---
2625
if (Config.Display_image_limits)
2626
Display_image_limits();
2627
Update_rect(0,0,Screen_width,Menu_Y); // TODO On peut faire plus fin, en �vitant de mettre � jour la partie � droite du split quand on est en mode loupe. Mais c'est pas vraiment int�ressant ?
2632
byte Best_color(byte r,byte g,byte b)
2635
int delta_r,delta_g,delta_b;
2637
int best_dist=0x7FFFFFFF;
2641
for (col=0; col<256; col++)
2643
if (!Exclude_color[col])
2645
delta_r=(int)Main_palette[col].R-r;
2646
delta_g=(int)Main_palette[col].G-g;
2647
delta_b=(int)Main_palette[col].B-b;
2649
rmean = ( Main_palette[col].R + r ) / 2;
2651
if (!(dist= ( ( (512+rmean) *delta_r*delta_r) >>8) + 4*delta_g*delta_g + (((767-rmean)*delta_b*delta_b)>>8)))
2652
//if (!(dist=(delta_r*delta_r*30)+(delta_g*delta_g*59)+(delta_b*delta_b*11)))
2666
byte Best_color_nonexcluded(byte red,byte green,byte blue)
2669
int delta_r,delta_g,delta_b;
2671
int best_dist=0x7FFFFFFF;
2675
for (col=0; col<256; col++)
2677
delta_r=(int)Main_palette[col].R-red;
2678
delta_g=(int)Main_palette[col].G-green;
2679
delta_b=(int)Main_palette[col].B-blue;
2681
if(delta_r == 0 && delta_g == 0 && delta_b == 0) return col;
2683
rmean = ( Main_palette[col].R + red ) / 2;
2685
dist= ( ( (512+rmean) *delta_r*delta_r) >>8) + 4*delta_g*delta_g + (((767-rmean)*delta_b*delta_b)>>8);
2686
//dist=(delta_r*delta_r*30)+(delta_g*delta_g*59)+(delta_b*delta_b*11)
2697
void Compute_4_best_colors_for_1_menu_color
2698
(byte red, byte green, byte blue, T_Components * palette, byte * table)
2701
int delta_r,delta_g,delta_b;
2703
int best_dist[4]={0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF};
2706
for (col=0; col<256; col++)
2708
delta_r=(int)palette[col].R-red;
2709
delta_g=(int)palette[col].G-green;
2710
delta_b=(int)palette[col].B-blue;
2712
dist=(delta_r*delta_r*30)+(delta_g*delta_g*59)+(delta_b*delta_b*11);
2714
if (dist<best_dist[0])
2716
best_dist[3]=best_dist[2];
2717
best_dist[2]=best_dist[1];
2718
best_dist[1]=best_dist[0];
2727
if (dist<best_dist[1])
2729
best_dist[3]=best_dist[2];
2730
best_dist[2]=best_dist[1];
2738
if (dist<best_dist[2])
2740
best_dist[3]=best_dist[2];
2746
if (dist<best_dist[3])
2764
void Remap_pixel(byte * pixel)
2766
if (*pixel==Old_light) // On commence par tester le Gris clair
2767
*pixel=MC_Light; // qui est pas mal utilis�.
2770
if (*pixel==Old_black) // Puis le Noir...
2774
if (*pixel==Old_dark) // etc...
2778
if (*pixel==Old_white)
2782
if (*pixel==Old_trans)
2792
void Remap_screen_after_menu_colors_change(void)
2795
byte conversion_table[256];
2796
short temp/*,temp2*/;
2798
if ( (MC_Light!=Old_light) || (MC_Dark!=Old_dark) || (MC_White!=Old_white) || (MC_Black !=Old_black )
2799
|| (MC_Trans!=Old_trans) )
2801
// Cr�ation de la table de conversion
2802
for (index=0; index<256; index++)
2803
conversion_table[index]=index;
2805
conversion_table[Old_black ]=MC_Black;
2806
conversion_table[Old_dark]=MC_Dark;
2807
conversion_table[Old_light]=MC_Light;
2808
conversion_table[Old_white]=MC_White;
2810
// Remappage de l'�cran
2812
temp=Window_height*Menu_factor_Y;
2814
Remap_screen(Window_pos_X, Window_pos_Y,
2815
Window_width*Menu_factor_X,
2816
(Window_pos_Y+temp<Menu_Y_before_window)?temp:Menu_Y_before_window-Window_pos_Y,
2819
if (Menu_is_visible_before_window)
2821
Remap_screen(0, Menu_Y_before_window,
2822
Screen_width, Screen_height-Menu_Y_before_window,
2824
// Remappage de la partie du fond de la fenetre qui cacherait le menu...
2825
Remap_window_backgrounds(conversion_table, Menu_Y_before_window, Screen_height);
2827
Il faudrait peut-�tre remapper les pointill�s d�limitant l'image.
2828
Mais �a va �tre chiant parce qu'ils peuvent �tre affich�s en mode Loupe.
2829
Mais de toutes fa�ons, c'est franchement facultatif...
2831
// On passe la table juste pour ne rafficher que les couleurs modifi�es
2832
Display_menu_palette_avoiding_window(conversion_table);
2834
Clear_border(MC_Black);
2842
void Compute_optimal_menu_colors(T_Components * palette)
2846
Old_black =MC_Black;
2848
Old_light = MC_Light;
2849
Old_white = MC_White;
2850
Old_trans = MC_Trans;
2852
// Recherche du noir
2853
Compute_4_best_colors_for_1_menu_color
2854
(Config.Fav_menu_colors[0].R, Config.Fav_menu_colors[0].G, Config.Fav_menu_colors[0].B,palette,table);
2857
// Recherche du blanc
2858
Compute_4_best_colors_for_1_menu_color
2859
(Config.Fav_menu_colors[3].R, Config.Fav_menu_colors[3].G, Config.Fav_menu_colors[3].B,palette,table);
2860
if (MC_Black!=table[0])
2865
// Recherche du gris clair
2866
Compute_4_best_colors_for_1_menu_color
2867
(Config.Fav_menu_colors[2].R, Config.Fav_menu_colors[2].G, Config.Fav_menu_colors[2].B,palette,table);
2868
if ( (MC_Black!=table[0]) && (MC_White!=table[0]) )
2872
if ( (MC_Black!=table[1]) && (MC_White!=table[1]) )
2878
// Recherche du gris fonc�
2879
Compute_4_best_colors_for_1_menu_color
2880
(Config.Fav_menu_colors[1].R, Config.Fav_menu_colors[1].G, Config.Fav_menu_colors[1].B,palette,table);
2881
if ( (MC_Black!=table[0]) && (MC_White!=table[0]) && (MC_Light!=table[0]) )
2885
if ( (MC_Black!=table[1]) && (MC_White!=table[1]) && (MC_Light!=table[1]) )
2889
if ( (MC_Black!=table[2]) && (MC_White!=table[2]) && (MC_Light!=table[2]) )
2896
// C'est peu probable mais il est possible que MC_Light soit plus fonc�e que
2897
// MC_Dark. Dans ce cas, on les inverse.
2898
if ( ((palette[MC_Light].R*30)+(palette[MC_Light].G*59)+(palette[MC_Light].B*11)) <
2899
((palette[MC_Dark].R*30)+(palette[MC_Dark].G*59)+(palette[MC_Dark].B*11)) )
2901
SWAP_BYTES(MC_Light, MC_Dark);
2904
// On cherche une couleur de transparence diff�rente des 4 autres.
2905
for (MC_Trans=0; ((MC_Trans==MC_Black) || (MC_Trans==MC_Dark) ||
2906
(MC_Trans==MC_Light) || (MC_Trans==MC_White)); MC_Trans++);
2908
Remap_menu_sprites();
2911
/// Remap all menu data when the palette changes or a new skin is loaded
2912
void Remap_menu_sprites()
2916
if ( (MC_Light!=Old_light)
2917
|| (MC_Dark!=Old_dark)
2918
|| (MC_White!=Old_white)
2919
|| (MC_Black !=Old_black )
2920
|| (MC_Trans!=Old_trans) )
2922
// Mouse cursor sprites
2923
for (k=0; k<NB_CURSOR_SPRITES; k++)
2924
for (j=0; j<CURSOR_SPRITE_HEIGHT; j++)
2925
for (i=0; i<CURSOR_SPRITE_WIDTH; i++)
2926
Remap_pixel(&Gfx->Cursor_sprite[k][j][i]);
2928
for (j=0; j<Menu_bars[MENUBAR_TOOLS].Height; j++)
2929
for (i=0; i<Menu_bars[MENUBAR_TOOLS].Skin_width; i++)
2930
Remap_pixel(&Gfx->Menu_block[j][i]);
2932
for (k=0; k<NB_MENU_SPRITES; k++)
2933
for (j=0; j<MENU_SPRITE_HEIGHT; j++)
2934
for (i=0; i<MENU_SPRITE_WIDTH; i++)
2935
Remap_pixel(&Gfx->Menu_sprite[k][j][i]);
2937
for (k=0; k<NB_EFFECTS_SPRITES; k++)
2938
for (j=0; j<MENU_SPRITE_HEIGHT; j++)
2939
for (i=0; i<MENU_SPRITE_WIDTH; i++)
2940
Remap_pixel(&Gfx->Effect_sprite[k][j][i]);
2943
for (k=0; k<16; k++)
2944
for (j=0; j<LAYER_SPRITE_HEIGHT; j++)
2945
for (i=0; i<LAYER_SPRITE_WIDTH; i++)
2946
Remap_pixel(&Gfx->Layer_sprite[l][k][j][i]);
2949
for (j=0; j<Menu_bars[MENUBAR_STATUS].Height; j++)
2950
for (i=0; i<Menu_bars[MENUBAR_STATUS].Skin_width; i++)
2951
Remap_pixel(&Gfx->Statusbar_block[j][i]);
2953
for (j=0; j<Menu_bars[MENUBAR_LAYERS].Height; j++)
2954
for (i=0; i<Menu_bars[MENUBAR_LAYERS].Skin_width; i++)
2955
Remap_pixel(&Gfx->Layerbar_block[j][i]);
2958
for (k=0; k<256; k++)
2961
Remap_pixel(&Gfx->Help_font_norm[k][i][j]);
2962
for (k=0; k<256; k++)
2965
Remap_pixel(&Gfx->Bold_font[k][i][j]);
2966
for (k=0; k<64; k++)
2969
Remap_pixel(&Gfx->Help_font_t1[k][i][j]);
2970
for (k=0; k<64; k++)
2973
Remap_pixel(&Gfx->Help_font_t2[k][i][j]);
2974
for (k=0; k<64; k++)
2977
Remap_pixel(&Gfx->Help_font_t3[k][i][j]);
2978
for (k=0; k<64; k++)
2981
Remap_pixel(&Gfx->Help_font_t4[k][i][j]);
2983
// Drives and other misc. 8x8 icons
2984
for (k=0; k<NB_ICON_SPRITES; k++)
2985
for (j=0; j<ICON_SPRITE_HEIGHT; j++)
2986
for (i=0; i<ICON_SPRITE_WIDTH; i++)
2987
Remap_pixel(&Gfx->Icon_sprite[k][j][i]);
2990
for (j = 0; j < 173; j++)
2991
for (i = 0; i < 16; i++)
2992
Remap_pixel(&Gfx->Preview[i][j]);
2994
Clear_border(MC_Black);