diff --git a/buttons.c b/buttons.c index 39390c97..a34c0a2d 100644 --- a/buttons.c +++ b/buttons.c @@ -1192,6 +1192,9 @@ void Button_Page(void) Exchange_main_and_spare(); // On fait le reste du travail "à la main": + SWAP_PBYTES(Main_visible_image.Image,Spare_visible_image.Image) + SWAP_WORDS (Main_visible_image.Width,Spare_visible_image.Width) + SWAP_WORDS (Main_visible_image.Height,Spare_visible_image.Height) SWAP_SHORTS(Main_offset_X,Spare_offset_X) SWAP_SHORTS(Main_offset_Y,Spare_offset_Y) SWAP_SHORTS(Old_main_offset_X,Old_spare_offset_X) @@ -1223,8 +1226,13 @@ void Button_Page(void) SWAP_BYTES (Main_current_layer,Spare_current_layer) SWAP_DWORDS(Main_layers_visible,Spare_layers_visible) + //Redraw_layered_image(); + // replaced by + Update_buffers(Main_image_width, Main_image_height); + Update_depth_buffer(); Update_screen_targets(); - Redraw_layered_image(); + End_of_modification(); + // -- // A la fin, on affiche l'écran for (factor_index=0; ZOOM_FACTOR[factor_index]!=Main_magnifier_factor; factor_index++); diff --git a/graph.c b/graph.c index c4134049..85f065f0 100644 --- a/graph.c +++ b/graph.c @@ -2882,7 +2882,7 @@ byte Read_pixel_from_current_screen (word x,word y) if (color != Main_backups->Pages->Transparent_color) // transparent color return color; - depth = *(Visible_image_depth_buffer.Image+x+y*Main_image_width); + depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); return *(Main_backups->Pages->Image[depth] + x+y*Main_image_width); #else return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer]); @@ -2892,7 +2892,7 @@ byte Read_pixel_from_current_screen (word x,word y) void Pixel_in_current_screen (word x,word y,byte color,int with_preview) { #ifndef NOLAYERS - byte depth = *(Visible_image_depth_buffer.Image+x+y*Main_image_width); + byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color; if ( depth <= Main_current_layer) { diff --git a/loadsave.h b/loadsave.h index 55dd3444..79f96234 100644 --- a/loadsave.h +++ b/loadsave.h @@ -107,8 +107,6 @@ void Pixel_load_in_24b_preview(short x_pos,short y_pos,byte r,byte g,byte b); // -extern enum PIXEL_RATIO Ratio_of_loaded_image; - void Set_file_error(int value); void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio); diff --git a/main.c b/main.c index e50f6447..8c6f0717 100644 --- a/main.c +++ b/main.c @@ -699,18 +699,6 @@ int Init_program(int argc,char * argv[]) Spare_image_width=Screen_width/Pixel_width; Spare_image_height=Screen_height/Pixel_height; - #ifndef NOLAYERS - Visible_image[0].Width = 0; - Visible_image[0].Height = 0; - Visible_image[0].Image = NULL; - Visible_image[1].Width = 0; - Visible_image[1].Height = 0; - Visible_image[1].Image = NULL; - Visible_image_depth_buffer.Width = 0; - Visible_image_depth_buffer.Height = 0; - Visible_image_depth_buffer.Image = NULL; - #endif - // Allocation de mémoire pour les différents écrans virtuels (et brosse) if (Init_all_backup_lists(Screen_width,Screen_height)==0) Error(ERROR_MEMORY); diff --git a/misc.c b/misc.c index 9647542f..4227bc37 100644 --- a/misc.c +++ b/misc.c @@ -37,6 +37,7 @@ #include "palette.h" #include "input.h" #include "graph.h" +#include "pages.h" ///Count used palette indexes in the whole picture ///Return the total number of different colors @@ -287,10 +288,18 @@ void Copy_part_of_image_to_another(byte * source,word source_x,word source_y,wor byte Read_pixel_from_spare_screen(word x,word y) { - return 0; - /* Temporarily disabled. Need to implement a third Visible_image buffer - return *(Spare_screen+y*Spare_image_width+x); - */ +// return *(Spare_screen+y*Spare_image_width+x); + + // Clipping is required as this can be called with coordinates from main image + // (can be a bigger or smaller image) + if (x>=Spare_image_width || y>=Spare_image_height) + return 0; // TODO: we could return the spare's transparent color, if it has one. +#ifndef NOLAYERS + return *(Spare_visible_image.Image + y*Spare_image_width + x); +#else + return *(Spare_backups->Pages->Image[Spare_current_layer] + y*Spare_image_width + x); +#endif + } void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height) diff --git a/misc.h b/misc.h index b10fc218..31be15a9 100644 --- a/misc.h +++ b/misc.h @@ -30,6 +30,7 @@ #define SWAP_DWORDS(a,b) { dword c=a; a=b; b=c;} #define SWAP_SHORTS(a,b) { short c=a; a=b; b=c;} #define SWAP_FLOATS(a,b) { float c=a; a=b; b=c;} +#define SWAP_PBYTES(a,b) { byte * c=a; a=b; b=c;} void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width); void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width); diff --git a/pages.c b/pages.c index c8988c1c..e22d7232 100644 --- a/pages.c +++ b/pages.c @@ -37,11 +37,12 @@ /// Array of two images, that contains the "flattened" version of the visible layers. #ifndef NOLAYERS -T_Image Visible_image[2]; -T_Image Visible_image_depth_buffer; +T_Bitmap Main_visible_image; +T_Bitmap Main_visible_image_backup; +T_Bitmap Main_visible_image_depth_buffer; +T_Bitmap Spare_visible_image; #endif - /// /// GESTION DES PAGES /// @@ -182,13 +183,13 @@ void Redraw_layered_image(void) { if ((1<Pages->Image[layer], Main_image_width*Main_image_height); // Initialize the depth buffer - memset(Visible_image_depth_buffer.Image, + memset(Main_visible_image_depth_buffer.Image, layer, Main_image_width*Main_image_height); @@ -208,9 +209,9 @@ void Redraw_layered_image(void) byte color = *(Main_backups->Pages->Image[layer]+i); if (color != Main_backups->Pages->Transparent_color) // transparent color { - *(Visible_image[0].Image+i) = color; + *(Main_visible_image.Image+i) = color; if (layer != Main_current_layer) - *(Visible_image_depth_buffer.Image+i) = layer; + *(Main_visible_image_depth_buffer.Image+i) = layer; } } } @@ -235,7 +236,7 @@ void Update_depth_buffer(void) if ((1<Pages->Image[layer]+i); if (color != Main_backups->Pages->Transparent_color) // transparent color { - *(Visible_image_depth_buffer.Image+i) = layer; + *(Main_visible_image_depth_buffer.Image+i) = layer; } } } @@ -274,17 +275,17 @@ void Redraw_current_layer(void) int i; for (i=0; iPages->Image[Main_current_layer]+i); if (color != Main_backups->Pages->Transparent_color) // transparent color { - *(Visible_image[0].Image+i) = color; + *(Main_visible_image.Image+i) = color; } else { - *(Visible_image[0].Image+i) = *(Main_backups->Pages->Image[depth]+i); + *(Main_visible_image.Image+i) = *(Main_backups->Pages->Image[depth]+i); } } } @@ -565,31 +566,11 @@ void Free_page_of_a_list(T_List_of_pages * list) } } -/// Resize one of the special bitmap buffers, if necessary. -int Update_buffer(T_Image * image, int width, int height) -{ - // At least one dimension is different - if (image->Width != width || image->Height != height) - { - // Actual size difference - if (image->Width * image->Height != width * height) - { - free(image->Image); - image->Image = (byte *)malloc(width * height); - if (image->Image == NULL) - return 0; - } - image->Width = width; - image->Height = height; - } - return 1; -} - void Update_screen_targets(void) { #ifndef NOLAYERS - Main_screen=Visible_image[0].Image; - Screen_backup=Visible_image[1].Image; + Main_screen=Main_visible_image.Image; + Screen_backup=Main_visible_image_backup.Image; #else Main_screen=Main_backups->Pages->Image[Main_current_layer]; Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer]; @@ -600,16 +581,63 @@ void Update_screen_targets(void) int Update_buffers(int width, int height) { #ifndef NOLAYERS - if (! Update_buffer(&Visible_image_depth_buffer, width, height)) - return 0; - if (! Update_buffer(&Visible_image[0], width, height)) - return 0; - if (! Update_buffer(&Visible_image[1], width, height)) - return 0; + // At least one dimension is different + if (Main_visible_image.Width*Main_visible_image.Height != width*height) + { + // Current image + free(Main_visible_image.Image); + Main_visible_image.Image = (byte *)malloc(width * height); + if (Main_visible_image.Image == NULL) + return 0; + } + Main_visible_image.Width = width; + Main_visible_image.Height = height; + + if (Main_visible_image_backup.Width*Main_visible_image_backup.Height != width*height) + { + // Previous image + free(Main_visible_image_backup.Image); + Main_visible_image_backup.Image = (byte *)malloc(width * height); + if (Main_visible_image_backup.Image == NULL) + return 0; + } + Main_visible_image_backup.Width = width; + Main_visible_image_backup.Height = height; + + if (Main_visible_image_depth_buffer.Width*Main_visible_image_depth_buffer.Height != width*height) + { + // Depth buffer + free(Main_visible_image_depth_buffer.Image); + Main_visible_image_depth_buffer.Image = (byte *)malloc(width * height); + if (Main_visible_image_depth_buffer.Image == NULL) + return 0; + } + Main_visible_image_depth_buffer.Width = width; + Main_visible_image_depth_buffer.Height = height; + #endif Update_screen_targets(); return 1; } +/// Update all the special image buffers of the spare page, if necessary. +int Update_spare_buffers(int width, int height) +{ +#ifndef NOLAYERS + // At least one dimension is different + if (Spare_visible_image.Width*Spare_visible_image.Height != width*height) + { + // Current image + free(Spare_visible_image.Image); + Spare_visible_image.Image = (byte *)malloc(width * height); + if (Spare_visible_image.Image == NULL) + return 0; + } + Spare_visible_image.Width = width; + Spare_visible_image.Height = height; + +#endif + return 1; +} /// /// GESTION DES BACKUPS @@ -639,25 +667,28 @@ int Init_all_backup_lists(int width,int height) memset(Main_backups->Pages->Image[i], 0, width*height); } #ifndef NOLAYERS - Visible_image[0].Width = 0; - Visible_image[0].Height = 0; - Visible_image[0].Image = NULL; + Main_visible_image.Width = 0; + Main_visible_image.Height = 0; + Main_visible_image.Image = NULL; + Main_visible_image_backup.Image = NULL; + Main_visible_image_depth_buffer.Image = NULL; + Spare_visible_image.Width = 0; + Spare_visible_image.Height = 0; + Spare_visible_image.Image = NULL; - Visible_image[1].Width = 0; - Visible_image[1].Height = 0; - Visible_image[1].Image = NULL; - - Visible_image_depth_buffer.Width = 0; - Visible_image_depth_buffer.Height = 0; - Visible_image_depth_buffer.Image = NULL; #endif if (!Update_buffers(width, height)) return 0; + if (!Update_spare_buffers(width, height)) + return 0; + #ifndef NOLAYERS // For speed, instead of Redraw_layered_image() we'll directly set the buffers. - memset(Visible_image[0].Image, 0, width*height); - memset(Visible_image[1].Image, 0, width*height); - memset(Visible_image_depth_buffer.Image, 0, width*height); + memset(Main_visible_image.Image, 0, width*height); + memset(Main_visible_image_backup.Image, 0, width*height); + memset(Main_visible_image_depth_buffer.Image, 0, width*height); + memset(Spare_visible_image.Image, 0, width*height); + #endif Download_infos_page_main(Main_backups->Pages); Download_infos_backup(Main_backups); @@ -735,7 +766,7 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height) Update_buffers(width, height); Download_infos_page_main(Main_backups->Pages); - Download_infos_backup(Main_backups); + End_of_modification(); return_code=1; } @@ -864,8 +895,6 @@ void Undo(void) // On extrait ensuite les infos sur la nouvelle page courante Download_infos_page_main(Main_backups->Pages); - // Et celles du backup - Download_infos_backup(Main_backups); // Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même // palette que la page courante. Mais en temps normal, le backup // n'est pas utilisé à la suite d'un Undo. Donc ça ne devrait pas @@ -873,6 +902,7 @@ void Undo(void) Check_layers_limits(); Redraw_layered_image(); + End_of_modification(); } @@ -893,8 +923,6 @@ void Redo(void) // On extrait ensuite les infos sur la nouvelle page courante Download_infos_page_main(Main_backups->Pages); - // Et celles du backup - Download_infos_backup(Main_backups); // Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même // palette que la page courante. Mais en temps normal, le backup // n'est pas utilisé à la suite d'un Redo. Donc ça ne devrait pas @@ -902,6 +930,7 @@ void Redo(void) Check_layers_limits(); Redraw_layered_image(); + End_of_modification(); } @@ -912,8 +941,6 @@ void Free_current_page(void) // On extrait ensuite les infos sur la nouvelle page courante Download_infos_page_main(Main_backups->Pages); - // Et celles du backup - Download_infos_backup(Main_backups); // Note: le backup n'a pas obligatoirement les mêmes dimensions ni la même // palette que la page courante. Mais en temps normal, le backup // n'est pas utilisé à la suite d'une destruction de page. Donc ça ne @@ -922,6 +949,7 @@ void Free_current_page(void) Update_buffers(Main_backups->Pages->Width, Main_backups->Pages->Height); Check_layers_limits(); Redraw_layered_image(); + End_of_modification(); } void Exchange_main_and_spare(void) @@ -942,8 +970,6 @@ void Exchange_main_and_spare(void) // On extrait ensuite les infos sur les nouvelles pages courante, brouillon // et backup. - Update_buffers(Main_backups->Pages->Width, Main_backups->Pages->Height); - /* SECTION GROS CACA PROUT PROUT */ // Auparavant on ruse en mettant déjà à jour les dimensions de la // nouvelle page courante. Si on ne le fait pas, le "Download" va détecter @@ -954,7 +980,6 @@ void Exchange_main_and_spare(void) Main_image_height=Main_backups->Pages->Height; Download_infos_page_main(Main_backups->Pages); - Download_infos_backup(Main_backups); Download_infos_page_spare(Spare_backups->Pages); } @@ -964,8 +989,8 @@ void End_of_modification(void) //Update_buffers(Main_image_width, Main_image_height); #ifndef NOLAYERS - memcpy(Visible_image[1].Image, - Visible_image[0].Image, + memcpy(Main_visible_image_backup.Image, + Main_visible_image.Image, Main_image_width*Main_image_height); #else Update_screen_targets(); diff --git a/pages.h b/pages.h index 7ec8658f..34510f96 100644 --- a/pages.h +++ b/pages.h @@ -32,8 +32,15 @@ /////////////////////////// BACKUP /////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -extern T_Image Visible_image[2]; -extern T_Image Visible_image_depth_buffer; +/// The pixels of visible layers, flattened copy. +extern T_Bitmap Main_visible_image; +/// The pixels of visible layers, flattened copy, used for no-feedback effects. +extern T_Bitmap Main_visible_image_backup; +/// The index of visible pixels from ::Visible image. Points to the right layer. +extern T_Bitmap Main_visible_image_depth_buffer; + +/// The pixels of visible layers for the spare page, flattened copy. +extern T_Bitmap Spare_visible_image; /// /// INDIVIDUAL PAGES diff --git a/struct.h b/struct.h index f734f6ba..82ef940d 100644 --- a/struct.h +++ b/struct.h @@ -366,7 +366,7 @@ typedef struct int Width; ///< Image width in pixels. int Height; ///< Image height in pixels. byte * Image; ///< Pixel data for the image. -} T_Image; +} T_Bitmap; /// A single memorized brush from the Brush Container typedef struct