diff --git a/src/layers.c b/src/layers.c
index d82df062..17aaa873 100644
--- a/src/layers.c
+++ b/src/layers.c
@@ -1,697 +1,697 @@
-/* vim:expandtab:ts=2 sw=2:
-*/
-/* Grafx2 - The Ultimate 256-color bitmap paint program
-
- Copyright 2009 Yves Rizoud
- Copyright 2007 Adrien Destugues
- Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
-
- Grafx2 is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; version 2
- of the License.
-
- Grafx2 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Grafx2; if not, see
-*/
-#include "const.h"
-#include "struct.h"
-#include "global.h"
-#include "windows.h"
-#include "engine.h"
-#include "pages.h"
-#include "sdlscreen.h"
-#include "input.h"
-#include "help.h"
-#include "misc.h"
-#include "readline.h"
-#include "graph.h"
-
-void Layer_activate(int layer, short side)
-{
- word old_layers;
-
- if (layer >= Main_backups->Pages->Nb_layers)
- return;
-
- // Keep a copy of which layers were visible
- old_layers = Main_layers_visible;
-
- if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
- {
- if (side == RIGHT_SIDE)
- {
- // Right-click on current layer
- if (Main_current_layer == layer)
- {
- if (Main_layers_visible == (dword)(1<Pages);
- //Update_FX_feedback(Config.FX_Feedback);
- Update_pixel_renderer();
- Display_all_screen();
- Display_layerbar();
- Display_cursor();
-}
-
-void Button_Layer_add(void)
-{
- int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5};
-
- Hide_cursor();
-
- if (Main_backups->Pages->Nb_layers < max[Main_backups->Pages->Image_mode])
- {
- // Backup with unchanged layers
- Backup_layers(LAYER_NONE);
- if (!Add_layer(Main_backups,Main_current_layer+1))
- {
- Update_depth_buffer();
- // I just noticed this might be unneeded, since the new layer
- // is transparent, it shouldn't have any visible effect.
- Display_all_screen();
- Display_layerbar();
- End_of_modification();
- }
- }
-
- Unselect_button(BUTTON_LAYER_ADD);
- Unselect_button(BUTTON_ANIM_ADD_FRAME);
- Display_cursor();
-}
-
-
-void Button_Layer_duplicate(void)
-{
- int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5};
-
- Hide_cursor();
-
- if (Main_backups->Pages->Nb_layers < max[Main_backups->Pages->Image_mode])
- {
- // Backup with unchanged layers
- Backup_layers(LAYER_NONE);
- if (!Add_layer(Main_backups,Main_current_layer+1))
- {
- // Make a copy of current image
- memcpy(
- Main_backups->Pages->Image[Main_current_layer].Pixels,
- Main_backups->Pages->Image[Main_current_layer-1].Pixels,
- Main_backups->Pages->Width*Main_backups->Pages->Height);
-
- if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) {
- Update_depth_buffer();
- // I just noticed this might be unneeded, since the new layer
- // is transparent, it shouldn't have any visible effect.
- Display_all_screen();
- }
- Display_layerbar();
- End_of_modification();
- }
- }
-
- Unselect_button(BUTTON_LAYER_ADD);
- Unselect_button(BUTTON_ANIM_ADD_FRAME);
- Display_cursor();
-}
-
-void Button_Layer_remove(void)
-{
- Hide_cursor();
-
- if (Main_backups->Pages->Nb_layers > 1)
- {
- // Backup with unchanged layers
- Backup_layers(LAYER_NONE);
- if (!Delete_layer(Main_backups,Main_current_layer))
- {
- Update_screen_targets();
- Redraw_layered_image();
-
- Display_all_screen();
- Display_layerbar();
- End_of_modification();
- }
- }
- Unselect_button(BUTTON_LAYER_REMOVE);
- Unselect_button(BUTTON_ANIM_REMOVE_FRAME);
- Display_cursor();
-}
-
-short Layer_under_mouse(void)
-{
- short layer;
- // Determine which button is clicked according to mouse position
- layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width)
- / Layer_button_width;
-
- // Safety required because the mouse cursor can have slided outside button.
- if (layer < 0)
- layer=0;
- else if (layer > Main_backups->Pages->Nb_layers-1)
- layer=Main_backups->Pages->Nb_layers-1;
-
- return layer;
-}
-
-void Button_Layer_select(void)
-{
- short layer = Layer_under_mouse();
- Layer_activate(layer, LEFT_SIDE);
- Mouse_K=0;
-}
-
-void Button_Layer_toggle(void)
-{
- int layer;
- // Determine which button is clicked according to mouse position
- layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width)
- / Layer_button_width;
-
- // Safety required because the mouse cursor can have slided outside button.
- if (layer < 0)
- layer=0;
- else if (layer > Main_backups->Pages->Nb_layers-1)
- layer=Main_backups->Pages->Nb_layers-1;
-
- Layer_activate(layer, RIGHT_SIDE);
- Mouse_K=0;
-}
-
-static void Draw_transparent_color(byte color)
-{
- char buf[4];
- Num2str(color, buf, 3);
- Print_in_window(63,39,buf,MC_Black,MC_Light);
- Window_rectangle(90,39,13,7,color);
-}
-
-static void Draw_transparent_background(byte background)
-{
- Print_in_window(99,57,background?"X":" ",MC_Black,MC_Light);
-}
-
-
-void Button_Layer_menu(void)
-{
- byte transparent_color = Main_backups->Pages->Transparent_color;
- byte transparent_background = Main_backups->Pages->Background_transparent;
- short clicked_button;
- byte color;
- byte click;
-
- Open_window(122,100,"Layers");
-
- Window_display_frame_in( 6, 21,110, 52);
- Print_in_window(14,18,"Transparency",MC_Dark,MC_Light);
-
- Print_in_window(11,38,"Color",MC_Black,MC_Light);
- Window_set_normal_button(54, 36, 56,13,"" , 0,1,KEY_NONE); // 1
- Draw_transparent_color(transparent_color);
-
- Print_in_window(11,57,"Background",MC_Black,MC_Light);
- Window_set_normal_button(95, 54, 15,13,"" , 0,1,KEY_NONE); // 2
- Draw_transparent_background(transparent_background);
-
- Window_set_normal_button( 7, 78, 51,14,"OK" , 0,1,SDLK_RETURN); // 3
- Window_set_normal_button(63, 78, 51,14,"Cancel", 0,1,KEY_ESC); // 4
-
- Update_window_area(0,0,Window_width, Window_height);
- Display_cursor();
-
- do
- {
-
- clicked_button=Window_clicked_button();
- if (Is_shortcut(Key,0x100+BUTTON_HELP))
- Window_help(BUTTON_LAYER_MENU, NULL);
- switch(clicked_button)
- {
- case 1: // color
- Get_color_behind_window(&color,&click);
- if (click && transparent_color!=color)
- {
- transparent_color=color;
- Hide_cursor();
- Draw_transparent_color(transparent_color);
- Display_cursor();
- Wait_end_of_click();
- }
- break;
-
- case 2: // background
- transparent_background = !transparent_background;
- Hide_cursor();
- Draw_transparent_background(transparent_background);
- Display_cursor();
- break;
- }
- }
- while (clicked_button<3);
-
- // On exit
- Hide_cursor();
- Close_window();
- if (clicked_button==3)
- {
- // Accept changes
- if (Main_backups->Pages->Transparent_color != transparent_color ||
- Main_backups->Pages->Background_transparent != transparent_background)
- {
- Backup_layers(LAYER_NONE);
- Main_backups->Pages->Transparent_color = transparent_color;
- Main_backups->Pages->Background_transparent = transparent_background;
- Redraw_layered_image();
- Display_all_screen();
- End_of_modification();
- }
- }
- Unselect_button(BUTTON_LAYER_MENU);
- Unselect_button(BUTTON_LAYER_MENU2);
- Display_cursor();
-}
-
-void Button_Layer_set_transparent(void)
-{
- Hide_cursor();
-
- if (Main_backups->Pages->Transparent_color != Back_color)
- {
- Backup_layers(LAYER_ALL);
- Main_backups->Pages->Transparent_color = Back_color;
-
- Redraw_layered_image();
- Display_all_screen();
- End_of_modification();
- }
-
- Unselect_button(BUTTON_LAYER_COLOR);
- Display_cursor();
-}
-
-void Button_Layer_get_transparent(void)
-{
- Hide_cursor();
-
- if (Main_backups->Pages->Transparent_color != Back_color)
- {
- Set_back_color(Main_backups->Pages->Transparent_color);
- }
-
- Unselect_button(BUTTON_LAYER_COLOR);
- Display_cursor();
-}
-
-void Button_Layer_merge(void)
-{
- Hide_cursor();
-
- if (Main_current_layer>0)
- {
- // Backup layer below the current
- Backup_layers(Main_current_layer-1);
-
- Merge_layer();
-
- Update_screen_targets();
- Redraw_layered_image();
- Display_all_screen();
- Display_layerbar();
- End_of_modification();
- }
-
- Unselect_button(BUTTON_LAYER_MERGE);
- Display_cursor();
-}
-
-void Button_Layer_up(void)
-{
- Hide_cursor();
-
- if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
- {
- T_Image tmp;
- dword layer_flags;
-
- // Backup with unchanged layers
- Backup_layers(LAYER_NONE);
-
- // swap
- tmp = Main_backups->Pages->Image[Main_current_layer];
- Main_backups->Pages->Image[Main_current_layer] = Main_backups->Pages->Image[Main_current_layer+1];
- Main_backups->Pages->Image[Main_current_layer+1] = tmp;
-
- // Swap visibility indicators
- layer_flags = (Main_layers_visible >> Main_current_layer) & 3;
- // Only needed if they are different.
- if (layer_flags == 1 || layer_flags == 2)
- {
- // One is on, the other is off. Negating them will
- // perform the swap.
- Main_layers_visible ^= (3 << Main_current_layer);
- }
- Main_current_layer++;
-
- Update_screen_targets();
- Redraw_layered_image();
- Display_all_screen();
- Display_layerbar();
- End_of_modification();
- }
-
- Unselect_button(BUTTON_LAYER_UP);
- Unselect_button(BUTTON_ANIM_UP_FRAME);
- Display_cursor();
-}
-
-void Button_Layer_down(void)
-{
- Hide_cursor();
-
- if (Main_current_layer > 0)
- {
- T_Image tmp;
- dword layer_flags;
-
- // Backup with unchanged layers
- Backup_layers(LAYER_NONE);
-
- // swap
- tmp = Main_backups->Pages->Image[Main_current_layer];
- Main_backups->Pages->Image[Main_current_layer] = Main_backups->Pages->Image[Main_current_layer-1];
- Main_backups->Pages->Image[Main_current_layer-1] = tmp;
-
- // Swap visibility indicators
- layer_flags = (Main_layers_visible >> (Main_current_layer-1)) & 3;
- // Only needed if they are different.
- if (layer_flags == 1 || layer_flags == 2)
- {
- // Only needed if they are different.
- // One is on, the other is off. Negating them will
- // perform the swap.
- Main_layers_visible ^= (3 << (Main_current_layer-1));
- }
- Main_current_layer--;
- Update_screen_targets();
- Redraw_layered_image();
- Display_layerbar();
- Display_all_screen();
- End_of_modification();
- }
-
- Unselect_button(BUTTON_LAYER_DOWN);
- Unselect_button(BUTTON_ANIM_DOWN_FRAME);
- Display_cursor();
-}
-
-int Interpret_delay(int delay)
-{
- // Firefox behavior
- if (delay>30)
- return delay;
- if (delay==0)
- return 100;
- return 30;
-}
-void Button_Anim_time(void)
-{
- short clicked_button;
- int mode=0;
- int frame;
- char buffer[6+1];
- T_Special_button * input_duration_button;
- int duration=Main_backups->Pages->Image[Main_current_layer].Duration;
-
- Open_window(166,110,"Animation speed");
-
- Print_in_window(88,20,"ms",MC_Black,MC_Light);
- input_duration_button = Window_set_input_button(33,18,6); // 1
-
- Num2str(duration,buffer,6);
- Print_in_window_limited(input_duration_button->Pos_X+2,input_duration_button->Pos_Y+2,buffer,input_duration_button->Width/8,MC_Black,MC_Light);
-
- Print_in_window(24,37,"Set this frame",MC_Black,MC_Light);
- Window_set_normal_button(7, 34, 13,13,"X" , 0,1,KEY_NONE); // 2
-
- Print_in_window(24,55,"Set all frames",MC_Black,MC_Light);
- Window_set_normal_button(7, 52, 13,13,"" , 0,1,KEY_NONE); // 3
-
- Print_in_window(24,73,"Add to all frames",MC_Black,MC_Light);
- Window_set_normal_button(7, 70, 13,13,"" , 0,1,KEY_NONE); // 4
-
- Window_set_normal_button( 7, 92, 51,14,"OK" , 0,1,SDLK_RETURN); // 5
- Window_set_normal_button(63, 92, 51,14,"Cancel", 0,1,KEY_ESC); // 6
-
- Update_window_area(0,0,Window_width, Window_height);
- Display_cursor();
-
- do
- {
-
- clicked_button=Window_clicked_button();
- if (Is_shortcut(Key,0x100+BUTTON_HELP))
- Window_help(BUTTON_ANIM_TIME, NULL);
- switch(clicked_button)
- {
- case 1: // duration
- // safety
- if (duration <= -10000)
- sprintf(buffer,"-99999");
- else if (duration >= 1000000)
- sprintf(buffer,"999999");
- else
- sprintf(buffer,"%d", duration);
- Hide_cursor();
- if (Readline(input_duration_button->Pos_X+2,
- input_duration_button->Pos_Y+2,
- buffer,
- 6,
- INPUT_TYPE_DECIMAL))
- {
- duration=atoi(buffer);
- }
- Print_in_window_limited(input_duration_button->Pos_X+2,input_duration_button->Pos_Y+2,buffer,input_duration_button->Width/8,MC_Black,MC_Light);
- Display_cursor();
- break;
- case 2: // Radio: set 1
- case 3: // Radio: set all
- case 4: // Radio: add
- mode=clicked_button-2;
- Hide_cursor();
- Print_in_window(10,37,mode==0?"X":" ",MC_Black,MC_Light);
- Print_in_window(10,55,mode==1?"X":" ",MC_Black,MC_Light);
- Print_in_window(10,73,mode==2?"X":" ",MC_Black,MC_Light);
- Display_cursor();
- break;
- }
- }
- while (clicked_button<5);
-
- // On exit
- Hide_cursor();
- Close_window();
- if (clicked_button==5)
- {
- // Accept changes
- Backup_layers(LAYER_NONE);
- switch(mode)
- {
- case 0:
- if (duration<0)
- duration=0;
- else if (duration>655350)
- duration=655350;
- Main_backups->Pages->Image[Main_current_layer].Duration = duration;
- break;
- case 1:
- if (duration<0)
- duration=0;
- else if (duration>655350)
- duration=655350;
- for (frame=0; framePages->Nb_layers; frame++)
- {
- Main_backups->Pages->Image[frame].Duration = duration;
- }
- break;
- case 2:
- for (frame=0; framePages->Nb_layers; frame++)
- {
- int cur_duration = Main_backups->Pages->Image[frame].Duration+duration;
- if (cur_duration<0)
- cur_duration=0;
- else if (cur_duration>655350)
- cur_duration=655350;
- Main_backups->Pages->Image[frame].Duration = cur_duration;
- }
- break;
- break;
- }
- End_of_modification();
- }
-
- Unselect_button(BUTTON_ANIM_TIME);
- Display_cursor();
-}
-
-void Button_Anim_first_frame(void)
-{
- if (Main_current_layer>0)
- Layer_activate(0,LEFT_SIDE);
-
- Hide_cursor();
- Unselect_button(BUTTON_ANIM_FIRST_FRAME);
- Display_cursor();
-}
-
-void Button_Anim_prev_frame(void)
-{
- if (Main_backups->Pages->Nb_layers>1)
- {
- if (Main_current_layer==0)
- Layer_activate(Main_backups->Pages->Nb_layers-1,LEFT_SIDE);
- else
- Layer_activate(Main_current_layer-1,LEFT_SIDE);
- }
- Hide_cursor();
- Unselect_button(BUTTON_ANIM_PREV_FRAME);
- Display_cursor();
-}
-
-void Button_Anim_next_frame(void)
-{
- if (Main_backups->Pages->Nb_layers>1)
- {
- if (Main_current_layer==Main_backups->Pages->Nb_layers-1)
- Layer_activate(0,LEFT_SIDE);
- else
- Layer_activate(Main_current_layer+1,LEFT_SIDE);
- }
-
- Hide_cursor();
- Unselect_button(BUTTON_ANIM_NEXT_FRAME);
- Display_cursor();
-}
-
-void Button_Anim_last_frame(void)
-{
- if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
- Layer_activate((Main_backups->Pages->Nb_layers-1),LEFT_SIDE);
-
- Hide_cursor();
- Unselect_button(BUTTON_ANIM_LAST_FRAME);
- Display_cursor();
-}
-
-void Button_Anim_continuous_next(void)
-{
- Uint32 time_start;
- int time_in_current_frame=0;
-
- time_start = SDL_GetTicks();
-
- do
- {
- int target_frame;
- Uint32 time_now;
-
- Get_input(20);
-
- time_now=SDL_GetTicks();
- time_in_current_frame += time_now-time_start;
- time_start=time_now;
- target_frame = Main_current_layer;
- while (time_in_current_frame > Main_backups->Pages->Image[target_frame].Duration)
- {
- time_in_current_frame -= Interpret_delay(Main_backups->Pages->Image[target_frame].Duration);
- target_frame = (target_frame+1) % Main_backups->Pages->Nb_layers;
- }
- if (target_frame != Main_current_layer)
- {
- Layer_activate(target_frame,LEFT_SIDE);
- }
-
- } while (Mouse_K);
-
- Hide_cursor();
- Unselect_button(BUTTON_ANIM_NEXT_FRAME);
- Display_cursor();
-}
-
-void Button_Anim_continuous_prev(void)
-{
- Uint32 time_start;
- int time_in_current_frame=0;
-
- time_start = SDL_GetTicks();
-
- do
- {
- int target_frame;
- Uint32 time_now;
-
- Get_input(20);
-
- time_now=SDL_GetTicks();
- time_in_current_frame += time_now-time_start;
- time_start=time_now;
- target_frame = Main_current_layer;
- while (time_in_current_frame > Main_backups->Pages->Image[target_frame].Duration)
- {
- time_in_current_frame -= Interpret_delay(Main_backups->Pages->Image[target_frame].Duration);
- target_frame = (target_frame+Main_backups->Pages->Nb_layers-1) % Main_backups->Pages->Nb_layers;
- }
- if (target_frame != Main_current_layer)
- {
- Layer_activate(target_frame,LEFT_SIDE);
- }
-
- } while (Mouse_K);
-
- Hide_cursor();
- Unselect_button(BUTTON_ANIM_PREV_FRAME);
- Display_cursor();
-}
+/* vim:expandtab:ts=2 sw=2:
+*/
+/* Grafx2 - The Ultimate 256-color bitmap paint program
+
+ Copyright 2009 Yves Rizoud
+ Copyright 2007 Adrien Destugues
+ Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
+
+ Grafx2 is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2
+ of the License.
+
+ Grafx2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grafx2; if not, see
+*/
+#include "const.h"
+#include "struct.h"
+#include "global.h"
+#include "windows.h"
+#include "engine.h"
+#include "pages.h"
+#include "sdlscreen.h"
+#include "input.h"
+#include "help.h"
+#include "misc.h"
+#include "readline.h"
+#include "graph.h"
+
+void Layer_activate(int layer, short side)
+{
+ word old_layers;
+
+ if (layer >= Main_backups->Pages->Nb_layers)
+ return;
+
+ // Keep a copy of which layers were visible
+ old_layers = Main_layers_visible;
+
+ if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
+ {
+ if (side == RIGHT_SIDE)
+ {
+ // Right-click on current layer
+ if (Main_current_layer == layer)
+ {
+ if (Main_layers_visible == (dword)(1<Pages);
+ //Update_FX_feedback(Config.FX_Feedback);
+ Update_pixel_renderer();
+ Display_all_screen();
+ Display_layerbar();
+ Display_cursor();
+}
+
+void Button_Layer_add(void)
+{
+ int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5};
+
+ Hide_cursor();
+
+ if (Main_backups->Pages->Nb_layers < max[Main_backups->Pages->Image_mode])
+ {
+ // Backup with unchanged layers
+ Backup_layers(LAYER_NONE);
+ if (!Add_layer(Main_backups,Main_current_layer+1))
+ {
+ Update_depth_buffer();
+ // I just noticed this might be unneeded, since the new layer
+ // is transparent, it shouldn't have any visible effect.
+ Display_all_screen();
+ Display_layerbar();
+ End_of_modification();
+ }
+ }
+
+ Unselect_button(BUTTON_LAYER_ADD);
+ Unselect_button(BUTTON_ANIM_ADD_FRAME);
+ Display_cursor();
+}
+
+
+void Button_Layer_duplicate(void)
+{
+ int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5};
+
+ Hide_cursor();
+
+ if (Main_backups->Pages->Nb_layers < max[Main_backups->Pages->Image_mode])
+ {
+ // Backup with unchanged layers
+ Backup_layers(LAYER_NONE);
+ if (!Add_layer(Main_backups,Main_current_layer+1))
+ {
+ // Make a copy of current image
+ memcpy(
+ Main_backups->Pages->Image[Main_current_layer].Pixels,
+ Main_backups->Pages->Image[Main_current_layer-1].Pixels,
+ Main_backups->Pages->Width*Main_backups->Pages->Height);
+
+ if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) {
+ Update_depth_buffer();
+ // I just noticed this might be unneeded, since the new layer
+ // is transparent, it shouldn't have any visible effect.
+ Display_all_screen();
+ }
+ Display_layerbar();
+ End_of_modification();
+ }
+ }
+
+ Unselect_button(BUTTON_LAYER_ADD);
+ Unselect_button(BUTTON_ANIM_ADD_FRAME);
+ Display_cursor();
+}
+
+void Button_Layer_remove(void)
+{
+ Hide_cursor();
+
+ if (Main_backups->Pages->Nb_layers > 1)
+ {
+ // Backup with unchanged layers
+ Backup_layers(LAYER_NONE);
+ if (!Delete_layer(Main_backups,Main_current_layer))
+ {
+ Update_screen_targets();
+ Redraw_layered_image();
+
+ Display_all_screen();
+ Display_layerbar();
+ End_of_modification();
+ }
+ }
+ Unselect_button(BUTTON_LAYER_REMOVE);
+ Unselect_button(BUTTON_ANIM_REMOVE_FRAME);
+ Display_cursor();
+}
+
+short Layer_under_mouse(void)
+{
+ short layer;
+ // Determine which button is clicked according to mouse position
+ layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width)
+ / Layer_button_width;
+
+ // Safety required because the mouse cursor can have slided outside button.
+ if (layer < 0)
+ layer=0;
+ else if (layer > Main_backups->Pages->Nb_layers-1)
+ layer=Main_backups->Pages->Nb_layers-1;
+
+ return layer;
+}
+
+void Button_Layer_select(void)
+{
+ short layer = Layer_under_mouse();
+ Layer_activate(layer, LEFT_SIDE);
+ Mouse_K=0;
+}
+
+void Button_Layer_toggle(void)
+{
+ int layer;
+ // Determine which button is clicked according to mouse position
+ layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width)
+ / Layer_button_width;
+
+ // Safety required because the mouse cursor can have slided outside button.
+ if (layer < 0)
+ layer=0;
+ else if (layer > Main_backups->Pages->Nb_layers-1)
+ layer=Main_backups->Pages->Nb_layers-1;
+
+ Layer_activate(layer, RIGHT_SIDE);
+ Mouse_K=0;
+}
+
+static void Draw_transparent_color(byte color)
+{
+ char buf[4];
+ Num2str(color, buf, 3);
+ Print_in_window(63,39,buf,MC_Black,MC_Light);
+ Window_rectangle(90,39,13,7,color);
+}
+
+static void Draw_transparent_background(byte background)
+{
+ Print_in_window(99,57,background?"X":" ",MC_Black,MC_Light);
+}
+
+
+void Button_Layer_menu(void)
+{
+ byte transparent_color = Main_backups->Pages->Transparent_color;
+ byte transparent_background = Main_backups->Pages->Background_transparent;
+ short clicked_button;
+ byte color;
+ byte click;
+
+ Open_window(122,100,"Layers");
+
+ Window_display_frame_in( 6, 21,110, 52);
+ Print_in_window(14,18,"Transparency",MC_Dark,MC_Light);
+
+ Print_in_window(11,38,"Color",MC_Black,MC_Light);
+ Window_set_normal_button(54, 36, 56,13,"" , 0,1,KEY_NONE); // 1
+ Draw_transparent_color(transparent_color);
+
+ Print_in_window(11,57,"Background",MC_Black,MC_Light);
+ Window_set_normal_button(95, 54, 15,13,"" , 0,1,KEY_NONE); // 2
+ Draw_transparent_background(transparent_background);
+
+ Window_set_normal_button( 7, 78, 51,14,"OK" , 0,1,SDLK_RETURN); // 3
+ Window_set_normal_button(63, 78, 51,14,"Cancel", 0,1,KEY_ESC); // 4
+
+ Update_window_area(0,0,Window_width, Window_height);
+ Display_cursor();
+
+ do
+ {
+
+ clicked_button=Window_clicked_button();
+ if (Is_shortcut(Key,0x100+BUTTON_HELP))
+ Window_help(BUTTON_LAYER_MENU, NULL);
+ switch(clicked_button)
+ {
+ case 1: // color
+ Get_color_behind_window(&color,&click);
+ if (click && transparent_color!=color)
+ {
+ transparent_color=color;
+ Hide_cursor();
+ Draw_transparent_color(transparent_color);
+ Display_cursor();
+ Wait_end_of_click();
+ }
+ break;
+
+ case 2: // background
+ transparent_background = !transparent_background;
+ Hide_cursor();
+ Draw_transparent_background(transparent_background);
+ Display_cursor();
+ break;
+ }
+ }
+ while (clicked_button<3);
+
+ // On exit
+ Hide_cursor();
+ Close_window();
+ if (clicked_button==3)
+ {
+ // Accept changes
+ if (Main_backups->Pages->Transparent_color != transparent_color ||
+ Main_backups->Pages->Background_transparent != transparent_background)
+ {
+ Backup_layers(LAYER_NONE);
+ Main_backups->Pages->Transparent_color = transparent_color;
+ Main_backups->Pages->Background_transparent = transparent_background;
+ Redraw_layered_image();
+ Display_all_screen();
+ End_of_modification();
+ }
+ }
+ Unselect_button(BUTTON_LAYER_MENU);
+ Unselect_button(BUTTON_LAYER_MENU2);
+ Display_cursor();
+}
+
+void Button_Layer_set_transparent(void)
+{
+ Hide_cursor();
+
+ if (Main_backups->Pages->Transparent_color != Back_color)
+ {
+ Backup_layers(LAYER_ALL);
+ Main_backups->Pages->Transparent_color = Back_color;
+
+ Redraw_layered_image();
+ Display_all_screen();
+ End_of_modification();
+ }
+
+ Unselect_button(BUTTON_LAYER_COLOR);
+ Display_cursor();
+}
+
+void Button_Layer_get_transparent(void)
+{
+ Hide_cursor();
+
+ if (Main_backups->Pages->Transparent_color != Back_color)
+ {
+ Set_back_color(Main_backups->Pages->Transparent_color);
+ }
+
+ Unselect_button(BUTTON_LAYER_COLOR);
+ Display_cursor();
+}
+
+void Button_Layer_merge(void)
+{
+ Hide_cursor();
+
+ if (Main_current_layer>0)
+ {
+ // Backup layer below the current
+ Backup_layers(Main_current_layer-1);
+
+ Merge_layer();
+
+ Update_screen_targets();
+ Redraw_layered_image();
+ Display_all_screen();
+ Display_layerbar();
+ End_of_modification();
+ }
+
+ Unselect_button(BUTTON_LAYER_MERGE);
+ Display_cursor();
+}
+
+void Button_Layer_up(void)
+{
+ Hide_cursor();
+
+ if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
+ {
+ T_Image tmp;
+ dword layer_flags;
+
+ // Backup with unchanged layers
+ Backup_layers(LAYER_NONE);
+
+ // swap
+ tmp = Main_backups->Pages->Image[Main_current_layer];
+ Main_backups->Pages->Image[Main_current_layer] = Main_backups->Pages->Image[Main_current_layer+1];
+ Main_backups->Pages->Image[Main_current_layer+1] = tmp;
+
+ // Swap visibility indicators
+ layer_flags = (Main_layers_visible >> Main_current_layer) & 3;
+ // Only needed if they are different.
+ if (layer_flags == 1 || layer_flags == 2)
+ {
+ // One is on, the other is off. Negating them will
+ // perform the swap.
+ Main_layers_visible ^= (3 << Main_current_layer);
+ }
+ Main_current_layer++;
+
+ Update_screen_targets();
+ Redraw_layered_image();
+ Display_all_screen();
+ Display_layerbar();
+ End_of_modification();
+ }
+
+ Unselect_button(BUTTON_LAYER_UP);
+ Unselect_button(BUTTON_ANIM_UP_FRAME);
+ Display_cursor();
+}
+
+void Button_Layer_down(void)
+{
+ Hide_cursor();
+
+ if (Main_current_layer > 0)
+ {
+ T_Image tmp;
+ dword layer_flags;
+
+ // Backup with unchanged layers
+ Backup_layers(LAYER_NONE);
+
+ // swap
+ tmp = Main_backups->Pages->Image[Main_current_layer];
+ Main_backups->Pages->Image[Main_current_layer] = Main_backups->Pages->Image[Main_current_layer-1];
+ Main_backups->Pages->Image[Main_current_layer-1] = tmp;
+
+ // Swap visibility indicators
+ layer_flags = (Main_layers_visible >> (Main_current_layer-1)) & 3;
+ // Only needed if they are different.
+ if (layer_flags == 1 || layer_flags == 2)
+ {
+ // Only needed if they are different.
+ // One is on, the other is off. Negating them will
+ // perform the swap.
+ Main_layers_visible ^= (3 << (Main_current_layer-1));
+ }
+ Main_current_layer--;
+ Update_screen_targets();
+ Redraw_layered_image();
+ Display_layerbar();
+ Display_all_screen();
+ End_of_modification();
+ }
+
+ Unselect_button(BUTTON_LAYER_DOWN);
+ Unselect_button(BUTTON_ANIM_DOWN_FRAME);
+ Display_cursor();
+}
+
+int Interpret_delay(int delay)
+{
+ // Firefox behavior
+ if (delay>30)
+ return delay;
+ if (delay==0)
+ return 100;
+ return 30;
+}
+void Button_Anim_time(void)
+{
+ short clicked_button;
+ int mode=0;
+ int frame;
+ char buffer[6+1];
+ T_Special_button * input_duration_button;
+ int duration=Main_backups->Pages->Image[Main_current_layer].Duration;
+
+ Open_window(166,110,"Animation speed");
+
+ Print_in_window(88,20,"ms",MC_Black,MC_Light);
+ input_duration_button = Window_set_input_button(33,18,6); // 1
+
+ Num2str(duration,buffer,6);
+ Print_in_window_limited(input_duration_button->Pos_X+2,input_duration_button->Pos_Y+2,buffer,input_duration_button->Width/8,MC_Black,MC_Light);
+
+ Print_in_window(24,37,"Set this frame",MC_Black,MC_Light);
+ Window_set_normal_button(7, 34, 13,13,"X" , 0,1,KEY_NONE); // 2
+
+ Print_in_window(24,55,"Set all frames",MC_Black,MC_Light);
+ Window_set_normal_button(7, 52, 13,13,"" , 0,1,KEY_NONE); // 3
+
+ Print_in_window(24,73,"Add to all frames",MC_Black,MC_Light);
+ Window_set_normal_button(7, 70, 13,13,"" , 0,1,KEY_NONE); // 4
+
+ Window_set_normal_button( 7, 92, 51,14,"OK" , 0,1,SDLK_RETURN); // 5
+ Window_set_normal_button(63, 92, 51,14,"Cancel", 0,1,KEY_ESC); // 6
+
+ Update_window_area(0,0,Window_width, Window_height);
+ Display_cursor();
+
+ do
+ {
+
+ clicked_button=Window_clicked_button();
+ if (Is_shortcut(Key,0x100+BUTTON_HELP))
+ Window_help(BUTTON_ANIM_TIME, NULL);
+ switch(clicked_button)
+ {
+ case 1: // duration
+ // safety
+ if (duration <= -10000)
+ sprintf(buffer,"-99999");
+ else if (duration >= 1000000)
+ sprintf(buffer,"999999");
+ else
+ sprintf(buffer,"%d", duration);
+ Hide_cursor();
+ if (Readline(input_duration_button->Pos_X+2,
+ input_duration_button->Pos_Y+2,
+ buffer,
+ 6,
+ INPUT_TYPE_DECIMAL))
+ {
+ duration=atoi(buffer);
+ }
+ Print_in_window_limited(input_duration_button->Pos_X+2,input_duration_button->Pos_Y+2,buffer,input_duration_button->Width/8,MC_Black,MC_Light);
+ Display_cursor();
+ break;
+ case 2: // Radio: set 1
+ case 3: // Radio: set all
+ case 4: // Radio: add
+ mode=clicked_button-2;
+ Hide_cursor();
+ Print_in_window(10,37,mode==0?"X":" ",MC_Black,MC_Light);
+ Print_in_window(10,55,mode==1?"X":" ",MC_Black,MC_Light);
+ Print_in_window(10,73,mode==2?"X":" ",MC_Black,MC_Light);
+ Display_cursor();
+ break;
+ }
+ }
+ while (clicked_button<5);
+
+ // On exit
+ Hide_cursor();
+ Close_window();
+ if (clicked_button==5)
+ {
+ // Accept changes
+ Backup_layers(LAYER_NONE);
+ switch(mode)
+ {
+ case 0:
+ if (duration<0)
+ duration=0;
+ else if (duration>655350)
+ duration=655350;
+ Main_backups->Pages->Image[Main_current_layer].Duration = duration;
+ break;
+ case 1:
+ if (duration<0)
+ duration=0;
+ else if (duration>655350)
+ duration=655350;
+ for (frame=0; framePages->Nb_layers; frame++)
+ {
+ Main_backups->Pages->Image[frame].Duration = duration;
+ }
+ break;
+ case 2:
+ for (frame=0; framePages->Nb_layers; frame++)
+ {
+ int cur_duration = Main_backups->Pages->Image[frame].Duration+duration;
+ if (cur_duration<0)
+ cur_duration=0;
+ else if (cur_duration>655350)
+ cur_duration=655350;
+ Main_backups->Pages->Image[frame].Duration = cur_duration;
+ }
+ break;
+ break;
+ }
+ End_of_modification();
+ }
+
+ Unselect_button(BUTTON_ANIM_TIME);
+ Display_cursor();
+}
+
+void Button_Anim_first_frame(void)
+{
+ if (Main_current_layer>0)
+ Layer_activate(0,LEFT_SIDE);
+
+ Hide_cursor();
+ Unselect_button(BUTTON_ANIM_FIRST_FRAME);
+ Display_cursor();
+}
+
+void Button_Anim_prev_frame(void)
+{
+ if (Main_backups->Pages->Nb_layers>1)
+ {
+ if (Main_current_layer==0)
+ Layer_activate(Main_backups->Pages->Nb_layers-1,LEFT_SIDE);
+ else
+ Layer_activate(Main_current_layer-1,LEFT_SIDE);
+ }
+ Hide_cursor();
+ Unselect_button(BUTTON_ANIM_PREV_FRAME);
+ Display_cursor();
+}
+
+void Button_Anim_next_frame(void)
+{
+ if (Main_backups->Pages->Nb_layers>1)
+ {
+ if (Main_current_layer==Main_backups->Pages->Nb_layers-1)
+ Layer_activate(0,LEFT_SIDE);
+ else
+ Layer_activate(Main_current_layer+1,LEFT_SIDE);
+ }
+
+ Hide_cursor();
+ Unselect_button(BUTTON_ANIM_NEXT_FRAME);
+ Display_cursor();
+}
+
+void Button_Anim_last_frame(void)
+{
+ if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
+ Layer_activate((Main_backups->Pages->Nb_layers-1),LEFT_SIDE);
+
+ Hide_cursor();
+ Unselect_button(BUTTON_ANIM_LAST_FRAME);
+ Display_cursor();
+}
+
+void Button_Anim_continuous_next(void)
+{
+ Uint32 time_start;
+ int time_in_current_frame=0;
+
+ time_start = SDL_GetTicks();
+
+ do
+ {
+ int target_frame;
+ Uint32 time_now;
+
+ Get_input(20);
+
+ time_now=SDL_GetTicks();
+ time_in_current_frame += time_now-time_start;
+ time_start=time_now;
+ target_frame = Main_current_layer;
+ while (time_in_current_frame > Main_backups->Pages->Image[target_frame].Duration)
+ {
+ time_in_current_frame -= Interpret_delay(Main_backups->Pages->Image[target_frame].Duration);
+ target_frame = (target_frame+1) % Main_backups->Pages->Nb_layers;
+ }
+ if (target_frame != Main_current_layer)
+ {
+ Layer_activate(target_frame,LEFT_SIDE);
+ }
+
+ } while (Mouse_K);
+
+ Hide_cursor();
+ Unselect_button(BUTTON_ANIM_NEXT_FRAME);
+ Display_cursor();
+}
+
+void Button_Anim_continuous_prev(void)
+{
+ Uint32 time_start;
+ int time_in_current_frame=0;
+
+ time_start = SDL_GetTicks();
+
+ do
+ {
+ int target_frame;
+ Uint32 time_now;
+
+ Get_input(20);
+
+ time_now=SDL_GetTicks();
+ time_in_current_frame += time_now-time_start;
+ time_start=time_now;
+ target_frame = Main_current_layer;
+ while (time_in_current_frame > Main_backups->Pages->Image[target_frame].Duration)
+ {
+ time_in_current_frame -= Interpret_delay(Main_backups->Pages->Image[target_frame].Duration);
+ target_frame = (target_frame+Main_backups->Pages->Nb_layers-1) % Main_backups->Pages->Nb_layers;
+ }
+ if (target_frame != Main_current_layer)
+ {
+ Layer_activate(target_frame,LEFT_SIDE);
+ }
+
+ } while (Mouse_K);
+
+ Hide_cursor();
+ Unselect_button(BUTTON_ANIM_PREV_FRAME);
+ Display_cursor();
+}
diff --git a/src/layers.h b/src/layers.h
index 61c8f8ac..f85db3f2 100644
--- a/src/layers.h
+++ b/src/layers.h
@@ -1,44 +1,44 @@
-/* vim:expandtab:ts=2 sw=2:
-*/
-/* Grafx2 - The Ultimate 256-color bitmap paint program
-
- Copyright 2009 Yves Rizoud
- Copyright 2007 Adrien Destugues
- Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
-
- Grafx2 is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; version 2
- of the License.
-
- Grafx2 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Grafx2; if not, see
-*/
-
-void Button_Layer_add(void);
-void Button_Layer_duplicate(void);
-void Button_Layer_remove(void);
-void Button_Layer_menu(void);
-void Button_Layer_set_transparent(void);
-void Button_Layer_get_transparent(void);
-void Button_Layer_merge(void);
-void Button_Layer_up(void);
-void Button_Layer_down(void);
-void Button_Layer_select(void);
-void Button_Layer_toggle(void);
-void Layer_activate(int layer, short side);
-void Button_Anim_time(void);
-void Button_Anim_first_frame(void);
-void Button_Anim_prev_frame(void);
-void Button_Anim_next_frame(void);
-void Button_Anim_last_frame(void);
-void Button_Anim_play(void);
-void Button_Anim_continuous_prev(void);
-void Button_Anim_continuous_next(void);
-
-short Layer_under_mouse(void);
+/* vim:expandtab:ts=2 sw=2:
+*/
+/* Grafx2 - The Ultimate 256-color bitmap paint program
+
+ Copyright 2009 Yves Rizoud
+ Copyright 2007 Adrien Destugues
+ Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
+
+ Grafx2 is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2
+ of the License.
+
+ Grafx2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grafx2; if not, see
+*/
+
+void Button_Layer_add(void);
+void Button_Layer_duplicate(void);
+void Button_Layer_remove(void);
+void Button_Layer_menu(void);
+void Button_Layer_set_transparent(void);
+void Button_Layer_get_transparent(void);
+void Button_Layer_merge(void);
+void Button_Layer_up(void);
+void Button_Layer_down(void);
+void Button_Layer_select(void);
+void Button_Layer_toggle(void);
+void Layer_activate(int layer, short side);
+void Button_Anim_time(void);
+void Button_Anim_first_frame(void);
+void Button_Anim_prev_frame(void);
+void Button_Anim_next_frame(void);
+void Button_Anim_last_frame(void);
+void Button_Anim_play(void);
+void Button_Anim_continuous_prev(void);
+void Button_Anim_continuous_next(void);
+
+short Layer_under_mouse(void);
diff --git a/src/oldies.c b/src/oldies.c
index 10942555..b8344b8c 100644
--- a/src/oldies.c
+++ b/src/oldies.c
@@ -1,414 +1,414 @@
-/* vim:expandtab:ts=2 sw=2:
-*/
-/* Grafx2 - The Ultimate 256-color bitmap paint program
-
- Copyright 2008 Yves Rizoud
- Copyright 2008 Franck Charlet
- Copyright 2007 Adrien Destugues
- Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
-
- Grafx2 is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; version 2
- of the License.
-
- Grafx2 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Grafx2; if not, see
-*/
-#include
-#include
-#include
-#include
-#include
-#include "struct.h"
-#include "global.h"
-#include "errors.h"
-#include "misc.h"
-#include "palette.h"
-#include "pages.h"
-#include "windows.h"
-#include "layers.h"
-
-void Pixel_in_layer(word x,word y, byte layer, byte color)
-{
- *((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer].Pixels)=color;
-}
-
-byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
-{
- word used_colors[200][40];
- word block_used_colors[25][40];
- word line_used_colors[200];
- byte used_colors_count[200][40];
- dword usage[16];
- word x,y,row,col;
- int i;
- byte line_color[200];
- byte block_color[25][40];
- word best_color_count;
- byte best_color;
- const byte no_color=16;
-
- // Prerequisites
- if (Main_backups->Pages->Nb_layers < 3)
- return 1;
- if (Main_image_width != 160 || Main_image_height != 200)
- return 2;
-
- memset(used_colors,0,200*40*sizeof(word));
- memset(block_used_colors,0,25*40*sizeof(word));
- memset(line_used_colors,0,200*sizeof(word));
- memset(used_colors_count,0,200*40*sizeof(byte));
-
- // Initialize these as "unset"
- memset(line_color,no_color,200*sizeof(byte));
- memset(block_color,no_color,25*40*sizeof(byte));
-
- // Examine all 4-pixel blocks to fill used_colors[][]
- for (row=0;row<200;row++)
- {
- for (col=0;col<40;col++)
- {
- for (x=0;x<4;x++)
- {
- byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
- used_colors[row][col] |= 1<Pages->Image[0].Pixels);
- if (c<16)
- {
- line_color[row]=c;
- for (col=0;col<40;col++)
- {
- // Remove that color from the sets
- used_colors[row][col] &= ~(1<Pages->Image[1].Pixels);
- if (c<16)
- {
- block_color[row/8][col]=c;
- // Remove that color from the sets
- for (y=0; y<8;y++)
- used_colors[row+y][col] &= ~(1<best_color_count)
- {
- best_color_count=usage[i];
- best_color=i;
- }
- }
- line_color[row]=best_color;
-
- // Remove that color from the sets
- for (col=0;col<40;col++)
- {
- if (used_colors[row][col] & (1<2)
- {
- filter &= used_colors[row+y][col];
-
- for (i=0; i<16; i++)
- {
- if (used_colors[row+y][col] & (1<best_color_count)
- {
- best_color_count=usage[i];
- best_color=i;
- }
- }
- }
- }
- block_color[row/8][col]=best_color;
-
- // Remove that color from the sets
- for (y=0;y<8;y++)
- {
- if (used_colors[row+y][col] & (1<15)
- c1=16;
- if (c2>15)
- c2=16;
-
- // Output Screen RAMs
- if (screen_ram!=NULL)
- screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4);
-
- // Output bitmap
- if (bitmap!=NULL)
- {
- for(x=0; x<4; x++)
- {
- byte bits;
- byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
-
- if (c==line_color[row*8+y])
- // BG color
- bits=0;
- else if (c==block_color[row][col])
- // block color
- bits=3;
- else if (c==c1)
- // Color 1
- bits=2;
- else if (c==c2)
- // Color 2
- bits=1;
- else // problem
- bits=0;
- // clear target bits
- //bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2));
- // set them
- bitmap[row*320+col*8+y] |= bits<<((3-x)*2);
- }
- }
- }
- }
- }
- //memset(background,3,200);
- //memset(color_ram,5,8000);
- //memset(screen_ram,(9<<4) | 7,8192);
-
- return 0;
-
-}
-
-byte C64_FLI_enforcer(void)
-{
- byte background[200];
- byte bitmap[8000];
- byte screen_ram[8192];
- byte color_ram[1000];
-
- int row, col, x, y;
- byte c[4];
-
- // Checks
- if (Main_image_width != 160)
- return 1;
- if (Main_image_height != 200)
- return 1;
- if (Main_backups->Pages->Nb_layers != 4)
- return 2;
-
- Backup_layers(3);
-
- memset(bitmap,0,8000);
- memset(background,0,200);
- memset(color_ram,0,1000);
- memset(screen_ram,0,8192);
- C64_FLI(bitmap, screen_ram, color_ram, background);
-
- for(row=0; row<25; row++)
- {
- for(col=0; col<40; col++)
- {
- c[3]=color_ram[row*40+col]&15;
- for(y=0; y<8; y++)
- {
- int pixel=bitmap[row*320+col*8+y];
-
- c[0]=background[row*8+y]&15;
- c[1]=screen_ram[y*1024+row*40+col]>>4;
- c[2]=screen_ram[y*1024+row*40+col]&15;
- for(x=0; x<4; x++)
- {
- int color=c[(pixel&3)];
- pixel>>=2;
- Pixel_in_layer(col*4+(3-x),row*8+y,3,color);
- }
- }
- }
- }
- End_of_modification();
-
- // Visible feedback:
-
- // If the "check" layer was visible, manually update the whole thing
- if (Main_layers_visible & (1<<3))
- {
- Hide_cursor();
- Redraw_layered_image();
- Display_all_screen();
- Display_layerbar();
- Display_cursor();
- }
- else
- // Otherwise, simply toggle the layer visiblity
- Layer_activate(3,RIGHT_SIDE);
-
-
- return 0;
-}
+/* vim:expandtab:ts=2 sw=2:
+*/
+/* Grafx2 - The Ultimate 256-color bitmap paint program
+
+ Copyright 2008 Yves Rizoud
+ Copyright 2008 Franck Charlet
+ Copyright 2007 Adrien Destugues
+ Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
+
+ Grafx2 is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2
+ of the License.
+
+ Grafx2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grafx2; if not, see
+*/
+#include
+#include
+#include
+#include
+#include
+#include "struct.h"
+#include "global.h"
+#include "errors.h"
+#include "misc.h"
+#include "palette.h"
+#include "pages.h"
+#include "windows.h"
+#include "layers.h"
+
+void Pixel_in_layer(word x,word y, byte layer, byte color)
+{
+ *((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer].Pixels)=color;
+}
+
+byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
+{
+ word used_colors[200][40];
+ word block_used_colors[25][40];
+ word line_used_colors[200];
+ byte used_colors_count[200][40];
+ dword usage[16];
+ word x,y,row,col;
+ int i;
+ byte line_color[200];
+ byte block_color[25][40];
+ word best_color_count;
+ byte best_color;
+ const byte no_color=16;
+
+ // Prerequisites
+ if (Main_backups->Pages->Nb_layers < 3)
+ return 1;
+ if (Main_image_width != 160 || Main_image_height != 200)
+ return 2;
+
+ memset(used_colors,0,200*40*sizeof(word));
+ memset(block_used_colors,0,25*40*sizeof(word));
+ memset(line_used_colors,0,200*sizeof(word));
+ memset(used_colors_count,0,200*40*sizeof(byte));
+
+ // Initialize these as "unset"
+ memset(line_color,no_color,200*sizeof(byte));
+ memset(block_color,no_color,25*40*sizeof(byte));
+
+ // Examine all 4-pixel blocks to fill used_colors[][]
+ for (row=0;row<200;row++)
+ {
+ for (col=0;col<40;col++)
+ {
+ for (x=0;x<4;x++)
+ {
+ byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
+ used_colors[row][col] |= 1<Pages->Image[0].Pixels);
+ if (c<16)
+ {
+ line_color[row]=c;
+ for (col=0;col<40;col++)
+ {
+ // Remove that color from the sets
+ used_colors[row][col] &= ~(1<Pages->Image[1].Pixels);
+ if (c<16)
+ {
+ block_color[row/8][col]=c;
+ // Remove that color from the sets
+ for (y=0; y<8;y++)
+ used_colors[row+y][col] &= ~(1<best_color_count)
+ {
+ best_color_count=usage[i];
+ best_color=i;
+ }
+ }
+ line_color[row]=best_color;
+
+ // Remove that color from the sets
+ for (col=0;col<40;col++)
+ {
+ if (used_colors[row][col] & (1<2)
+ {
+ filter &= used_colors[row+y][col];
+
+ for (i=0; i<16; i++)
+ {
+ if (used_colors[row+y][col] & (1<best_color_count)
+ {
+ best_color_count=usage[i];
+ best_color=i;
+ }
+ }
+ }
+ }
+ block_color[row/8][col]=best_color;
+
+ // Remove that color from the sets
+ for (y=0;y<8;y++)
+ {
+ if (used_colors[row+y][col] & (1<15)
+ c1=16;
+ if (c2>15)
+ c2=16;
+
+ // Output Screen RAMs
+ if (screen_ram!=NULL)
+ screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4);
+
+ // Output bitmap
+ if (bitmap!=NULL)
+ {
+ for(x=0; x<4; x++)
+ {
+ byte bits;
+ byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
+
+ if (c==line_color[row*8+y])
+ // BG color
+ bits=0;
+ else if (c==block_color[row][col])
+ // block color
+ bits=3;
+ else if (c==c1)
+ // Color 1
+ bits=2;
+ else if (c==c2)
+ // Color 2
+ bits=1;
+ else // problem
+ bits=0;
+ // clear target bits
+ //bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2));
+ // set them
+ bitmap[row*320+col*8+y] |= bits<<((3-x)*2);
+ }
+ }
+ }
+ }
+ }
+ //memset(background,3,200);
+ //memset(color_ram,5,8000);
+ //memset(screen_ram,(9<<4) | 7,8192);
+
+ return 0;
+
+}
+
+byte C64_FLI_enforcer(void)
+{
+ byte background[200];
+ byte bitmap[8000];
+ byte screen_ram[8192];
+ byte color_ram[1000];
+
+ int row, col, x, y;
+ byte c[4];
+
+ // Checks
+ if (Main_image_width != 160)
+ return 1;
+ if (Main_image_height != 200)
+ return 1;
+ if (Main_backups->Pages->Nb_layers != 4)
+ return 2;
+
+ Backup_layers(3);
+
+ memset(bitmap,0,8000);
+ memset(background,0,200);
+ memset(color_ram,0,1000);
+ memset(screen_ram,0,8192);
+ C64_FLI(bitmap, screen_ram, color_ram, background);
+
+ for(row=0; row<25; row++)
+ {
+ for(col=0; col<40; col++)
+ {
+ c[3]=color_ram[row*40+col]&15;
+ for(y=0; y<8; y++)
+ {
+ int pixel=bitmap[row*320+col*8+y];
+
+ c[0]=background[row*8+y]&15;
+ c[1]=screen_ram[y*1024+row*40+col]>>4;
+ c[2]=screen_ram[y*1024+row*40+col]&15;
+ for(x=0; x<4; x++)
+ {
+ int color=c[(pixel&3)];
+ pixel>>=2;
+ Pixel_in_layer(col*4+(3-x),row*8+y,3,color);
+ }
+ }
+ }
+ }
+ End_of_modification();
+
+ // Visible feedback:
+
+ // If the "check" layer was visible, manually update the whole thing
+ if (Main_layers_visible & (1<<3))
+ {
+ Hide_cursor();
+ Redraw_layered_image();
+ Display_all_screen();
+ Display_layerbar();
+ Display_cursor();
+ }
+ else
+ // Otherwise, simply toggle the layer visiblity
+ Layer_activate(3,RIGHT_SIDE);
+
+
+ return 0;
+}
diff --git a/src/oldies.h b/src/oldies.h
index 8476775f..6f781883 100644
--- a/src/oldies.h
+++ b/src/oldies.h
@@ -1,24 +1,24 @@
-/* vim:expandtab:ts=2 sw=2:
-*/
-/* Grafx2 - The Ultimate 256-color bitmap paint program
-
- Copyright 2008 Adrien Destugues
-
- Grafx2 is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; version 2
- of the License.
-
- Grafx2 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Grafx2; if not, see
-*/
-
-byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background);
-
-byte C64_FLI_enforcer(void);
-
+/* vim:expandtab:ts=2 sw=2:
+*/
+/* Grafx2 - The Ultimate 256-color bitmap paint program
+
+ Copyright 2008 Adrien Destugues
+
+ Grafx2 is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2
+ of the License.
+
+ Grafx2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grafx2; if not, see
+*/
+
+byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background);
+
+byte C64_FLI_enforcer(void);
+
diff --git a/src/tiles.c b/src/tiles.c
index fb0fbd5b..6da3ed07 100644
--- a/src/tiles.c
+++ b/src/tiles.c
@@ -1,426 +1,426 @@
-/* vim:expandtab:ts=2 sw=2:
-*/
-/* Grafx2 - The Ultimate 256-color bitmap paint program
-
- Copyright 2011 Yves Rizoud
- Copyright 2010-2011 Adrien Destugues
-
- Grafx2 is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; version 2
- of the License.
-
- Grafx2 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Grafx2; if not, see
-*/
-
-#include "struct.h"
-#include "global.h"
-#include "graph.h"
-#include "sdlscreen.h"
-#include "engine.h"
-#include "windows.h"
-#include "input.h"
-#include "misc.h"
-#include "tiles.h"
-
-// These helpers are only needed internally at the moment
-#define TILE_FOR_COORDS(x,y) (((y)-Snap_offset_Y)/Snap_height*Main_tilemap_width+((x)-Snap_offset_X)/Snap_width)
-#define TILE_AT(x,y) (y)*Main_tilemap_width+(x)
-#define TILE_X(t) (((t)%Main_tilemap_width)*Snap_width+Snap_offset_X)
-#define TILE_Y(t) (((t)/Main_tilemap_width)*Snap_height+Snap_offset_Y)
-
-enum TILE_FLIPPED
-{
- TILE_FLIPPED_NONE = 0,
- TILE_FLIPPED_X = 1,
- TILE_FLIPPED_Y = 2,
- TILE_FLIPPED_XY = 3, // needs be TILE_FLIPPED_X|TILE_FLIPPED_Y
-};
-
-// globals
-
-/// Tilemap for the main screen
-T_Tile * Main_tilemap;
-/// Number of tiles (horizontally) for the main page's tilemap
-short Main_tilemap_width;
-/// Number of tiles (vertically) for the main page's tilemap
-short Main_tilemap_height;
-
-/// Tilemap for the spare
-T_Tile * Spare_tilemap;
-/// Number of tiles (horizontally) for the spare page's tilemap
-short Spare_tilemap_width;
-/// Number of tiles (vertically) for the spare page's tilemap
-short Spare_tilemap_height;
-
-
-///
-/// Draw a pixel while Tilemap mode is active : This will paint on all
-/// similar tiles of the layer, visible on the screen or not.
-void Tilemap_draw(word x, word y, byte color)
-{
- int tile, first_tile;
- int rel_x, rel_y;
-
- if (x < Snap_offset_X
- || y < Snap_offset_Y
- || x >= Snap_offset_X + Main_tilemap_width*Snap_width
- || y >= Snap_offset_Y + Main_tilemap_height*Snap_height)
- return;
-
- tile = first_tile = TILE_FOR_COORDS(x,y);
-
- rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
- rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
- do
- {
- int xx,yy;
- switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped)
- {
- case 0: // no
- default:
- xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
- yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
- break;
- case 1: // horizontal
- xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
- yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
- break;
- case 2: // vertical
- xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
- yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
- break;
- case 3: // both
- xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
- yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
- break;
- }
- if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right)
- Pixel_in_current_screen_with_preview(xx,yy,color);
- else
- Pixel_in_current_screen(xx,yy,color);
-
- tile = Main_tilemap[tile].Next;
- } while (tile != first_tile);
-
- Update_rect(0,0,0,0);
-}
-
-///
-int Tile_is_same(int t1, int t2)
-{
- byte *bmp1,*bmp2;
- int y;
-
- bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
- bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2));
-
- for (y=0; y < Snap_height; y++)
- {
- if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width))
- return 0;
- }
- return 1;
-}
-
-///
-int Tile_is_same_flipped_x(int t1, int t2)
-{
- byte *bmp1,*bmp2;
- int y, x;
-
- bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
- bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2)+Snap_width-1);
-
- for (y=0; y < Snap_height; y++)
- {
- for (x=0; x < Snap_width; x++)
- if (*(bmp1+y*Main_image_width+x) != *(bmp2+y*Main_image_width-x))
- return 0;
- }
- return 1;
-}
-
-///
-int Tile_is_same_flipped_y(int t1, int t2)
-{
- byte *bmp1,*bmp2;
- int y;
-
- bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
- bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2));
-
- for (y=0; y < Snap_height; y++)
- {
- if (memcmp(bmp1+y*Main_image_width, bmp2-y*Main_image_width, Snap_width))
- return 0;
- }
- return 1;
-}
-
-
-///
-int Tile_is_same_flipped_xy(int t1, int t2)
-{
- byte *bmp1,*bmp2;
- int y, x;
-
- bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
- bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2)+Snap_width-1);
-
- for (y=0; y < Snap_height; y++)
- {
- for (x=0; x < Snap_width; x++)
- if (*(bmp1+y*Main_image_width+x) != *(bmp2-y*Main_image_width-x))
- return 0;
- }
- return 1;
-}
-
-/// Create or update a tilemap based on current screen (layer)'s pixels.
-void Tilemap_update(void)
-{
- int width;
- int height;
- int tile;
- int count=1;
- T_Tile * tile_ptr;
-
- int wait_window=0;
- byte old_cursor=0;
-
- if (!Main_tilemap_mode)
- return;
-
- width=(Main_image_width-Snap_offset_X)/Snap_width;
- height=(Main_image_height-Snap_offset_Y)/Snap_height;
-
- if (width<1 || height<1 || width*height>1000000l
- || (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL)
- {
- // Cannot enable tilemap because either the image is too small
- // for the grid settings (and I don't want to implement partial tiles)
- // Or the number of tiles seems unreasonable (one million) : This can
- // happen if you set grid 1x1 for example.
-
- Disable_main_tilemap();
- return;
- }
-
- if (Main_tilemap)
- {
- // Recycle existing tilemap
- free(Main_tilemap);
- Main_tilemap=NULL;
- }
- Main_tilemap=tile_ptr;
-
- Main_tilemap_width=width;
- Main_tilemap_height=height;
-
- if (width*height > 1000 || Config.Tilemap_show_count)
- {
- wait_window=1;
- old_cursor=Cursor_shape;
- Open_window(180,36,"Creating tileset");
- Print_in_window(26, 20, "Please wait...",MC_Black,MC_Light);
- Cursor_shape=CURSOR_SHAPE_HOURGLASS;
- Update_window_area(0,0,Window_width, Window_height);
- Display_cursor();
- Get_input(0);
- }
-
- // Initialize array with all tiles unique by default
- for (tile=0; tile
+*/
+
+#include "struct.h"
+#include "global.h"
+#include "graph.h"
+#include "sdlscreen.h"
+#include "engine.h"
+#include "windows.h"
+#include "input.h"
+#include "misc.h"
+#include "tiles.h"
+
+// These helpers are only needed internally at the moment
+#define TILE_FOR_COORDS(x,y) (((y)-Snap_offset_Y)/Snap_height*Main_tilemap_width+((x)-Snap_offset_X)/Snap_width)
+#define TILE_AT(x,y) (y)*Main_tilemap_width+(x)
+#define TILE_X(t) (((t)%Main_tilemap_width)*Snap_width+Snap_offset_X)
+#define TILE_Y(t) (((t)/Main_tilemap_width)*Snap_height+Snap_offset_Y)
+
+enum TILE_FLIPPED
+{
+ TILE_FLIPPED_NONE = 0,
+ TILE_FLIPPED_X = 1,
+ TILE_FLIPPED_Y = 2,
+ TILE_FLIPPED_XY = 3, // needs be TILE_FLIPPED_X|TILE_FLIPPED_Y
+};
+
+// globals
+
+/// Tilemap for the main screen
+T_Tile * Main_tilemap;
+/// Number of tiles (horizontally) for the main page's tilemap
+short Main_tilemap_width;
+/// Number of tiles (vertically) for the main page's tilemap
+short Main_tilemap_height;
+
+/// Tilemap for the spare
+T_Tile * Spare_tilemap;
+/// Number of tiles (horizontally) for the spare page's tilemap
+short Spare_tilemap_width;
+/// Number of tiles (vertically) for the spare page's tilemap
+short Spare_tilemap_height;
+
+
+///
+/// Draw a pixel while Tilemap mode is active : This will paint on all
+/// similar tiles of the layer, visible on the screen or not.
+void Tilemap_draw(word x, word y, byte color)
+{
+ int tile, first_tile;
+ int rel_x, rel_y;
+
+ if (x < Snap_offset_X
+ || y < Snap_offset_Y
+ || x >= Snap_offset_X + Main_tilemap_width*Snap_width
+ || y >= Snap_offset_Y + Main_tilemap_height*Snap_height)
+ return;
+
+ tile = first_tile = TILE_FOR_COORDS(x,y);
+
+ rel_x = (x - Snap_offset_X + Snap_width) % Snap_width;
+ rel_y = (y - Snap_offset_Y + Snap_height) % Snap_height;
+ do
+ {
+ int xx,yy;
+ switch(Main_tilemap[tile].Flipped ^ Main_tilemap[first_tile].Flipped)
+ {
+ case 0: // no
+ default:
+ xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
+ yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
+ break;
+ case 1: // horizontal
+ xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
+ yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + rel_y;
+ break;
+ case 2: // vertical
+ xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + rel_x;
+ yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
+ break;
+ case 3: // both
+ xx = (tile % Main_tilemap_width)*Snap_width+Snap_offset_X + Snap_width-rel_x-1;
+ yy = (tile / Main_tilemap_width)*Snap_height+Snap_offset_Y + Snap_height - rel_y - 1;
+ break;
+ }
+ if (yy>=Limit_top&&yy<=Limit_bottom&&xx>=Limit_left&&xx<=Limit_right)
+ Pixel_in_current_screen_with_preview(xx,yy,color);
+ else
+ Pixel_in_current_screen(xx,yy,color);
+
+ tile = Main_tilemap[tile].Next;
+ } while (tile != first_tile);
+
+ Update_rect(0,0,0,0);
+}
+
+///
+int Tile_is_same(int t1, int t2)
+{
+ byte *bmp1,*bmp2;
+ int y;
+
+ bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
+ bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2));
+
+ for (y=0; y < Snap_height; y++)
+ {
+ if (memcmp(bmp1+y*Main_image_width, bmp2+y*Main_image_width, Snap_width))
+ return 0;
+ }
+ return 1;
+}
+
+///
+int Tile_is_same_flipped_x(int t1, int t2)
+{
+ byte *bmp1,*bmp2;
+ int y, x;
+
+ bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
+ bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2))*Main_image_width+(TILE_X(t2)+Snap_width-1);
+
+ for (y=0; y < Snap_height; y++)
+ {
+ for (x=0; x < Snap_width; x++)
+ if (*(bmp1+y*Main_image_width+x) != *(bmp2+y*Main_image_width-x))
+ return 0;
+ }
+ return 1;
+}
+
+///
+int Tile_is_same_flipped_y(int t1, int t2)
+{
+ byte *bmp1,*bmp2;
+ int y;
+
+ bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
+ bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2));
+
+ for (y=0; y < Snap_height; y++)
+ {
+ if (memcmp(bmp1+y*Main_image_width, bmp2-y*Main_image_width, Snap_width))
+ return 0;
+ }
+ return 1;
+}
+
+
+///
+int Tile_is_same_flipped_xy(int t1, int t2)
+{
+ byte *bmp1,*bmp2;
+ int y, x;
+
+ bmp1 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t1))*Main_image_width+(TILE_X(t1));
+ bmp2 = Main_backups->Pages->Image[Main_current_layer].Pixels+(TILE_Y(t2)+Snap_height-1)*Main_image_width+(TILE_X(t2)+Snap_width-1);
+
+ for (y=0; y < Snap_height; y++)
+ {
+ for (x=0; x < Snap_width; x++)
+ if (*(bmp1+y*Main_image_width+x) != *(bmp2-y*Main_image_width-x))
+ return 0;
+ }
+ return 1;
+}
+
+/// Create or update a tilemap based on current screen (layer)'s pixels.
+void Tilemap_update(void)
+{
+ int width;
+ int height;
+ int tile;
+ int count=1;
+ T_Tile * tile_ptr;
+
+ int wait_window=0;
+ byte old_cursor=0;
+
+ if (!Main_tilemap_mode)
+ return;
+
+ width=(Main_image_width-Snap_offset_X)/Snap_width;
+ height=(Main_image_height-Snap_offset_Y)/Snap_height;
+
+ if (width<1 || height<1 || width*height>1000000l
+ || (tile_ptr=(T_Tile *)malloc(width*height*sizeof(T_Tile))) == NULL)
+ {
+ // Cannot enable tilemap because either the image is too small
+ // for the grid settings (and I don't want to implement partial tiles)
+ // Or the number of tiles seems unreasonable (one million) : This can
+ // happen if you set grid 1x1 for example.
+
+ Disable_main_tilemap();
+ return;
+ }
+
+ if (Main_tilemap)
+ {
+ // Recycle existing tilemap
+ free(Main_tilemap);
+ Main_tilemap=NULL;
+ }
+ Main_tilemap=tile_ptr;
+
+ Main_tilemap_width=width;
+ Main_tilemap_height=height;
+
+ if (width*height > 1000 || Config.Tilemap_show_count)
+ {
+ wait_window=1;
+ old_cursor=Cursor_shape;
+ Open_window(180,36,"Creating tileset");
+ Print_in_window(26, 20, "Please wait...",MC_Black,MC_Light);
+ Cursor_shape=CURSOR_SHAPE_HOURGLASS;
+ Update_window_area(0,0,Window_width, Window_height);
+ Display_cursor();
+ Get_input(0);
+ }
+
+ // Initialize array with all tiles unique by default
+ for (tile=0; tile
-*/
-
-//////////////////////////////////////////////////////////////////////////////
-///@file tiles.h
-/// Functions for tilemap effect
-//////////////////////////////////////////////////////////////////////////////
-
-/// Create or update a tilemap based on current screen pixels.
-void Tilemap_update(void);
-
-///
-/// Draw a pixel while Tilemap mode is active : This will paint on all
-/// similar tiles of the layer, visible on the screen or not.
-void Tilemap_draw(word x, word y, byte color);
-
-///
-/// This exchanges the tilemap settings of the main and spare, it should
-/// be called when swapping pages.
-void Swap_tilemap(void);
-
-///
-/// Clears all tilemap data and settings for the main page.
-/// Safe to call again.
-void Disable_main_tilemap(void);
-
-///
-/// Clears all tilemap data and settings for the spare.
-/// Safe to call again.
-void Disable_spare_tilemap(void);
-
-
-/// Tilemap for the main screen
-extern T_Tile * Main_tilemap;
-/// Number of tiles (horizontally) for the main page's tilemap
-extern short Main_tilemap_width;
-/// Number of tiles (vertically) for the main page's tilemap
-extern short Main_tilemap_height;
-
-/// Tilemap for the spare
-extern T_Tile * Spare_tilemap;
-/// Number of tiles (horizontally) for the spare page's tilemap
-extern short Spare_tilemap_width;
-/// Number of tiles (vertically) for the spare page's tilemap
-extern short Spare_tilemap_height;
+/* vim:expandtab:ts=2 sw=2:
+*/
+/* Grafx2 - The Ultimate 256-color bitmap paint program
+
+ Copyright 2011 Yves Rizoud
+ Copyright 2011 Adrien Destugues
+
+ Grafx2 is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; version 2
+ of the License.
+
+ Grafx2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Grafx2; if not, see
+*/
+
+//////////////////////////////////////////////////////////////////////////////
+///@file tiles.h
+/// Functions for tilemap effect
+//////////////////////////////////////////////////////////////////////////////
+
+/// Create or update a tilemap based on current screen pixels.
+void Tilemap_update(void);
+
+///
+/// Draw a pixel while Tilemap mode is active : This will paint on all
+/// similar tiles of the layer, visible on the screen or not.
+void Tilemap_draw(word x, word y, byte color);
+
+///
+/// This exchanges the tilemap settings of the main and spare, it should
+/// be called when swapping pages.
+void Swap_tilemap(void);
+
+///
+/// Clears all tilemap data and settings for the main page.
+/// Safe to call again.
+void Disable_main_tilemap(void);
+
+///
+/// Clears all tilemap data and settings for the spare.
+/// Safe to call again.
+void Disable_spare_tilemap(void);
+
+
+/// Tilemap for the main screen
+extern T_Tile * Main_tilemap;
+/// Number of tiles (horizontally) for the main page's tilemap
+extern short Main_tilemap_width;
+/// Number of tiles (vertically) for the main page's tilemap
+extern short Main_tilemap_height;
+
+/// Tilemap for the spare
+extern T_Tile * Spare_tilemap;
+/// Number of tiles (horizontally) for the spare page's tilemap
+extern short Spare_tilemap_width;
+/// Number of tiles (vertically) for the spare page's tilemap
+extern short Spare_tilemap_height;