1 /* vim:expandtab:ts=2 sw=2:
2 */
3 /* Grafx2 - The Ultimate 256-color bitmap paint program
4
5 Copyright owned by various GrafX2 authors, see COPYRIGHT.txt for details.
6
7 Grafx2 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2
10 of the License.
11
12 Grafx2 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Grafx2; if not, see <http://www.gnu.org/licenses/>
19 */
20
21 ////////////////////////////////////////////////////////////////////////////
22 ///@file buttons_effects.c
23 /// Handles all the effects buttons and setup windows in the effects menu.
24 ////////////////////////////////////////////////////////////////////////////
25
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "gfx2log.h"
30 #include "brush.h"
31 #include "buttons.h"
32 #include "engine.h"
33 #include "global.h"
34 #include "graph.h"
35 #include "help.h"
36 #include "input.h"
37 #include "misc.h"
38 #include "pages.h"
39 #include "readline.h"
40 #include "screen.h"
41 #include "struct.h"
42 #include "windows.h"
43 #include "tiles.h"
44 #include "oldies.h"
45 #include "palette.h"
46 #include "layers.h"
47
48 #ifndef MIN
49 #define MIN(a,b) ((a)<(b)?(a):(b))
50 #endif
51
52 //---------- Menu dans lequel on tagge des couleurs (genre Stencil) ----------
Menu_tag_colors(char * window_title,byte * table,byte * mode,byte can_cancel,const char * help_section,word close_shortcut)53 void Menu_tag_colors(char * window_title, byte * table, byte * mode, byte can_cancel, const char *help_section, word close_shortcut)
54 {
55 short clicked_button;
56 byte backup_table[256];
57 word index;
58 word old_mouse_x;
59 word old_mouse_y;
60 byte old_mouse_k;
61 byte tagged_color;
62 byte color;
63 byte click;
64
65
66 Open_window(176,150,window_title);
67
68 Window_set_palette_button(6,38); // 1
69 Window_set_normal_button( 7, 19,78,14,"Clear" ,1,1,KEY_c); // 2
70 Window_set_normal_button(91, 19,78,14,"Invert",1,1,KEY_i); // 3
71 if (can_cancel)
72 {
73 Window_set_normal_button(91,129,78,14,"OK" ,0,1,KEY_RETURN); // 4
74 Window_set_normal_button( 7,129,78,14,"Cancel",0,1,KEY_ESC); // 5
75 // On enregistre la table dans un backup au cas où on ferait Cancel
76 memcpy(backup_table,table,256);
77 }
78 else
79 Window_set_normal_button(49,129,78,14,"OK" ,0,1,KEY_RETURN); // 4
80
81 // On affiche l'état actuel de la table
82 for (index=0; index<=255; index++)
83 Stencil_tag_color(index, (table[index])?MC_Black:MC_Light);
84
85 Update_window_area(0,0,Window_width, Window_height);
86 Display_cursor();
87
88 do
89 {
90 old_mouse_x=Mouse_X;
91 old_mouse_y=Mouse_Y;
92 old_mouse_k=Mouse_K;
93
94 clicked_button=Window_clicked_button();
95
96 switch (clicked_button)
97 {
98 case 0 :
99 break;
100 case -1 :
101 case 1 : // Palette
102 if ( (Mouse_X!=old_mouse_x) || (Mouse_Y!=old_mouse_y) || (Mouse_K!=old_mouse_k) )
103 {
104 Hide_cursor();
105 tagged_color=(clicked_button==1) ? Window_attribute2 : Read_pixel(Mouse_X,Mouse_Y);
106 table[tagged_color]=(Mouse_K==LEFT_SIDE);
107 Stencil_tag_color(tagged_color,(Mouse_K==LEFT_SIDE)?MC_Black:MC_Light);
108 Display_cursor();
109 Stencil_update_color(tagged_color);
110 }
111 break;
112 case 2 : // Clear
113 memset(table,0,256);
114 Hide_cursor();
115 for (index=0; index<=255; index++)
116 Stencil_tag_color(index,MC_Light);
117 Display_cursor();
118 Update_window_area(0,0,Window_width, Window_height);
119 break;
120 case 3 : // Invert
121 Hide_cursor();
122 for (index=0; index<=255; index++)
123 Stencil_tag_color(index,(table[index]^=1)?MC_Black:MC_Light);
124 Display_cursor();
125 Update_window_area(0,0,Window_width, Window_height);
126 }
127
128 if (!Mouse_K)
129 switch (Key)
130 {
131 case KEY_BACKQUOTE : // Récupération d'une couleur derrière le menu
132 case KEY_COMMA :
133 Get_color_behind_window(&color,&click);
134 if (click)
135 {
136 Hide_cursor();
137 tagged_color=color;
138 table[tagged_color]=(click==LEFT_SIDE);
139 Stencil_tag_color(tagged_color,(click==LEFT_SIDE)?MC_Black:MC_Light);
140 Stencil_update_color(tagged_color);
141 Display_cursor();
142 Wait_end_of_click();
143 }
144 Key=0;
145 break;
146 default:
147 if (Is_shortcut(Key,0x100+BUTTON_HELP))
148 {
149 Window_help(BUTTON_EFFECTS, help_section);
150 Key=0;
151 break;
152 }
153 else if (Is_shortcut(Key,close_shortcut))
154 {
155 clicked_button=4;
156 }
157 }
158 }
159 while (clicked_button<4);
160
161 Close_window();
162
163 if (clicked_button==5) // Cancel
164 memcpy(table,backup_table,256);
165 else // OK
166 *mode=1;
167
168 Display_cursor();
169 }
170
171
172 /// Block Constraint check
173 ///
174 /// This function count the number of colors in a block and reports errors
175 /// by marking the pixel in color 17 in layer 2.
176 /// @param mode
177 /// @return -1 if the mode is invalid
178 /// @return the number of constraint errors detected
Check_block_constraints(enum IMAGE_MODES mode)179 static int Check_block_constraints(enum IMAGE_MODES mode)
180 {
181 int x, y, x2, y2;
182 int block_width = 8, block_height = 8, max_colors = 2; // default values
183 int error_count = 0;
184 byte errcol = 17;
185 byte pal_mask;
186
187 switch (mode)
188 {
189 case IMAGE_MODE_TMS9918G2:
190 case IMAGE_MODE_THOMSON:
191 block_height = 1;
192 break;
193 case IMAGE_MODE_ZX:
194 case IMAGE_MODE_C64HIRES:
195 break;
196 case IMAGE_MODE_C64MULTI:
197 block_width = 4;
198 max_colors = 3; // 3 + background color
199 break;
200 case IMAGE_MODE_GBC:
201 max_colors = 4;
202 errcol = 33;
203 break;
204 case IMAGE_MODE_MEGADRIVE:
205 max_colors = 16;
206 errcol = 65;
207 break;
208 default:
209 return -1; // unsupported mode
210 }
211 pal_mask = ~(max_colors - 1);
212
213 for (y = 0; y <= Main.image_height - block_height; y += block_height)
214 {
215 for (x = 0; x <= Main.image_width - block_width; x += block_width)
216 {
217 int count = 0;
218 byte c[16]; // colors already used in block
219
220 for (y2 = 0; y2 < block_height; y2++)
221 {
222 for (x2 = 0; x2 < block_width; x2++)
223 {
224 int i;
225 byte col = Read_pixel_from_layer(0, x+x2, y+y2);
226 if (mode == IMAGE_MODE_GBC || mode == IMAGE_MODE_MEGADRIVE)
227 {
228 if (count == 0)
229 c[count++] = col;
230 else if ((col & pal_mask) != (c[0] & pal_mask)) // compare palettes
231 {
232 if (Main.backups->Pages->Nb_layers < 2)
233 Add_layer(Main.backups, 1);
234 Pixel_in_layer(1, x+x2, y+y2, errcol);
235 error_count++;
236 }
237 continue;
238 }
239 if (col > 15) // forbidden color !
240 {
241 if (Main.backups->Pages->Nb_layers < 2)
242 Add_layer(Main.backups, 1);
243 Pixel_in_layer(1, x+x2, y+y2, errcol);
244 error_count++;
245 continue;
246 }
247 if (mode == IMAGE_MODE_C64MULTI && col == 0) // Background color
248 continue;
249 // search color in already used ones
250 for (i = 0; i < count; i++)
251 {
252 if (col == c[i])
253 break;
254 // ZX Spectrum : consider both blacks as the same color
255 if (mode == IMAGE_MODE_ZX && (col & 7) == 0 && (c[i] & 7) == 0)
256 break;
257 }
258 if (i >= count) // not found
259 {
260 // ZX Spectrum : check that both colors have same intensity (except black)
261 if (mode == IMAGE_MODE_ZX && count > 0)
262 {
263 if ((col & 8) != (c[0] & 8) && (col & 7) != 0 && (c[0] & 7) != 0)
264 {
265 GFX2_Log(GFX2_INFO, "Check_block_constraints() intensity error at (%d,%d) color=%d (other color=%d)\n", x+x2, y+y2, col, c[0]);
266 if (Main.backups->Pages->Nb_layers < 2)
267 Add_layer(Main.backups, 1);
268 Pixel_in_layer(1, x+x2, y+y2, errcol);
269 error_count++;
270 continue;
271 }
272 }
273 if (count >= max_colors)
274 {
275 // constraint error : add color 17 pixel in layer 2
276 GFX2_Log(GFX2_INFO, "Check_block_constraints() constraint error at (%d,%d)\n", x+x2, y+y2);
277 if (Main.backups->Pages->Nb_layers < 2)
278 Add_layer(Main.backups, 1);
279 if (mode == IMAGE_MODE_TMS9918G2)
280 {
281 Pixel_in_layer(1, x+x2, y+y2, col); // put color in sprite layer
282 Pixel_in_layer(0, x+x2, y+y2, c[0]); // put other color in picture layer
283 }
284 else
285 Pixel_in_layer(1, x+x2, y+y2, errcol);
286 error_count++;
287 }
288 else
289 c[count++] = col;
290 }
291 }
292 }
293 }
294 }
295 if (error_count > 0)
296 Main.current_layer = 0; // activate layer 1 again
297 return error_count;
298 }
299
300 /// convert a picture to the HGR mode
301 ///
302 /// Recognize monochrome pictures.
303 /// Color pictures should use the 8 first colors.
Convert_to_hgr(void)304 static void Convert_to_hgr(void)
305 {
306 int i;
307 word count, x, y;
308 dword usage[256];
309
310 count = Count_used_colors(usage);
311 if (count <= 1) // blank picture, nothing to do :)
312 return;
313 if (count == 2) // monochrome !
314 {
315 byte bg, fg;
316 i = 0;
317 while (usage[i] == 0 && i < 256)
318 i++;
319 bg = (byte)i;
320 i++;
321 while (usage[i] == 0 && i < 256)
322 i++;
323 fg = (byte)i;
324 GFX2_Log(GFX2_DEBUG, "Convert_to_hgr() monochrome bg=%u fg=%u\n", bg, fg);
325 if (!(bg == 0 && fg == 3) && !(bg == 4 && fg == 7))
326 {
327 // convert to B&W
328 for (y = 0; y < Main.image_height; y++)
329 {
330 for (x = 0; x < Main.image_width; x++)
331 {
332 byte c = Read_pixel_from_layer(0, x, y);
333 Pixel_in_layer(0, x, y, (c == fg) ? 3 : 0);
334 }
335 }
336 }
337 }
338 else
339 {
340 // "convert" color picture to B&W
341 for (y = 0; y < Main.image_height; y++)
342 {
343 for (x = 0; x < Main.image_width; x++)
344 {
345 byte c = Read_pixel_from_layer(0, x, y);
346 switch (c & 3)
347 {
348 case 0: // black
349 case 3: // white
350 Pixel_in_layer(0, x, y, c);
351 break;
352 case 1: // green/orange
353 case 2: // purple/blue
354 Pixel_in_layer(0, x, y, (c & 4) | (((c & 1) ^ (x & 1) ^ 1) * 3));
355 }
356 }
357 }
358 }
359 // update color layer
360 for (y = 0; y < Main.image_height; y++)
361 {
362 for (x = 0; x < Main.image_width; x++)
363 {
364 Update_color_hgr_pixel(x, y, 0);
365 }
366 }
367 }
368
369 /// convert a picture to the DHGR mode
370 ///
371 /// Recognize monochrome pictures.
Convert_to_dhgr(void)372 static void Convert_to_dhgr(void)
373 {
374 int i;
375 word count, x, y;
376 dword usage[256];
377
378 count = Count_used_colors(usage);
379 if (count <= 1) // blank picture, nothing to do :)
380 return;
381 if (count == 2) // monochrome !
382 {
383 byte bg, fg;
384 i = 0;
385 while (usage[i] == 0 && i < 256)
386 i++;
387 bg = (byte)i;
388 i++;
389 while (usage[i] == 0 && i < 256)
390 i++;
391 fg = (byte)i;
392 GFX2_Log(GFX2_DEBUG, "Convert_to_dhgr() monochrome bg=%u fg=%u\n", bg, fg);
393 if (!(bg == 0 && fg == 3) && !(bg == 4 && fg == 7))
394 {
395 // convert to B&W
396 for (y = 0; y < Main.image_height; y++)
397 {
398 for (x = 0; x < Main.image_width; x++)
399 {
400 byte c = Read_pixel_from_layer(0, x, y);
401 Pixel_in_layer(0, x, y, (c == fg) ? 15 : 0);
402 }
403 }
404 }
405 }
406 else
407 {
408 // "convert" color picture to B&W
409 for (y = 0; y < Main.image_height; y++)
410 {
411 for (x = 0; x < Main.image_width; x += 4)
412 {
413 byte c = Read_pixel_from_layer(0, x, y);
414 Pixel_in_layer(0, x, y, c & 0x18);
415 Pixel_in_layer(0, x + 1, y, c & 0x14);
416 Pixel_in_layer(0, x + 2, y, c & 0x12);
417 Pixel_in_layer(0, x + 3, y, c & 0x11);
418 }
419 }
420 }
421 // update color layer
422 for (y = 0; y < Main.image_height; y++)
423 {
424 for (x = 0; x < Main.image_width; x += 4)
425 {
426 Update_color_dhgr_pixel(x, y, 0);
427 }
428 }
429 }
430
431
432 /// Constaint enforcer/checker
433 ///
434 /// A call toggles between constraint mode and Layered mode.
Button_Constraint_mode(void)435 void Button_Constraint_mode(void)
436 {
437 int pixel;
438
439 if (Main.backups->Pages->Image_mode > IMAGE_MODE_ANIMATION)
440 {
441 // Disable
442 Switch_layer_mode(IMAGE_MODE_LAYERED);
443 return;
444 }
445
446 if (Selected_Constraint_Mode <= IMAGE_MODE_ANIMATION)
447 Selected_Constraint_Mode = IMAGE_MODE_EGX; ///@todo load prefered/last used contrained mode from config ?
448
449 if (Selected_Constraint_Mode == IMAGE_MODE_MODE5 && (Main.image_width%48))
450 {
451 Verbose_message("Error!", "Emulation of Amstrad CPC's Mode5 can only be used on an image whose width is a multiple of 48.");
452 return;
453 }
454 if (Selected_Constraint_Mode == IMAGE_MODE_C64FLI && ((Main.image_width < 160) || (Main.image_height < 200)))
455 {
456 Verbose_message("Error!", "Emulation of Commodore 64 FLI Mode needs a 160x200 sized image.");
457 return;
458 }
459
460 // now check the constraints on existing pixels
461 switch (Selected_Constraint_Mode)
462 {
463 case IMAGE_MODE_MODE5:
464 case IMAGE_MODE_RASTER:
465 // switch to layer mode if needed
466 if (Main.backups->Pages->Image_mode != IMAGE_MODE_LAYERED)
467 Switch_layer_mode(IMAGE_MODE_LAYERED);
468 // auto-create extra layers
469 while (Main.backups->Pages->Nb_layers < 5)
470 if (Add_layer(Main.backups, Main.backups->Pages->Nb_layers))
471 {
472 Verbose_message("Error!", "Failed to create the 5 layers needed by Emulation of Amstrad CPC's rasters.");
473 return;
474 }
475 for (pixel=0; pixel < Main.image_width*Main.image_height; pixel++)
476 {
477 if (Main.backups->Pages->Image[4].Pixels[pixel]>3)
478 {
479 GFX2_Log(GFX2_INFO, "pixel[%u]=0x%02x\n", pixel, Main.backups->Pages->Image[4].Pixels[pixel]);
480 Verbose_message("Error!", "Emulation of Amstrad CPC's rasters needs all pixels of layer 5 to use colors 0-3.");
481 return;
482 }
483 }
484 break;
485 case IMAGE_MODE_C64FLI:
486 // switch to layer mode if needed
487 if (Main.backups->Pages->Image_mode != IMAGE_MODE_LAYERED)
488 Switch_layer_mode(IMAGE_MODE_LAYERED);
489 Main.backups->Pages->Transparent_color = 16;
490 // auto-create extra layers
491 while (Main.backups->Pages->Nb_layers < 3)
492 if (Add_layer(Main.backups, 0))
493 {
494 Verbose_message("Error!", "Failed to create the 3 layers needed by C64 Flexible Line Interpretation mode.");
495 return;
496 }
497 {
498 word x, y;
499 byte bitmap[8000],screen_ram[1024*8],color_ram[1024];
500 byte background[200];
501
502 memset(bitmap, 0, sizeof(bitmap));
503 memset(screen_ram, 0, sizeof(screen_ram));
504 memset(color_ram, 0, sizeof(color_ram));
505 memset(background, 0, sizeof(background));
506
507 // give "hints" to the converter
508 for (y = 0; y < 200; y++)
509 background[y] = Read_pixel_from_layer(0, 0, y);
510 for (y = 0; y < 25; y++)
511 {
512 for (x = 0; x < 40; x++)
513 color_ram[x + y*40] = Read_pixel_from_layer(1, x*4, y*8);
514 }
515
516 if (C64_pixels_to_FLI(bitmap, screen_ram, color_ram, background, Main.backups->Pages->Image[2].Pixels, Main.image_width, 1) > 0)
517 {
518 // put errors in layer 4 if not already done
519 if (Main.backups->Pages->Nb_layers < 4)
520 {
521 Add_layer(Main.backups, Main.backups->Pages->Nb_layers);
522 C64_pixels_to_FLI(bitmap, screen_ram, color_ram, background, Main.backups->Pages->Image[2].Pixels, Main.image_width, 1);
523 }
524 }
525
526 // copy background to layer 1
527 // and color RAM to layer 2
528 for (y = 0; y < 200; y++)
529 {
530 for (x = 0; x < 160; x++)
531 {
532 Pixel_in_layer(0, x, y, background[y]);
533 Pixel_in_layer(1, x, y, color_ram[(x >> 2) + (y >> 3)*40]);
534 }
535 }
536 }
537 break;
538 case IMAGE_MODE_HGR:
539 case IMAGE_MODE_DHGR:
540 // switch to layer mode if needed
541 if (Main.backups->Pages->Image_mode != IMAGE_MODE_LAYERED)
542 Switch_layer_mode(IMAGE_MODE_LAYERED);
543 // auto-create extra layers
544 while (Main.backups->Pages->Nb_layers < 2)
545 if (Add_layer(Main.backups, Main.backups->Pages->Nb_layers))
546 {
547 Verbose_message("Error!", "Failed to create the 2 layers needed by Emulation of Apple II HGR or DHGR.");
548 return;
549 }
550 if (Selected_Constraint_Mode == IMAGE_MODE_HGR)
551 Convert_to_hgr();
552 else
553 Convert_to_dhgr();
554 break;
555 case IMAGE_MODE_TMS9918G2:
556 // switch to layer mode if needed
557 if (Main.backups->Pages->Image_mode != IMAGE_MODE_LAYERED)
558 Switch_layer_mode(IMAGE_MODE_LAYERED);
559 Main.backups->Pages->Transparent_color = 0;
560 Check_block_constraints(Selected_Constraint_Mode);
561 break;
562 default:
563 Check_block_constraints(Selected_Constraint_Mode);
564 }
565 /// Setting the palette is done in @ref Button_Constraint_menu (8-bit constraint window)
566
567 /// @todo backup
568 Switch_layer_mode(Selected_Constraint_Mode);
569 }
570
571
Button_Constraint_menu(void)572 void Button_Constraint_menu(void)
573 {
574 unsigned int i;
575 int set_palette = 1;
576 int set_pic_size = 0;
577 int set_grid = 1;
578 short clicked_button;
579 T_Dropdown_button* dropdown;
580 const char * label;
581 const char * summary;
582 static const struct {
583 enum IMAGE_MODES mode;
584 const char * label;
585 const char * summary;
586 int grid;
587 } modes[] = {
588 {IMAGE_MODE_ZX, "ZX Spectrum", "2 colors per 8x8 block", 1}, // 256x192
589 {IMAGE_MODE_GBC, "Game Boy Color","4 colors per 8x8 block", 1}, // 160x144 to 256x256
590 {IMAGE_MODE_MEGADRIVE,"Sega MegaDrive","16colors per 8x8 block",1}, // 256x224 to 1024x256
591 {IMAGE_MODE_THOMSON, "40col (MO/TO)", "2 colors per 8x1 block", 1}, // 320x200
592 {IMAGE_MODE_EGX, "EGX (CPC)", "Alternate Mode0/Mode1 ", 0}, // 320x200
593 {IMAGE_MODE_EGX2, "EGX2 (CPC)", "Alternate Mode1/Mode2 ", 0}, // 640x200
594 {IMAGE_MODE_MODE5, "Mode 5 (CPC)", "Mode5 ", 0}, // 288x256
595 {IMAGE_MODE_RASTER, "Rasters (CPC)", "CPC Rasters ", 1},
596 {IMAGE_MODE_C64HIRES,"C64 HiRes", "2 colors per 8x8 block", 1}, // 320x200
597 {IMAGE_MODE_C64MULTI,"C64 Multicolor","4 colors per 4x1 block", 1}, // 160x200
598 {IMAGE_MODE_C64FLI, "C64 FLI", "improved multicolor ", 1}, // 160x200
599 {IMAGE_MODE_HGR, "Apple II HGR", "6 colors ", 1}, // 280x192
600 {IMAGE_MODE_DHGR, "Apple II DHGR", "\"Le Chat Mauve\" mode3 ", 1}, // 560x192
601 {IMAGE_MODE_TMS9918G2,"TMS9918 Mode 2","MSX Screen2, etc. ", 1}, // 256x192
602 };
603
604 Open_window(194,95+36,"8-bit constraints");
605
606 Window_set_normal_button(31,71+36,51,14,"Cancel",0,1,KEY_ESC); // 1
607 Window_set_normal_button(112,71+36,51,14,"OK" ,0,1,KEY_RETURN); // 2
608
609 label = "Constraints";
610 summary = "";
611 for (i = 0; i < sizeof(modes)/sizeof(modes[0]) ; i++)
612 if (Selected_Constraint_Mode == modes[i].mode)
613 {
614 label = modes[i].label;
615 summary = modes[i].summary;
616 set_grid = modes[i].grid;
617 break;
618 }
619 dropdown = Window_set_dropdown_button(32, 21, 130, 14, 120, label, 1, 0, 1, RIGHT_SIDE|LEFT_SIDE, 0); // 3
620 for (i = 0; i < sizeof(modes)/sizeof(modes[0]) ; i++)
621 Window_dropdown_add_item(dropdown, modes[i].mode, modes[i].label);
622 Print_in_window(10, 21+18, summary, MC_Dark, MC_Light);
623
624 Window_set_normal_button(10, 51, 14, 14, set_palette?"X":" ", 0, 1, KEY_p); // 4
625 Print_in_window_underscore(10+18, 51+3, "Set palette", MC_Dark, MC_Light, 5);
626
627 Window_set_normal_button(10, 69, 14, 14, set_pic_size?"X":" ", 0, 1, KEY_s); // 5
628 Print_in_window_underscore(10+18, 69+3, "Set picture size", MC_Dark, MC_Light, 13);
629
630 Window_set_normal_button(10, 87, 14, 14, set_grid?"X":" ", 0, 1, KEY_g); // 6
631 Print_in_window_underscore(10+18, 87+3, "Enable grid", MC_Dark, MC_Light, 8);
632
633 Update_window_area(0,0,Window_width, Window_height);
634 Display_cursor();
635
636 do
637 {
638 clicked_button=Window_clicked_button();
639 if (Is_shortcut(Key, 0x100+BUTTON_HELP))
640 {
641 Key = 0;
642 Window_help(BUTTON_EFFECTS, "8 BIT");
643 }
644 else if (clicked_button == 3)
645 {
646 if (Selected_Constraint_Mode == IMAGE_MODE_GBC || Selected_Constraint_Mode == IMAGE_MODE_MEGADRIVE)
647 set_palette = 1; // activate palette back when switching from GBC
648 Selected_Constraint_Mode = Window_attribute2;
649 for (i = 0; i < sizeof(modes)/sizeof(modes[0]) ; i++)
650 if (Selected_Constraint_Mode == modes[i].mode)
651 {
652 set_grid = modes[i].grid;
653 Hide_cursor();
654 Print_in_window(10, 21+18, modes[i].summary, MC_Dark, MC_Light);
655 Display_cursor();
656 break;
657 }
658 if (Selected_Constraint_Mode == IMAGE_MODE_GBC || Selected_Constraint_Mode == IMAGE_MODE_MEGADRIVE)
659 set_palette = 0;
660 }
661 else if (clicked_button == 4) // palette
662 set_palette = !set_palette;
663 else if (clicked_button == 5) // picture size
664 set_pic_size = !set_pic_size;
665 else if (clicked_button == 6) // enable grid
666 set_grid = !set_grid;
667
668 if (clicked_button > 0) // refresh buttons
669 {
670 Hide_cursor();
671 Print_in_window(10+3, 51+3, set_palette?"X":" ", MC_Black, MC_Light);
672 Print_in_window(10+3, 69+3, set_pic_size?"X":" ", MC_Black, MC_Light);
673 Print_in_window(10+3, 87+3, set_grid?"X":" ", MC_Black, MC_Light);
674 Display_cursor();
675 }
676 }
677 while ( (clicked_button!=1) && (clicked_button!=2) );
678
679 Close_window();
680
681 if (clicked_button==2) // OK
682 {
683 if (Selected_Constraint_Mode > IMAGE_MODE_ANIMATION)
684 {
685 if (set_pic_size)
686 {
687 switch (Selected_Constraint_Mode)
688 {
689 case IMAGE_MODE_ZX:
690 Resize_image(256, 192);
691 End_of_modification();
692 break;
693 case IMAGE_MODE_GBC:
694 Resize_image(160, 144);
695 End_of_modification();
696 break;
697 case IMAGE_MODE_MODE5:
698 Resize_image(288, 256);
699 End_of_modification();
700 break;
701 case IMAGE_MODE_EGX:
702 case IMAGE_MODE_THOMSON:
703 case IMAGE_MODE_C64HIRES:
704 Resize_image(320, 200);
705 End_of_modification();
706 break;
707 case IMAGE_MODE_EGX2:
708 Resize_image(640, 200);
709 End_of_modification();
710 break;
711 case IMAGE_MODE_C64MULTI:
712 case IMAGE_MODE_C64FLI:
713 Resize_image(160, 200);
714 End_of_modification();
715 /// @todo enable WIDE pixels when switching to 160x200
716 break;
717 case IMAGE_MODE_HGR:
718 Resize_image(280, 192);
719 End_of_modification();
720 break;
721 case IMAGE_MODE_DHGR:
722 Resize_image(560, 192);
723 End_of_modification();
724 /// @todo enable TALL pixels when switching to 560x192
725 break;
726 case IMAGE_MODE_TMS9918G2:
727 Resize_image(256, 192);
728 End_of_modification();
729 break;
730 default:
731 break;
732 }
733 }
734 if (Main.backups->Pages->Image_mode > IMAGE_MODE_ANIMATION)
735 Button_Constraint_mode(); // unactivate current mode
736 Button_Constraint_mode(); // activate selected Mode
737 if (set_grid)
738 {
739 switch (Selected_Constraint_Mode)
740 {
741 case IMAGE_MODE_ZX:
742 case IMAGE_MODE_GBC:
743 case IMAGE_MODE_C64HIRES:
744 case IMAGE_MODE_MEGADRIVE:
745 Snap_width = 8;
746 Snap_height = 8;
747 break;
748 case IMAGE_MODE_C64MULTI:
749 case IMAGE_MODE_C64FLI:
750 Snap_width = 4;
751 Snap_height = 8;
752 break;
753 case IMAGE_MODE_RASTER:
754 case IMAGE_MODE_THOMSON:
755 case IMAGE_MODE_TMS9918G2:
756 Snap_width = 8;
757 Snap_height = 999; // maximum value (3 digits)
758 break;
759 case IMAGE_MODE_HGR:
760 Snap_width = 7;
761 Snap_height = 999; // maximum value (3 digits)
762 break;
763 case IMAGE_MODE_DHGR:
764 Snap_width = 4;
765 Snap_height = 999; // maximum value (3 digits)
766 break;
767 default:
768 set_grid = 0;
769 }
770 if (set_grid)
771 {
772 Show_grid = 1;
773 Snap_offset_X = 0;
774 Snap_offset_Y = 0;
775 Snap_mode = 0;
776 //Tilemap_update();
777 Display_all_screen();
778 }
779 }
780 if (set_palette)
781 {
782 switch (Selected_Constraint_Mode)
783 {
784 case IMAGE_MODE_ZX:
785 memset(Main.palette, 0, sizeof(T_Palette));
786 ZX_Spectrum_set_palette(Main.palette);
787 First_color_in_palette = 0;
788 Fore_color = 7;
789 Back_color = 0;
790 break;
791 case IMAGE_MODE_MEGADRIVE: // 64 colors among 512
792 memset(Main.palette + 64, 0, sizeof(T_Components) * (256 - 64));
793 Main.palette[65].R = 255; // for color clashes
794 First_color_in_palette = 0;
795 Fore_color = 15;
796 Back_color = 0;
797 break;
798 case IMAGE_MODE_GBC: // 32 colors among 32768
799 memset(Main.palette + 32, 0, sizeof(T_Components) * (256 - 32));
800 Main.palette[33].R = 255; // for color clashes
801 First_color_in_palette = 0;
802 Fore_color = 3;
803 Back_color = 0;
804 break;
805 case IMAGE_MODE_THOMSON:
806 {
807 static const T_MultipleChoice moto_choices[] = {
808 { MACHINE_TO7, "TO7 / TO7/70", "16 colors" },
809 { MACHINE_MO5, "MO5", "16 colors" },
810 { MACHINE_TO8, "TO9/TO8/TO9+", "4096 colors" },
811 { MACHINE_MO6, "MO6", "4096 colors" },
812 { -1, NULL, NULL }
813 };
814 int machine = Dialog_multiple_choice("Select machine", moto_choices, -1);
815 if (machine >= 0)
816 {
817 memset(Main.palette, 0, sizeof(T_Palette));
818 if (machine == MACHINE_MO5 || machine == MACHINE_MO6)
819 MOTO_set_MO5_palette(Main.palette);
820 else
821 MOTO_set_TO7_palette(Main.palette);
822 if (machine == MACHINE_MO6 || machine == MACHINE_TO8)
823 {
824 Set_palette_Gamma(Config.MOTO_gamma);
825 Set_palette_RGB_scale(16);
826 }
827 First_color_in_palette = 0;
828 Fore_color = 7;
829 Back_color = 0;
830 }
831 }
832 break;
833 case IMAGE_MODE_EGX:
834 case IMAGE_MODE_EGX2:
835 {
836 static const T_MultipleChoice cpc_choices[] = {
837 { 1, "CPC", "27 colors" },
838 { 2, "CPC+", "4096 colors" },
839 { -1, NULL, NULL }
840 };
841 int machine = Dialog_multiple_choice("Select machine", cpc_choices, -1);
842 if (machine >= 0)
843 {
844 memset(Main.palette, 0, sizeof(T_Palette));
845 CPC_set_default_BASIC_palette(Main.palette);
846 First_color_in_palette = 0;
847 Fore_color = 1;
848 Back_color = 0;
849 if (machine == 2)
850 Set_palette_RGB_scale(16);
851 else
852 Set_palette_RGB_scale(3);
853 }
854 }
855 break;
856 case IMAGE_MODE_MODE5:
857 case IMAGE_MODE_RASTER:
858 memset(Main.palette, 0, sizeof(T_Palette));
859 // setup colors 0,1,2,3 to see something in the thumbnail preview of layer 5
860 Main.palette[1].R = 60;
861 Main.palette[2].B = 60;
862 Main.palette[3].G = 60;
863 CPC_set_HW_palette(Main.palette + 0x40);
864 First_color_in_palette = 64;
865 Fore_color = 0x4b;
866 Back_color = 0x54;
867 break;
868 case IMAGE_MODE_C64HIRES:
869 case IMAGE_MODE_C64MULTI:
870 case IMAGE_MODE_C64FLI:
871 memset(Main.palette, 0, sizeof(T_Palette));
872 C64_set_palette(Main.palette);
873 First_color_in_palette = 0;
874 Fore_color = 1;
875 Back_color = 0;
876 break;
877 case IMAGE_MODE_HGR:
878 memset(Main.palette, 0, sizeof(T_Palette));
879 HGR_set_palette(Main.palette);
880 First_color_in_palette = 0;
881 Fore_color = 3;
882 Back_color = 0;
883 break;
884 case IMAGE_MODE_DHGR:
885 memset(Main.palette, 0, sizeof(T_Palette));
886 DHGR_set_palette(Main.palette);
887 First_color_in_palette = 0;
888 Fore_color = 15;
889 Back_color = 0;
890 break;
891 case IMAGE_MODE_TMS9918G2:
892 memset(Main.palette, 0, sizeof(T_Palette));
893 MSX_set_palette(Main.palette);
894 First_color_in_palette = 0;
895 Fore_color = 15; // White
896 Back_color = 1; // Black
897 break;
898 default:
899 break;
900 }
901 for (i = 0; i < 4; i++)
902 memcpy(Main.palette + 252 + i, Favorite_GUI_color(i), sizeof(T_Components));
903 // Refresh palette
904 Set_palette(Main.palette);
905 Compute_optimal_menu_colors(Main.palette);
906 Remap_screen_after_menu_colors_change();
907 Redraw_layered_image();
908 Check_menu_mode();
909 Display_all_screen();
910 //Display_menu_palette();
911 Display_menu();
912 }
913 }
914 }
915
916 Display_cursor();
917 }
918
919 // Tilemap mode
Button_Tilemap_mode(void)920 void Button_Tilemap_mode(void)
921 {
922 Main.tilemap_mode=!Main.tilemap_mode;
923 Tilemap_update();
924 }
925
Button_Tilemap_menu(void)926 void Button_Tilemap_menu(void)
927 {
928 short clicked_button;
929
930 byte flip_x=Config.Tilemap_allow_flipped_x;
931 byte flip_y=Config.Tilemap_allow_flipped_y;
932 byte count=Config.Tilemap_show_count;
933
934 Open_window(166,120,"Tilemap options");
935
936 Window_set_normal_button(6,102,51,14,"Cancel",0,1,KEY_ESC); // 1
937 Window_set_normal_button(110,102,51,14,"OK" ,0,1,KEY_RETURN); // 2
938
939 Print_in_window(24,21, "Detect mirrored",MC_Dark,MC_Light);
940 Window_display_frame(5,17,155,56);
941
942 Print_in_window(37,37, "Horizontally",MC_Black,MC_Light);
943 Window_set_normal_button(18,34,13,13,flip_x?"X":"",0,1,0); // 3
944
945 Print_in_window(37,55, "Vertically",MC_Black,MC_Light);
946 Window_set_normal_button(18,52,13,13,flip_y?"X":"",0,1,0); // 4
947
948 Print_in_window(27,81, "Show count",MC_Black,MC_Light);
949 Window_set_normal_button(7,78,13,13,count?"X":"",0,1,0); // 5
950
951 Update_window_area(0,0,Window_width, Window_height);
952
953 Display_cursor();
954
955 do
956 {
957 clicked_button=Window_clicked_button();
958
959 switch (clicked_button)
960 {
961 case 3 : // Horizontal flip
962 flip_x=!flip_x;
963 Hide_cursor();
964 Print_in_window(21,37,flip_x?"X":" ", MC_Black, MC_Light);
965 Display_cursor();
966 break;
967 case 4 : // Vertical flip
968 flip_y=!flip_y;
969 Hide_cursor();
970 Print_in_window(21,55,flip_y?"X":" ", MC_Black, MC_Light);
971 Display_cursor();
972 break;
973 case 5 : // Count
974 count=!count;
975 Hide_cursor();
976 Print_in_window(10,81,count?"X":" ", MC_Black, MC_Light);
977 Display_cursor();
978 break;
979 }
980 if (Is_shortcut(Key,0x100+BUTTON_HELP))
981 Window_help(BUTTON_EFFECTS, "TILEMAP");
982 }
983 while ( (clicked_button!=1) && (clicked_button!=2) );
984
985 if (clicked_button==2) // OK
986 {
987 byte changed =
988 Config.Tilemap_allow_flipped_x!=flip_x ||
989 Config.Tilemap_allow_flipped_y!=flip_y ||
990 !Main.tilemap_mode;
991
992 Config.Tilemap_allow_flipped_x=flip_x;
993 Config.Tilemap_allow_flipped_y=flip_y;
994 Config.Tilemap_show_count=count;
995
996 if (changed)
997 {
998 Main.tilemap_mode=1;
999 Tilemap_update();
1000 }
1001 }
1002 Close_window();
1003 Display_cursor();
1004 }
1005
1006 //--------------------------------- Stencil ----------------------------------
Button_Stencil_mode(void)1007 void Button_Stencil_mode(void)
1008 {
1009 Stencil_mode=!Stencil_mode;
1010 }
1011
1012
Stencil_tag_color(byte color,byte tag_color)1013 void Stencil_tag_color(byte color, byte tag_color)
1014 {
1015 Window_rectangle(Window_palette_button_list->Pos_X+4+(color >> 4)*10,
1016 Window_palette_button_list->Pos_Y+3+(color & 15)* 5,
1017 2,5,tag_color);
1018 }
1019
Stencil_update_color(byte color)1020 void Stencil_update_color(byte color)
1021 {
1022 Update_window_area(Window_palette_button_list->Pos_X+4+(color >> 4)*10,
1023 Window_palette_button_list->Pos_Y+3+(color & 15)* 5,
1024 2,5);
1025 }
1026
Button_Stencil_menu(void)1027 void Button_Stencil_menu(void)
1028 {
1029 Menu_tag_colors("Stencil",Stencil,&Stencil_mode,1, "STENCIL", SPECIAL_STENCIL_MENU);
1030 }
1031
1032
1033 //--------------------------------- Masque -----------------------------------
Button_Mask_mode(void)1034 void Button_Mask_mode(void)
1035 {
1036 Mask_mode=!Mask_mode;
1037 }
1038
1039
Button_Mask_menu(void)1040 void Button_Mask_menu(void)
1041 {
1042 Menu_tag_colors("Mask",Mask_table,&Mask_mode,1, "MASK", SPECIAL_MASK_MENU);
1043 }
1044
1045
1046 // -------------------------------- Grille -----------------------------------
1047
Button_Snap_mode(void)1048 void Button_Snap_mode(void)
1049 {
1050 Hide_cursor();
1051 Snap_mode=!Snap_mode;
1052 Compute_paintbrush_coordinates();
1053 Display_cursor();
1054 }
1055
1056
Button_Grid_menu(void)1057 void Button_Grid_menu(void)
1058 {
1059 short clicked_button;
1060 word chosen_X =Snap_width;
1061 word chosen_Y =Snap_height;
1062 short dx_selected=Snap_offset_X;
1063 short dy_selected=Snap_offset_Y;
1064
1065 // Entering this window automatically enables "snap"
1066 char snapgrid = 1;
1067
1068 T_Special_button * input_x_button;
1069 T_Special_button * input_y_button;
1070 T_Special_button * input_dx_button;
1071 T_Special_button * input_dy_button;
1072
1073 char str[4];
1074
1075
1076 Open_window(149,118,"Grid");
1077
1078 Window_set_normal_button(12,92,51,14,"Cancel",0,1,KEY_ESC); // 1
1079 Window_set_normal_button(86,92,51,14,"OK" ,0,1,KEY_RETURN); // 2
1080
1081 Print_in_window(11,26, "X:",MC_Dark,MC_Light);
1082 input_x_button = Window_set_input_button(29,24,3); // 3
1083 Num2str(MIN(chosen_X, 999), str, 3);
1084 Window_input_content(input_x_button,str);
1085
1086 Print_in_window(11,47, "Y:",MC_Dark,MC_Light);
1087 input_y_button = Window_set_input_button(29,45,3); // 4
1088 Num2str(MIN(chosen_Y, 999), str, 3);
1089 Window_input_content(input_y_button,str);
1090
1091 Print_in_window(77,26,"dX:",MC_Dark,MC_Light);
1092 input_dx_button = Window_set_input_button(103,24,3); // 5
1093 Num2str(dx_selected,str,3);
1094 Window_input_content(input_dx_button,str);
1095
1096 Print_in_window(77,47,"dY:",MC_Dark,MC_Light);
1097 input_dy_button = Window_set_input_button(103,45,3); // 6
1098 Num2str(dy_selected,str,3);
1099
1100 Window_set_normal_button(12, 62, 14, 14, " ", 0, 1, 0); // 7
1101 if (snapgrid)
1102 Print_in_window(16, 65, "X", MC_Black, MC_Light);
1103 Print_in_window(32, 65,"Snap",MC_Dark,MC_Light);
1104
1105 Window_input_content(input_dy_button,str);
1106 Update_window_area(0,0,Window_width, Window_height);
1107
1108 Display_cursor();
1109
1110 do
1111 {
1112 clicked_button=Window_clicked_button();
1113
1114 switch (clicked_button)
1115 {
1116 case 3 :
1117 Num2str(MIN(chosen_X, 999), str, 3);
1118 Readline(31,26,str,3,INPUT_TYPE_INTEGER);
1119 chosen_X=atoi(str);
1120 // On corrige les dimensions
1121 if ((!chosen_X) || (chosen_X>999))
1122 {
1123 if (!chosen_X)
1124 chosen_X=1;
1125 else
1126 chosen_X=999;
1127 Num2str(chosen_X,str,3);
1128 Window_input_content(input_x_button,str);
1129 }
1130 if (dx_selected>=chosen_X)
1131 {
1132 dx_selected=chosen_X-1;
1133 Num2str(dx_selected,str,3);
1134 Window_input_content(input_dx_button,str);
1135 }
1136 Display_cursor();
1137 break;
1138 case 4 :
1139 Num2str(MIN(chosen_Y, 999), str, 3);
1140 Readline(31,47,str,3,INPUT_TYPE_INTEGER);
1141 chosen_Y=atoi(str);
1142 // On corrige les dimensions
1143 if ((!chosen_Y) || (chosen_Y>999))
1144 {
1145 if (!chosen_Y)
1146 chosen_Y=1;
1147 else
1148 chosen_Y=999;
1149 Num2str(chosen_Y,str,3);
1150 Window_input_content(input_y_button,str);
1151 }
1152 if (dy_selected>=chosen_Y)
1153 {
1154 dy_selected=chosen_Y-1;
1155 Num2str(dy_selected,str,3);
1156 Window_input_content(input_dy_button,str);
1157 }
1158 Display_cursor();
1159 break;
1160 case 5 :
1161 Num2str(dx_selected,str,3);
1162 Readline(105,26,str,3,INPUT_TYPE_INTEGER);
1163 dx_selected=atoi(str);
1164 // On corrige les dimensions
1165 if (dx_selected>=chosen_X)
1166 dx_selected=chosen_X-1;
1167
1168 Num2str(dx_selected,str,3);
1169 Window_input_content(input_dx_button,str);
1170
1171 Display_cursor();
1172 break;
1173 case 6 :
1174 Num2str(dy_selected,str,3);
1175 Readline(105,47,str,3,INPUT_TYPE_INTEGER);
1176 dy_selected=atoi(str);
1177 // On corrige les dimensions
1178 if (dy_selected>=chosen_Y)
1179 dy_selected=chosen_Y-1;
1180
1181 Num2str(dy_selected,str,3);
1182 Window_input_content(input_dy_button,str);
1183
1184 Display_cursor();
1185 break;
1186 case 7:
1187 snapgrid = !snapgrid;
1188 Hide_cursor();
1189 Print_in_window(16, 65, snapgrid?"X":" ", MC_Black, MC_Light);
1190 Display_cursor();
1191 break;
1192 }
1193 if (Is_shortcut(Key,0x100+BUTTON_HELP))
1194 Window_help(BUTTON_EFFECTS, "GRID");
1195 }
1196 while ( (clicked_button!=1) && (clicked_button!=2) );
1197
1198 if (clicked_button==2) // OK
1199 {
1200 byte modified;
1201
1202 modified = Snap_width!=chosen_X
1203 || Snap_height!=chosen_Y
1204 || Snap_offset_X!=dx_selected
1205 || Snap_offset_Y!=dy_selected;
1206
1207 Snap_width=chosen_X;
1208 Snap_height=chosen_Y;
1209 Snap_offset_X=dx_selected;
1210 Snap_offset_Y=dy_selected;
1211 Snap_mode=snapgrid;
1212
1213 if (modified)
1214 {
1215 Tilemap_update();
1216 Disable_tilemap(&Spare);
1217 }
1218 }
1219
1220 Close_window();
1221
1222 Display_cursor();
1223 }
1224
Button_Show_grid(void)1225 void Button_Show_grid(void)
1226 {
1227 Show_grid = !Show_grid;
1228 Hide_cursor();
1229 Display_all_screen();
1230 Display_cursor();
1231 }
1232
1233
1234 // -- Mode Smooth -----------------------------------------------------------
Button_Smooth_mode(void)1235 void Button_Smooth_mode(void)
1236 {
1237 if (Smooth_mode)
1238 Effect_function=No_effect;
1239 else
1240 {
1241 Effect_function=Effect_smooth;
1242 Shade_mode=0;
1243 Quick_shade_mode=0;
1244 Colorize_mode=0;
1245 Tiling_mode=0;
1246 Smear_mode=0;
1247 }
1248 Smooth_mode=!Smooth_mode;
1249 }
1250
1251
1252 static const byte Smooth_default_matrices[4][3][3]=
1253 {
1254 { {1,2,1}, {2,4,2}, {1,2,1} },
1255 { {1,3,1}, {3,9,3}, {1,3,1} },
1256 { {0,1,0}, {1,2,1}, {0,1,0} },
1257 { {2,3,2}, {3,1,3}, {2,3,2} }
1258 };
1259
Button_Smooth_menu(void)1260 void Button_Smooth_menu(void)
1261 {
1262 short clicked_button;
1263 word x,y,i,j;
1264 byte chosen_matrix[3][3];
1265 T_Special_button * matrix_input[3][3];
1266 char str[4];
1267
1268 Open_window(142,109,"Smooth");
1269
1270 Window_set_normal_button(82,59,53,14,"Cancel",0,1,KEY_ESC); // 1
1271 Window_set_normal_button(82,88,53,14,"OK" ,0,1,KEY_RETURN); // 2
1272
1273 Window_display_frame(6,17,130,37);
1274 for (x=11,y=0; y<4; x+=31,y++)
1275 {
1276 Window_set_normal_button(x,22,27,27,"",0,1,KEY_NONE); // 3,4,5,6
1277 for (j=0; j<3; j++)
1278 for (i=0; i<3; i++)
1279 Print_char_in_window(x+2+(i<<3),24+(j<<3),'0'+Smooth_default_matrices[y][i][j],MC_Black,MC_Light);
1280 }
1281
1282 Window_display_frame(6,58, 69,45);
1283 for (j=0; j<3; j++)
1284 for (i=0; i<3; i++)
1285 {
1286 matrix_input[i][j]=Window_set_input_button(10+(i*21),62+(j*13),2); // 7..15
1287 chosen_matrix[i][j] = Smooth_matrix[i][j] ;
1288 Num2str(chosen_matrix[i][j], str, 2);
1289 Window_input_content(matrix_input[i][j],str);
1290 }
1291 Update_window_area(0,0,Window_width, Window_height);
1292
1293 Display_cursor();
1294
1295 do
1296 {
1297 clicked_button=Window_clicked_button();
1298
1299 if (clicked_button>2)
1300 {
1301 if (clicked_button<=6)
1302 {
1303 memcpy(chosen_matrix,Smooth_default_matrices[clicked_button-3],sizeof(chosen_matrix));
1304 Hide_cursor();
1305 for (j=0; j<3; j++)
1306 for (i=0; i<3; i++)
1307 {
1308 Num2str(chosen_matrix[i][j],str,2);
1309 Window_input_content(matrix_input[i][j],str);
1310 }
1311 Display_cursor();
1312 }
1313 else
1314 {
1315 i=clicked_button-7; x=i%3; y=i/3;
1316 Num2str(chosen_matrix[x][y],str,2);
1317 Readline(matrix_input[x][y]->Pos_X+2,
1318 matrix_input[x][y]->Pos_Y+2,
1319 str,2,INPUT_TYPE_INTEGER);
1320 chosen_matrix[x][y]=atoi(str);
1321 Display_cursor();
1322 }
1323 }
1324 if (Is_shortcut(Key,0x100+BUTTON_HELP))
1325 Window_help(BUTTON_EFFECTS, "SMOOTH");
1326 else if (Is_shortcut(Key,SPECIAL_SMOOTH_MENU))
1327 clicked_button=2;
1328 }
1329 while ((clicked_button!=1) && (clicked_button!=2));
1330
1331 Close_window();
1332
1333 if (clicked_button==2) // OK
1334 {
1335 memcpy(Smooth_matrix,chosen_matrix,sizeof(Smooth_matrix));
1336 Smooth_mode=0; // On le met à 0 car la fonct° suivante va le passer à 1
1337 Button_Smooth_mode();
1338 }
1339
1340 Display_cursor();
1341 }
1342
1343
1344 // -- Mode Smear ------------------------------------------------------------
Button_Smear_mode(void)1345 void Button_Smear_mode(void)
1346 {
1347 if (!Smear_mode)
1348 {
1349 if (!Colorize_mode)
1350 Effect_function=No_effect;
1351 Shade_mode=0;
1352 Quick_shade_mode=0;
1353 Smooth_mode=0;
1354 Tiling_mode=0;
1355 }
1356 Smear_mode=!Smear_mode;
1357 }
1358
1359 // -- Mode Colorize ---------------------------------------------------------
Compute_colorize_table(void)1360 void Compute_colorize_table(void)
1361 {
1362 word index;
1363 word factor_a;
1364 word factor_b;
1365
1366 factor_a=256*(100-Colorize_opacity)/100;
1367 factor_b=256*( Colorize_opacity)/100;
1368
1369 for (index=0;index<256;index++)
1370 {
1371 Factors_table[index]=index*factor_a;
1372 Factors_inv_table[index]=index*factor_b;
1373 }
1374 }
1375
1376
Button_Colorize_mode(void)1377 void Button_Colorize_mode(void)
1378 {
1379 if (Colorize_mode)
1380 Effect_function=No_effect;
1381 else
1382 {
1383 switch(Colorize_current_mode)
1384 {
1385 case 0 :
1386 Effect_function=Effect_interpolated_colorize;
1387 break;
1388 case 1 :
1389 Effect_function=Effect_additive_colorize;
1390 break;
1391 case 2 :
1392 Effect_function=Effect_substractive_colorize;
1393 break;
1394 case 3 :
1395 Effect_function=Effect_alpha_colorize;
1396 }
1397 Shade_mode=0;
1398 Quick_shade_mode=0;
1399 Smooth_mode=0;
1400 Tiling_mode=0;
1401 }
1402 Colorize_mode=!Colorize_mode;
1403 }
1404
1405
Button_Colorize_display_selection(int mode)1406 void Button_Colorize_display_selection(int mode)
1407 {
1408 short y_pos=0; // Ligne où afficher les flèches de sélection
1409
1410 // On commence par effacer les anciennes sélections:
1411 // Partie gauche
1412 Print_in_window(4,37," ",MC_Black,MC_Light);
1413 Print_in_window(4,57," ",MC_Black,MC_Light);
1414 Print_in_window(4,74," ",MC_Black,MC_Light);
1415 Print_in_window(4,91," ",MC_Black,MC_Light);
1416 // Partie droite
1417 Print_in_window(129,37," ",MC_Black,MC_Light);
1418 Print_in_window(129,57," ",MC_Black,MC_Light);
1419 Print_in_window(129,74," ",MC_Black,MC_Light);
1420 Print_in_window(129,91," ",MC_Black,MC_Light);
1421
1422 // Ensuite, on affiche la flèche là où il le faut:
1423 switch(mode)
1424 {
1425 case 0 : // Méthode interpolée
1426 y_pos=37;
1427 break;
1428 case 1 : // Méthode additive
1429 y_pos=57;
1430 break;
1431 case 2 : // Méthode soustractive
1432 y_pos=74;
1433 break;
1434 case 3 : // Méthode alpha
1435 y_pos=91;
1436 }
1437 Print_in_window(4,y_pos,"\020",MC_Black,MC_Light);
1438 Print_in_window(129,y_pos,"\021",MC_Black,MC_Light);
1439 }
1440
Button_Colorize_menu(void)1441 void Button_Colorize_menu(void)
1442 {
1443 short chosen_opacity;
1444 short selected_mode;
1445 short clicked_button;
1446 char str[4];
1447
1448 Open_window(140,135,"Transparency");
1449
1450 Print_in_window(16,23,"Opacity:",MC_Dark,MC_Light);
1451 Window_set_input_button(87,21,3); // 1
1452 Print_in_window(117,23,"%",MC_Dark,MC_Light);
1453 Window_set_normal_button(16,34,108,14,"Interpolate",1,1,KEY_i); // 2
1454 Window_display_frame(12,18,116,34);
1455
1456 Window_set_normal_button(16,54,108,14,"Additive" ,2,1,KEY_d); // 3
1457 Window_set_normal_button(16,71,108,14,"Subtractive",1,1,KEY_s); // 4
1458 Window_set_normal_button(16,88,108,14,"Alpha",1,1,KEY_a); // 4
1459
1460 Window_set_normal_button(16,111, 51,14,"Cancel" ,0,1,KEY_ESC); // 5
1461 Window_set_normal_button(73,111, 51,14,"OK" ,0,1,KEY_RETURN); // 6
1462
1463 Num2str(Colorize_opacity,str,3);
1464 Window_input_content(Window_special_button_list,str);
1465 Button_Colorize_display_selection(Colorize_current_mode);
1466
1467 chosen_opacity=Colorize_opacity;
1468 selected_mode =Colorize_current_mode;
1469
1470 Update_window_area(0,0,Window_width, Window_height);
1471 Display_cursor();
1472
1473 do
1474 {
1475 clicked_button=Window_clicked_button();
1476
1477 switch(clicked_button)
1478 {
1479 case 1: // Zone de saisie de l'opacité
1480 Num2str(chosen_opacity,str,3);
1481 Readline(89,23,str,3,INPUT_TYPE_INTEGER);
1482 chosen_opacity=atoi(str);
1483 // On corrige le pourcentage
1484 if (chosen_opacity>100)
1485 {
1486 chosen_opacity=100;
1487 Num2str(chosen_opacity,str,3);
1488 Window_input_content(Window_special_button_list,str);
1489 }
1490 Display_cursor();
1491 break;
1492 case 2: // Interpolated method
1493 case 3: // Additive method
1494 case 4: // Substractive method
1495 case 5: // Alpha method
1496 selected_mode=clicked_button-2;
1497 Hide_cursor();
1498 Button_Colorize_display_selection(selected_mode);
1499 Display_cursor();
1500 }
1501 if (Is_shortcut(Key,0x100+BUTTON_HELP))
1502 Window_help(BUTTON_EFFECTS, "TRANSPARENCY");
1503 else if (Is_shortcut(Key,SPECIAL_COLORIZE_MENU))
1504 clicked_button=7;
1505 }
1506 while (clicked_button<6);
1507
1508 Close_window();
1509
1510 if (clicked_button==7) // OK
1511 {
1512 Colorize_opacity =chosen_opacity;
1513 Colorize_current_mode=selected_mode;
1514 Compute_colorize_table();
1515 Colorize_mode=0; // On le met à 0 car la fonct° suivante va le passer à 1
1516 Button_Colorize_mode();
1517 }
1518
1519 Display_cursor();
1520 }
1521
1522
1523 // -- Mode Tiling -----------------------------------------------------------
Button_Tiling_mode(void)1524 void Button_Tiling_mode(void)
1525 {
1526 if (Tiling_mode)
1527 Effect_function=No_effect;
1528 else
1529 {
1530 Effect_function=Effect_tiling;
1531 Shade_mode=0;
1532 Quick_shade_mode=0;
1533 Colorize_mode=0;
1534 Smooth_mode=0;
1535 Smear_mode=0;
1536 }
1537 Tiling_mode=!Tiling_mode;
1538 }
1539
1540
Button_Tiling_menu(void)1541 void Button_Tiling_menu(void)
1542 {
1543 short clicked_button;
1544 short chosen_offset_x=Tiling_offset_X;
1545 short chosen_offset_y=Tiling_offset_Y;
1546 char str[5];
1547 T_Special_button * input_offset_x_button;
1548 T_Special_button * input_offset_y_button;
1549
1550 Open_window(138,79,"Tiling");
1551
1552 Window_set_normal_button(13,55,51,14,"Cancel",0,1,KEY_ESC); // 1
1553 Window_set_normal_button(74,55,51,14,"OK" ,0,1,KEY_RETURN); // 2
1554 input_offset_x_button = Window_set_input_button(91,21,4); // 3
1555 input_offset_y_button = Window_set_input_button(91,35,4); // 4
1556 Print_in_window(12,23,"Offset X:",MC_Dark,MC_Light);
1557 Print_in_window(12,37,"Offset Y:",MC_Dark,MC_Light);
1558
1559 Num2str(Tiling_offset_X,str,4);
1560 Window_input_content(input_offset_x_button,str);
1561 Num2str(Tiling_offset_Y,str,4);
1562 Window_input_content(input_offset_y_button,str);
1563
1564 Update_window_area(0,0,Window_width, Window_height);
1565 Display_cursor();
1566
1567 do
1568 {
1569 clicked_button=Window_clicked_button();
1570
1571 if (clicked_button==3) // Zone de saisie du décalage X
1572 {
1573 Num2str(chosen_offset_x,str,4);
1574 Readline(93,23,str,4,INPUT_TYPE_INTEGER);
1575 chosen_offset_x=atoi(str);
1576 // On corrige le décalage en X
1577 if (chosen_offset_x>=Brush_width)
1578 {
1579 chosen_offset_x=Brush_width-1;
1580 Num2str(chosen_offset_x,str,4);
1581 Window_input_content(input_offset_x_button,str);
1582 }
1583 Display_cursor();
1584 }
1585 else
1586 if (clicked_button==4) // Zone de saisie du décalage Y
1587 {
1588 Num2str(chosen_offset_y,str,4);
1589 Readline(93,37,str,4,INPUT_TYPE_INTEGER);
1590 chosen_offset_y=atoi(str);
1591 // On corrige le décalage en Y
1592 if (chosen_offset_y>=Brush_height)
1593 {
1594 chosen_offset_y=Brush_height-1;
1595 Num2str(chosen_offset_y,str,4);
1596 Window_input_content(input_offset_y_button,str);
1597 }
1598 Display_cursor();
1599 }
1600 if (Is_shortcut(Key,0x100+BUTTON_HELP))
1601 Window_help(BUTTON_EFFECTS, "TILING");
1602 }
1603 while ( (clicked_button!=1) && (clicked_button!=2) );
1604
1605 Close_window();
1606
1607 if (clicked_button==2) // OK
1608 {
1609 Tiling_offset_X=chosen_offset_x;
1610 Tiling_offset_Y=chosen_offset_y;
1611 if (!Tiling_mode)
1612 Button_Tiling_mode();
1613 }
1614
1615 Display_cursor();
1616 }
1617
1618 // -- All modes off ---------------------------------------------------------
Effects_off(void)1619 void Effects_off(void)
1620 {
1621 Effect_function=No_effect;
1622 Shade_mode=0;
1623 Quick_shade_mode=0;
1624 Colorize_mode=0;
1625 Smooth_mode=0;
1626 Tiling_mode=0;
1627 Smear_mode=0;
1628 Stencil_mode=0;
1629 Mask_mode=0;
1630 Sieve_mode=0;
1631 Snap_mode=0;
1632 Main.tilemap_mode=0;
1633 }
1634
1635
1636 // -- Mode Sieve (Sieve) ----------------------------------------------------
1637
Button_Sieve_mode(void)1638 void Button_Sieve_mode(void)
1639 {
1640 Sieve_mode=!Sieve_mode;
1641 }
1642
1643
Draw_sieve_scaled(short origin_x,short origin_y)1644 void Draw_sieve_scaled(short origin_x, short origin_y)
1645 {
1646 short x_pos;
1647 short y_pos;
1648 short x_size;
1649 short y_size;
1650 short start_x=Window_pos_X+(Menu_factor_X*230);
1651 short start_y=Window_pos_Y+(Menu_factor_Y*78);
1652
1653 x_size=Menu_factor_X*5; // |_ Taille d'une case
1654 y_size=Menu_factor_Y*5; // | de la trame zoomée
1655
1656 // On efface de contenu précédent
1657 Block(origin_x,origin_y,
1658 Menu_factor_X*Window_special_button_list->Width,
1659 Menu_factor_Y*Window_special_button_list->Height,MC_Light);
1660
1661 for (y_pos=0; y_pos<Sieve_height; y_pos++)
1662 for (x_pos=0; x_pos<Sieve_width; x_pos++)
1663 {
1664 // Bordures de la case
1665 Block(origin_x+(x_pos*x_size),
1666 origin_y+((y_pos+1)*y_size)-Menu_factor_Y,
1667 x_size, Menu_factor_Y,MC_Dark);
1668 Block(origin_x+((x_pos+1)*x_size)-Menu_factor_X,
1669 origin_y+(y_pos*y_size),
1670 Menu_factor_X, y_size-1,MC_Dark);
1671 // Contenu de la case
1672 Block(origin_x+(x_pos*x_size), origin_y+(y_pos*y_size),
1673 x_size-Menu_factor_X, y_size-Menu_factor_Y,
1674 (Sieve[x_pos][y_pos])?MC_White:MC_Black);
1675 }
1676
1677 // Dessiner la preview de la trame
1678 x_size=Menu_factor_X*51; // |_ Taille de la fenêtre
1679 y_size=Menu_factor_Y*71; // | de la preview
1680 for (y_pos=0; y_pos<y_size; y_pos++)
1681 for (x_pos=0; x_pos<x_size; x_pos++)
1682 Pixel(start_x+x_pos,start_y+y_pos,(Sieve[x_pos%Sieve_width][y_pos%Sieve_height])?MC_White:MC_Black);
1683 Update_rect(start_x,start_y,x_size,y_size);
1684 }
1685
1686
Draw_preset_sieve_patterns(void)1687 void Draw_preset_sieve_patterns(void)
1688 {
1689 short index;
1690 short i,j;
1691 //short x_size,y_size;
1692 short Zoom;
1693
1694 Zoom=Min(Menu_factor_X,Menu_factor_Y);
1695
1696 //x_size=1;//Menu_factor_X/Pixel_height;
1697 //y_size=1;//Menu_factor_Y/Pixel_width;
1698
1699 for (index=0; index<12; index++)
1700 for (j=0; j<16*Menu_factor_Y/Zoom; j++)
1701 for (i=0; i<16*Menu_factor_X/Zoom; i++)
1702 Block(((index*23+10)*Menu_factor_X)+i*Zoom+Window_pos_X,
1703 (22*Menu_factor_Y)+j*Zoom+Window_pos_Y,Zoom,Zoom,
1704 ((Gfx->Sieve_pattern[index][j&0xF]>>(15-(i&0xF)))&1)?MC_White:MC_Black);
1705
1706 Update_rect(ToWinX(10),ToWinY(22),ToWinL(12*23+16),ToWinH(16));
1707 }
1708
1709
Copy_preset_sieve(byte index)1710 void Copy_preset_sieve(byte index)
1711 {
1712 short i,j;
1713
1714 for (j=0; j<16; j++)
1715 for (i=0; i<16; i++)
1716 Sieve[i][j]=(Gfx->Sieve_pattern[index][j]>>(15-i))&1;
1717 Sieve_width=16;
1718 Sieve_height=16;
1719 }
1720
1721
Invert_trame(void)1722 void Invert_trame(void)
1723 {
1724 byte x_pos,y_pos;
1725
1726 for (y_pos=0; y_pos<Sieve_height; y_pos++)
1727 for (x_pos=0; x_pos<Sieve_width; x_pos++)
1728 Sieve[x_pos][y_pos]=!(Sieve[x_pos][y_pos]);
1729 }
1730
1731 // Rafraichit toute la zone correspondant à la trame zoomee.
Update_sieve_area(short x,short y)1732 void Update_sieve_area(short x, short y)
1733 {
1734 Update_rect(x,y,80*Menu_factor_X,80*Menu_factor_Y);
1735 }
1736
1737
Button_Sieve_menu(void)1738 void Button_Sieve_menu(void)
1739 {
1740 short clicked_button;
1741 short index;
1742 short x_pos;
1743 short y_pos;
1744 short old_x_pos=0;
1745 short old_y_pos=0;
1746 short origin_x;
1747 short origin_y;
1748 static byte default_bg_color=0;
1749 T_Normal_button * button_bg_color;
1750 char str[3];
1751 byte temp; // Octet temporaire servant à n'importe quoi
1752 short old_sieve_width=Sieve_width;
1753 short old_sieve_height=Sieve_height;
1754 byte old_sieve[16][16];
1755
1756 memcpy(old_sieve,Sieve,256);
1757
1758 Open_window(290,179,"Sieve");
1759
1760 Window_display_frame ( 7, 65,130,43);
1761 Window_display_frame ( 7,110,130,43);
1762 Window_display_frame_in(142, 68, 82,82);
1763 Window_display_frame_in(229, 77, 53,73);
1764
1765 Print_in_window(228, 68,"Preview",MC_Dark,MC_Light);
1766 Print_in_window( 27, 83,"Scroll" ,MC_Dark,MC_Light);
1767 Print_in_window( 23,120,"Width:" ,MC_Dark,MC_Light);
1768 Print_in_window( 15,136,"Height:",MC_Dark,MC_Light);
1769
1770 Window_set_special_button(143,69,80,80,0); // 1
1771
1772 Window_set_normal_button(175,157,51,14,"Cancel",0,1,KEY_ESC); // 2
1773 Window_set_normal_button(230,157,51,14,"OK" ,0,1,KEY_RETURN); // 3
1774
1775 Window_set_normal_button( 8,157,51,14,"Clear" ,1,1,KEY_c); // 4
1776 Window_set_normal_button( 63,157,51,14,"Invert",1,1,KEY_i); // 5
1777
1778 Window_set_normal_button( 8,46,131,14,"Get from brush" ,1,1,KEY_g); // 6
1779 Window_set_normal_button(142,46,139,14,"Transfer to brush",1,1,KEY_t); // 7
1780
1781 Window_set_normal_button(109,114,11,11,"\030",0,1,KEY_UP|GFX2_MOD_SHIFT); // 8
1782 Window_set_normal_button(109,138,11,11,"\031",0,1,KEY_DOWN|GFX2_MOD_SHIFT); // 9
1783 Window_set_normal_button( 97,126,11,11,"\033",0,1,KEY_LEFT|GFX2_MOD_SHIFT); // 10
1784 Window_set_normal_button(121,126,11,11,"\032",0,1,KEY_RIGHT|GFX2_MOD_SHIFT); // 11
1785 button_bg_color = Window_set_normal_button(109,126,11,11,"" ,0,1,KEY_INSERT); // 12
1786 Window_rectangle(button_bg_color->Pos_X+2,
1787 button_bg_color->Pos_Y+2,
1788 7, 7, (default_bg_color)?MC_White:MC_Black);
1789
1790 Window_set_repeatable_button(109, 69,11,11,"\030",0,1,KEY_UP); // 13
1791 Window_set_repeatable_button(109, 93,11,11,"\031",0,1,KEY_DOWN); // 14
1792 Window_set_repeatable_button( 97, 81,11,11,"\033",0,1,KEY_LEFT); // 15
1793 Window_set_repeatable_button(121, 81,11,11,"\032",0,1,KEY_RIGHT); // 16
1794
1795 for (index=0; index<12; index++)
1796 Window_set_normal_button((index*23)+8,20,20,20,"",0,1,KEY_F1+index); // 17 -> 28
1797 Draw_preset_sieve_patterns();
1798
1799 origin_x=Window_pos_X+(Menu_factor_X*Window_special_button_list->Pos_X);
1800 origin_y=Window_pos_Y+(Menu_factor_Y*Window_special_button_list->Pos_Y);
1801
1802 Num2str(Sieve_width,str,2);
1803 Print_in_window(71,120,str,MC_Black,MC_Light);
1804 Num2str(Sieve_height,str,2);
1805 Print_in_window(71,136,str,MC_Black,MC_Light);
1806 Draw_sieve_scaled(origin_x,origin_y);
1807
1808 Update_window_area(0,0,Window_width, Window_height);
1809
1810 Display_cursor();
1811
1812 do
1813 {
1814 clicked_button=Window_clicked_button();
1815
1816 origin_x=Window_pos_X+(Menu_factor_X*Window_special_button_list->Pos_X);
1817 origin_y=Window_pos_Y+(Menu_factor_Y*Window_special_button_list->Pos_Y);
1818
1819
1820 switch (clicked_button)
1821 {
1822 case -1 :
1823 case 0 :
1824 break;
1825
1826 case 1 : // Zone de dessin de la trame
1827 /* // Version qui n'accepte pas les clicks sur la grille
1828 x_pos=(Mouse_X-origin_x)/Menu_factor_X;
1829 y_pos=(Mouse_Y-origin_y)/Menu_factor_Y;
1830 if ( (x_pos%5<4) && (y_pos%5<4) )
1831 {
1832 x_pos/=5;
1833 y_pos/=5;
1834 if ( (x_pos<Sieve_width) && (y_pos<Sieve_height) )
1835 }
1836 */
1837 x_pos=(Mouse_X-origin_x)/(Menu_factor_X*5);
1838 y_pos=(Mouse_Y-origin_y)/(Menu_factor_Y*5);
1839 if ( (x_pos<Sieve_width) && (y_pos<Sieve_height) )
1840 {
1841 temp=(Mouse_K==LEFT_SIDE);
1842 if ( (x_pos!=old_x_pos) || (y_pos!=old_y_pos)
1843 || (Sieve[x_pos][y_pos]!=temp) )
1844 {
1845 old_x_pos=x_pos;
1846 old_y_pos=y_pos;
1847 Sieve[x_pos][y_pos]=temp;
1848 x_pos=Menu_factor_X*5;
1849 y_pos=Menu_factor_Y*5;
1850 Hide_cursor();
1851 if (temp)
1852 temp=MC_White;
1853 else
1854 temp=MC_Black;
1855 // Affichage du pixel dans la fenêtre zoomée
1856 Block(origin_x+(old_x_pos*x_pos), origin_y+(old_y_pos*y_pos),
1857 x_pos-Menu_factor_X, y_pos-Menu_factor_Y, temp);
1858 // Mise à jour de la preview
1859 Draw_sieve_scaled(origin_x,origin_y);
1860 Display_cursor();
1861 // Maj de la case seule
1862 Update_rect(origin_x+(old_x_pos*x_pos), origin_y+(old_y_pos*y_pos),Menu_factor_X*5,Menu_factor_Y*5);
1863 }
1864 }
1865 break;
1866
1867 case 2 : // Cancel
1868 case 3 : // OK
1869 break;
1870
1871 case 4 : // Clear
1872 Hide_cursor();
1873 memset(Sieve,default_bg_color,256);
1874 Draw_sieve_scaled(origin_x,origin_y);
1875 Display_cursor();
1876 Update_sieve_area(origin_x, origin_y);
1877 break;
1878
1879 case 5 : // Invert
1880 Hide_cursor();
1881 Invert_trame();
1882 Draw_sieve_scaled(origin_x,origin_y);
1883 Display_cursor();
1884 Update_sieve_area(origin_x, origin_y);
1885 break;
1886
1887 case 6 : // Get from brush
1888 Hide_cursor();
1889 Sieve_width=(Brush_width>16)?16:Brush_width;
1890 Sieve_height=(Brush_height>16)?16:Brush_height;
1891 for (y_pos=0; y_pos<Sieve_height; y_pos++)
1892 for (x_pos=0; x_pos<Sieve_width; x_pos++)
1893 Sieve[x_pos][y_pos]=(Read_pixel_from_brush(x_pos,y_pos)!=Back_color);
1894 Draw_sieve_scaled(origin_x,origin_y);
1895 Num2str(Sieve_height,str,2);
1896 Print_in_window(71,136,str,MC_Black,MC_Light);
1897 Num2str(Sieve_width,str,2);
1898 Print_in_window(71,120,str,MC_Black,MC_Light);
1899 Display_cursor();
1900 Update_sieve_area(origin_x, origin_y);
1901 break;
1902
1903 case 7 : // Transfer to brush
1904
1905 if (Realloc_brush(Sieve_width, Sieve_height, NULL, NULL))
1906 break;
1907
1908 for (y_pos=0; y_pos<Sieve_height; y_pos++)
1909 for (x_pos=0; x_pos<Sieve_width; x_pos++)
1910 *(Brush_original_pixels + y_pos * Brush_width + x_pos) = (Sieve[x_pos][y_pos])?Fore_color:Back_color;
1911
1912 // Grab palette
1913 memcpy(Brush_original_palette, Main.palette,sizeof(T_Palette));
1914 // Remap (no change)
1915 Remap_brush();
1916
1917 Brush_offset_X=(Brush_width>>1);
1918 Brush_offset_Y=(Brush_height>>1);
1919
1920 Change_paintbrush_shape(PAINTBRUSH_SHAPE_COLOR_BRUSH);
1921 break;
1922
1923 case 8 : // Réduire hauteur
1924 if (Sieve_height>1)
1925 {
1926 Hide_cursor();
1927 Sieve_height--;
1928 Num2str(Sieve_height,str,2);
1929 Print_in_window(71,136,str,MC_Black,MC_Light);
1930 Draw_sieve_scaled(origin_x,origin_y);
1931 Display_cursor();
1932 Update_sieve_area(origin_x, origin_y);
1933 }
1934 break;
1935
1936 case 9 : // Agrandir hauteur
1937 if (Sieve_height<16)
1938 {
1939 Hide_cursor();
1940 for (index=0; index<Sieve_width; index++)
1941 Sieve[index][Sieve_height]=default_bg_color;
1942 Sieve_height++;
1943 Num2str(Sieve_height,str,2);
1944 Print_in_window(71,136,str,MC_Black,MC_Light);
1945 Draw_sieve_scaled(origin_x,origin_y);
1946 Display_cursor();
1947 Update_sieve_area(origin_x, origin_y);
1948 }
1949 break;
1950
1951 case 10 : // Réduire largeur
1952 if (Sieve_width>1)
1953 {
1954 Hide_cursor();
1955 Sieve_width--;
1956 Num2str(Sieve_width,str,2);
1957 Print_in_window(71,120,str,MC_Black,MC_Light);
1958 Draw_sieve_scaled(origin_x,origin_y);
1959 Display_cursor();
1960 Update_sieve_area(origin_x, origin_y);
1961 }
1962 break;
1963
1964 case 11 : // Agrandir largeur
1965 if (Sieve_width<16)
1966 {
1967 Hide_cursor();
1968 for (index=0; index<Sieve_height; index++)
1969 Sieve[Sieve_width][index]=default_bg_color;
1970 Sieve_width++;
1971 Num2str(Sieve_width,str,2);
1972 Print_in_window(71,120,str,MC_Black,MC_Light);
1973 Draw_sieve_scaled(origin_x,origin_y);
1974 Display_cursor();
1975 Update_sieve_area(origin_x, origin_y);
1976 }
1977 break;
1978
1979 case 12 : // Toggle octets insérés
1980 Hide_cursor();
1981 default_bg_color=!default_bg_color;
1982 Window_rectangle(button_bg_color->Pos_X+2,
1983 button_bg_color->Pos_Y+2,
1984 7, 7, (default_bg_color)?MC_White:MC_Black);
1985 Display_cursor();
1986 Update_window_area(
1987 button_bg_color->Pos_X+2,
1988 button_bg_color->Pos_Y+2,
1989 7,
1990 7);
1991
1992 break;
1993
1994 case 13 : // Scroll vers le haut
1995 Hide_cursor();
1996 for (x_pos=0; x_pos<Sieve_width; x_pos++)
1997 {
1998 temp=Sieve[x_pos][0]; // Octet temporaire
1999 for (y_pos=1; y_pos<Sieve_height; y_pos++)
2000 Sieve[x_pos][y_pos-1]=Sieve[x_pos][y_pos];
2001 Sieve[x_pos][Sieve_height-1]=temp;
2002 }
2003 Draw_sieve_scaled(origin_x,origin_y);
2004 Display_cursor();
2005 Update_sieve_area(origin_x, origin_y);
2006 break;
2007
2008 case 14 : // Scroll vers le bas
2009 Hide_cursor();
2010 for (x_pos=0; x_pos<Sieve_width; x_pos++)
2011 {
2012 temp=Sieve[x_pos][Sieve_height-1]; // Octet temporaire
2013 for (y_pos=Sieve_height-1; y_pos>0; y_pos--)
2014 Sieve[x_pos][y_pos]=Sieve[x_pos][y_pos-1];
2015 Sieve[x_pos][0]=temp;
2016 }
2017 Draw_sieve_scaled(origin_x,origin_y);
2018 Display_cursor();
2019 Update_sieve_area(origin_x, origin_y);
2020 break;
2021
2022 case 15 : // Scroll vers la gauche
2023 Hide_cursor();
2024 for (y_pos=0; y_pos<Sieve_height; y_pos++)
2025 {
2026 temp=Sieve[0][y_pos]; // Octet temporaire
2027 for (x_pos=1; x_pos<Sieve_width; x_pos++)
2028 Sieve[x_pos-1][y_pos]=Sieve[x_pos][y_pos];
2029 Sieve[Sieve_width-1][y_pos]=temp;
2030 }
2031 Draw_sieve_scaled(origin_x,origin_y);
2032 Display_cursor();
2033 Update_sieve_area(origin_x, origin_y);
2034 break;
2035
2036 case 16 : // Scroll vers la droite
2037 Hide_cursor();
2038 for (y_pos=0; y_pos<Sieve_height; y_pos++)
2039 {
2040 temp=Sieve[Sieve_width-1][y_pos]; // Octet temporaire
2041 for (x_pos=Sieve_width-1; x_pos>0; x_pos--)
2042 Sieve[x_pos][y_pos]=Sieve[x_pos-1][y_pos];
2043 Sieve[0][y_pos]=temp;
2044 }
2045 Draw_sieve_scaled(origin_x,origin_y);
2046 Display_cursor();
2047 Update_sieve_area(origin_x, origin_y);
2048 break;
2049
2050 default : // Boutons de trames prédéfinies
2051 Hide_cursor();
2052 Copy_preset_sieve(clicked_button-17);
2053 Draw_sieve_scaled(origin_x,origin_y);
2054 Num2str(Sieve_width,str,2);
2055 Print_in_window(71,120,str,MC_Black,MC_Light);
2056 Num2str(Sieve_height,str,2);
2057 Print_in_window(71,136,str,MC_Black,MC_Light);
2058 Draw_sieve_scaled(origin_x,origin_y);
2059 Display_cursor();
2060 Update_sieve_area(origin_x, origin_y);
2061 }
2062 if (Is_shortcut(Key,0x100+BUTTON_HELP))
2063 {
2064 Key=0;
2065 Window_help(BUTTON_EFFECTS, "SIEVE");
2066 }
2067 }
2068 while ( (clicked_button!=2) && (clicked_button!=3) );
2069
2070
2071 Close_window();
2072
2073 if (clicked_button==2) // Cancel
2074 {
2075 Sieve_width=old_sieve_width;
2076 Sieve_height=old_sieve_height;
2077 memcpy(Sieve,old_sieve,256);
2078 }
2079
2080 if ( (clicked_button==3) && (!Sieve_mode) ) // OK
2081 Button_Sieve_mode();
2082
2083 Display_cursor();
2084 }
2085
2086
2087