From e73eb2786ab85f4aa0051cf400fca9e9770a2006 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Fri, 2 Mar 2012 23:19:47 +0000 Subject: [PATCH] Animation now has correct visual display and input feedback. Loading GIF guesses it's an anim if it loops, layers otherwise : Some rare non-looping GIF anims (usaully broken) will be misunderstood as layered. Editing of anims and layers seems flawless and stable. Still requires an auto-switch to the best toolbar (anim/layers) when relevant, but you can already switch manually. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1910 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/buttons.c | 26 +-- src/const.h | 5 +- src/fileformats.c | 49 +++-- src/graph.c | 32 ++-- src/layers.c | 83 ++++---- src/misc.c | 14 +- src/operatio.c | 5 +- src/pages.c | 479 +++++++++++++++++++++++----------------------- 8 files changed, 358 insertions(+), 335 deletions(-) diff --git a/src/buttons.c b/src/buttons.c index f69b3d27..368876fa 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -548,11 +548,23 @@ void Button_Toggle_toolbar(void) case 0: // tools Set_bar_visibility(MENUBAR_TOOLS, !Menu_bars[MENUBAR_TOOLS].Visible); break; - case 1: // anim + case 1: // layers if (Menu_bars[MENUBAR_ANIMATION].Visible && !Menu_bars[MENUBAR_LAYERS].Visible) Set_bar_visibility(MENUBAR_ANIMATION, 0); Set_bar_visibility(MENUBAR_LAYERS, !Menu_bars[MENUBAR_LAYERS].Visible); + if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { + // Exceptionally, this doesn't require a backup because a single-layer + // image is the same as a single-frame animation. + Main_backups->Pages->Image_mode = IMAGE_MODE_LAYERED; + } + break; + case 2: // anim + if (Menu_bars[MENUBAR_LAYERS].Visible && !Menu_bars[MENUBAR_ANIMATION].Visible) + Set_bar_visibility(MENUBAR_LAYERS, 0); + Set_bar_visibility(MENUBAR_ANIMATION, !Menu_bars[MENUBAR_ANIMATION].Visible); + if (Main_backups->Pages->Image_mode == IMAGE_MODE_LAYERED) { // Exceptionally, this doesn't require a backup because a single-frame @@ -560,18 +572,6 @@ void Button_Toggle_toolbar(void) Main_backups->Pages->Image_mode = IMAGE_MODE_ANIMATION; } - break; - case 2: // layers - if (Menu_bars[MENUBAR_LAYERS].Visible && !Menu_bars[MENUBAR_ANIMATION].Visible) - Set_bar_visibility(MENUBAR_LAYERS, 0); - Set_bar_visibility(MENUBAR_ANIMATION, !Menu_bars[MENUBAR_ANIMATION].Visible); - - if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) - { - // Exceptionally, this doesn't require a backup because a single-layer - // image is the same as a single-frame animation. - Main_backups->Pages->Image_mode = IMAGE_MODE_LAYERED; - } break; } } diff --git a/src/const.h b/src/const.h index 77272d9c..11642084 100644 --- a/src/const.h +++ b/src/const.h @@ -70,11 +70,8 @@ /// Character to display in menus for an ellipsis. #define ELLIPSIS_CHARACTER '…' #define NB_LAYERS 1 ///< Initial number of layers for a new image -#ifdef NOLAYERS -#define MAX_NB_LAYERS 999 ///< Maximum number of layers that can be used in grafx2. Note that 32 is upper limit because of a few bit fields. -#else +#define MAX_NB_FRAMES 999 ///< Maximum number of frames that can be used in a grafx2 animation. #define MAX_NB_LAYERS 16 ///< Maximum number of layers that can be used in grafx2. Note that 32 is upper limit because of a few bit fields. -#endif #define BRUSH_CONTAINER_PREVIEW_WIDTH 16 ///< Size for preview of a brush in Brush container #define BRUSH_CONTAINER_PREVIEW_HEIGHT 16 ///< Size for preview of a brush in Brush container #define BRUSH_CONTAINER_COLUMNS 4 ///< Number of columns in the Brush container diff --git a/src/fileformats.c b/src/fileformats.c index a1b52e39..15f9fe42 100644 --- a/src/fileformats.c +++ b/src/fileformats.c @@ -60,7 +60,6 @@ #include "struct.h" #include "io.h" #include "windows.h" // Best_color() -#include "pages.h" // Add_layer() //////////////////////////////////// IMG //////////////////////////////////// @@ -2025,7 +2024,13 @@ void Load_GIF(T_IO_Context * context) else if (!memcmp(aeb,"NETSCAPE2.0",0x0B)) { // The well-known Netscape extension. - // Nothing to do, just skip sub-block + // Load as an animation + if (context->Type == CONTEXT_MAIN_IMAGE) + { + Main_backups->Pages->Image_mode = IMAGE_MODE_ANIMATION; + Update_screen_targets(); + } + // Skip sub-block do { if (! Read_byte(GIF_file,&size_to_read)) @@ -2139,8 +2144,7 @@ void Load_GIF(T_IO_Context * context) // Attempt to add a layer to current image current_layer++; Set_loading_layer(context, current_layer); -#ifdef NOLAYERS - if (context->Type == CONTEXT_MAIN_IMAGE) + if (context->Type == CONTEXT_MAIN_IMAGE && Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) { if (is_transparent) // Copy the content of previous layer, in case of loading a GIF @@ -2155,7 +2159,6 @@ void Load_GIF(T_IO_Context * context) LSDB.Backcol, Main_backups->Pages->Width*Main_backups->Pages->Height); } -#endif } else { @@ -2165,7 +2168,6 @@ void Load_GIF(T_IO_Context * context) LSDB.Backcol, Main_backups->Pages->Width*Main_backups->Pages->Height); } - // Duration was set in the previously loaded GCE Set_frame_duration(context, last_delay*10); number_LID++; @@ -2497,10 +2499,9 @@ void Save_GIF(T_IO_Context * context) // Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\xLL\xSS\xSS\x00",19); // LL : 01 to loop // SSSS : number of loops -#ifdef NOLAYERS - if (context->Nb_layers>1) - Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\x01\x00\x00\x00",19); -#endif + if (context->Type == CONTEXT_MAIN_IMAGE && Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + if (context->Nb_layers>1) + Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\x01\x00\x00\x00",19); // Ecriture du commentaire if (context->Comment[0]) @@ -2543,18 +2544,24 @@ void Save_GIF(T_IO_Context * context) GCE.Block_identifier = 0x21; GCE.Function = 0xF9; GCE.Block_size=4; -#ifdef NOLAYERS - GCE.Packed_fields=(2<<2)|(context->Background_transparent); - GCE.Delay_time=Get_frame_duration(context)/10; -#else - if (current_layer==0) - GCE.Packed_fields=(1<<2)|(context->Background_transparent); + + if (context->Type == CONTEXT_MAIN_IMAGE && Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { + // Animation frame + GCE.Packed_fields=(2<<2)|(context->Background_transparent); + GCE.Delay_time=Get_frame_duration(context)/10; + } else - GCE.Packed_fields=(1<<2)|(1); - GCE.Delay_time=5; // Duration 5/100s (minimum viable value for current web browsers) - if (current_layer == context->Nb_layers -1) - GCE.Delay_time=0xFFFF; // Infinity (10 minutes) -#endif + { + // Layered image + if (current_layer==0) + GCE.Packed_fields=(1<<2)|(context->Background_transparent); + else + GCE.Packed_fields=(1<<2)|(1); + GCE.Delay_time=5; // Duration 5/100s (minimum viable value for current web browsers) + if (current_layer == context->Nb_layers -1) + GCE.Delay_time=0xFFFF; // Infinity (10 minutes) + } GCE.Transparent_color=context->Transparent_color; GCE.Block_terminator=0x00; diff --git a/src/graph.c b/src/graph.c index 119cf8a2..36fee1ce 100644 --- a/src/graph.c +++ b/src/graph.c @@ -3005,40 +3005,40 @@ void Redraw_grid(short x, short y, unsigned short w, unsigned short h) byte Read_pixel_from_current_screen (word x,word y) { - #ifndef NOLAYERS + byte depth; byte color; + if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { + return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels); + } + if (Main_backups->Pages->Image_mode == IMAGE_MODE_MODE5) if (Main_current_layer==4) return *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width); - + color = *(Main_screen+y*Main_image_width+x); if (color != Main_backups->Pages->Transparent_color) // transparent color return color; depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); return *(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width); - #else - return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels); - #endif } /// Paint a a single pixel in image only : as-is. void Pixel_in_screen_direct(word x,word y,byte color) { - *((y)*Main_image_width+(x)+/*Main_backups->Pages->Image[Main_current_layer].Pixels*/Main_screen)=color; + *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels)=color; } /// Paint a a single pixel in image and on screen: as-is. void Pixel_in_screen_direct_with_preview(word x,word y,byte color) { - *((y)*Main_image_width+(x)+/*Main_backups->Pages->Image[Main_current_layer].Pixels*/Main_screen)=color; + *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels)=color; Pixel_preview(x,y,color); } -#ifndef NOLAYERS - /// Paint a a single pixel in image only : using layered display. void Pixel_in_screen_layered(word x,word y,byte color) { @@ -3140,7 +3140,6 @@ void Pixel_in_screen_overlay_with_preview(word x,word y,byte color) Pixel_preview(x,y,color); } } -#endif Func_pixel Pixel_in_current_screen=Pixel_in_screen_direct; Func_pixel Pixel_in_current_screen_with_preview=Pixel_in_screen_direct_with_preview; @@ -3162,7 +3161,13 @@ byte Read_pixel_from_current_layer(word x,word y) void Update_pixel_renderer(void) { - #ifndef NOLAYERS + if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { + // direct + Pixel_in_current_screen = Pixel_in_screen_direct; + Pixel_in_current_screen_with_preview = Pixel_in_screen_direct_with_preview; + } + else if (Main_backups->Pages->Image_mode == IMAGE_MODE_LAYERED) { // layered @@ -3188,9 +3193,4 @@ void Update_pixel_renderer(void) Pixel_in_current_screen = Pixel_in_screen_layered; Pixel_in_current_screen_with_preview = Pixel_in_screen_layered_with_preview; } - #else - // direct - Pixel_in_current_screen = Pixel_in_screen_direct; - Pixel_in_current_screen_with_preview = Pixel_in_screen_direct_with_preview; - #endif } diff --git a/src/layers.c b/src/layers.c index a97ab14d..6780f7ce 100644 --- a/src/layers.c +++ b/src/layers.c @@ -41,46 +41,48 @@ void Layer_activate(int layer, short side) // Keep a copy of which layers were visible old_layers = Main_layers_visible; - #ifndef NOLAYERS - - if (side == RIGHT_SIDE) + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) { - // Right-click on current layer - if (Main_current_layer == layer) + if (side == RIGHT_SIDE) { - if (Main_layers_visible == (dword)(1<Pages->Nb_layers < MAX_NB_LAYERS) + if (Main_backups->Pages->Nb_layers < max[Main_backups->Pages->Image_mode]) { // Backup with unchanged layers Backup_layers(0); if (!Add_layer(Main_backups,Main_current_layer+1)) { - #ifdef NOLAYERS - // Make a copy of current image, so the display is unchanged - 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); - #else - 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(); - #endif + if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { + // Make a copy of current image, so the display is unchanged + 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); + } + else + { + 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(); } diff --git a/src/misc.c b/src/misc.c index 64dbc2b2..c20d5eea 100644 --- a/src/misc.c +++ b/src/misc.c @@ -303,12 +303,14 @@ byte Read_pixel_from_spare_screen(word x,word y) // (can be a bigger or smaller image) if (x>=Spare_image_width || y>=Spare_image_height) return Spare_backups->Pages->Transparent_color; -#ifndef NOLAYERS - return *(Spare_visible_image.Image + y*Spare_image_width + x); -#else - return *(Spare_backups->Pages->Image[Spare_current_layer].Pixels + y*Spare_image_width + x); -#endif - + if (Spare_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION) + { + return *(Spare_backups->Pages->Image[Spare_current_layer].Pixels + y*Spare_image_width + x); + } + else + { + return *(Spare_visible_image.Image + y*Spare_image_width + x); + } } void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height) diff --git a/src/operatio.c b/src/operatio.c index f53dc207..e9f2bf51 100644 --- a/src/operatio.c +++ b/src/operatio.c @@ -2785,13 +2785,14 @@ void Scroll_12_0(void) else { Backup_layers(-1); // Main_layers_visible - #ifndef NOLAYERS + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) + { // Ensure the backup visible image is up-to-date // (after swapping some layers on/off, it gets outdated) memcpy(Main_visible_image_backup.Image, Main_visible_image.Image, Main_image_width*Main_image_height); - #endif + } } Update_screen_targets(); diff --git a/src/pages.c b/src/pages.c index e51f5881..0f235092 100644 --- a/src/pages.c +++ b/src/pages.c @@ -38,12 +38,10 @@ // -- Layers data /// Array of two images, that contains the "flattened" version of the visible layers. -#ifndef NOLAYERS 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 @@ -200,40 +198,92 @@ void Download_infos_page_main(T_Page * page) void Redraw_layered_image(void) { - #ifndef NOLAYERS - // Re-construct the image with the visible layers - byte layer=0; - // First layer - if (Main_backups->Pages->Image_mode == IMAGE_MODE_MODE5 && Main_layers_visible & (1<<4)) + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) { - // The raster result layer is visible: start there - // Copy it in Main_visible_image - int i; - for (i=0; i< Main_image_width*Main_image_height; i++) + // Re-construct the image with the visible layers + byte layer=0; + // First layer + if (Main_backups->Pages->Image_mode == IMAGE_MODE_MODE5 && Main_layers_visible & (1<<4)) { - layer = *(Main_backups->Pages->Image[4].Pixels+i); - Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer].Pixels+i); + // The raster result layer is visible: start there + // Copy it in Main_visible_image + int i; + for (i=0; i< Main_image_width*Main_image_height; i++) + { + layer = *(Main_backups->Pages->Image[4].Pixels+i); + Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer].Pixels+i); + } + + // Copy it to the depth buffer + memcpy(Main_visible_image_depth_buffer.Image, + Main_backups->Pages->Image[4].Pixels, + Main_image_width*Main_image_height); + + // Next + layer= (1<<4)+1; + } + else + { + for (layer=0; layerPages->Nb_layers; layer++) + { + if ((1<Pages->Image[layer].Pixels, + Main_image_width*Main_image_height); + + // Initialize the depth buffer + memset(Main_visible_image_depth_buffer.Image, + layer, + Main_image_width*Main_image_height); + + // skip all other layers + layer++; + break; + } + } + } + // subsequent layer(s) + for (; layerPages->Nb_layers; layer++) + { + if ((1<Pages->Image[layer].Pixels+i); + if (color != Main_backups->Pages->Transparent_color) // transparent color + { + *(Main_visible_image.Image+i) = color; + if (layer != Main_current_layer) + *(Main_visible_image_depth_buffer.Image+i) = layer; + } + } + } } - - // Copy it to the depth buffer - memcpy(Main_visible_image_depth_buffer.Image, - Main_backups->Pages->Image[4].Pixels, - Main_image_width*Main_image_height); - - // Next - layer= (1<<4)+1; } else { + Update_screen_targets(); + } + Update_FX_feedback(Config.FX_Feedback); +} + +void Update_depth_buffer(void) +{ + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) + { + // Re-construct the depth buffer with the visible layers. + // This function doesn't touch the visible buffer, it assumes + // that it was already up-to-date. (Ex. user only changed active layer) + + int layer; + // First layer for (layer=0; layerPages->Nb_layers; layer++) { if ((1<Pages->Image[layer].Pixels, - Main_image_width*Main_image_height); - // Initialize the depth buffer memset(Main_visible_image_depth_buffer.Image, layer, @@ -244,145 +294,99 @@ void Redraw_layered_image(void) break; } } - } - // subsequent layer(s) - for (; layerPages->Nb_layers; layer++) - { - if ((1<Pages->Nb_layers; layer++) { - int i; - for (i=0; iPages->Image[layer].Pixels+i); - if (color != Main_backups->Pages->Transparent_color) // transparent color + int i; + for (i=0; iPages->Image[layer].Pixels+i); + if (color != Main_backups->Pages->Transparent_color) // transparent color + { *(Main_visible_image_depth_buffer.Image+i) = layer; + } } } } } - #else - Update_screen_targets(); - #endif - Update_FX_feedback(Config.FX_Feedback); -} - -void Update_depth_buffer(void) -{ - #ifndef NOLAYERS - // Re-construct the depth buffer with the visible layers. - // This function doesn't touch the visible buffer, it assumes - // that it was already up-to-date. (Ex. user only changed active layer) - - int layer; - // First layer - for (layer=0; layerPages->Nb_layers; layer++) - { - if ((1<Pages->Nb_layers; layer++) - { - // skip the current layer, whenever we reach it - if (layer == Main_current_layer) - continue; - - if ((1<Pages->Image[layer].Pixels+i); - if (color != Main_backups->Pages->Transparent_color) // transparent color - { - *(Main_visible_image_depth_buffer.Image+i) = layer; - } - } - } - } - #endif Update_FX_feedback(Config.FX_Feedback); } void Redraw_spare_image(void) { - #ifndef NOLAYERS - // Re-construct the image with the visible layers - byte layer; - // First layer - for (layer=0; layerPages->Nb_layers; layer++) + if (Spare_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) { - if ((1<Pages->Nb_layers; layer++) { - // Copy it in Spare_visible_image - memcpy(Spare_visible_image.Image, - Spare_backups->Pages->Image[layer].Pixels, - Spare_image_width*Spare_image_height); - - // No depth buffer in the spare - //memset(Spare_visible_image_depth_buffer.Image, - // layer, - // Spare_image_width*Spare_image_height); - - // skip all other layers - layer++; - break; - } - } - // subsequent layer(s) - for (; layerPages->Nb_layers; layer++) - { - if ((1<Pages->Image[layer].Pixels+i); - if (color != Spare_backups->Pages->Transparent_color) // transparent color + // Copy it in Spare_visible_image + memcpy(Spare_visible_image.Image, + Spare_backups->Pages->Image[layer].Pixels, + Spare_image_width*Spare_image_height); + + // No depth buffer in the spare + //memset(Spare_visible_image_depth_buffer.Image, + // layer, + // Spare_image_width*Spare_image_height); + + // skip all other layers + layer++; + break; + } + } + // subsequent layer(s) + for (; layerPages->Nb_layers; layer++) + { + if ((1<Pages->Image[layer].Pixels+i); + if (color != Spare_backups->Pages->Transparent_color) // transparent color + { + *(Spare_visible_image.Image+i) = color; + //if (layer != Spare_current_layer) + // *(Spare_visible_image_depth_buffer.Image+i) = layer; + } } } } } - #endif } void Redraw_current_layer(void) { -#ifndef NOLAYERS - int i; - for (i=0; iPages->Image_mode != IMAGE_MODE_ANIMATION) { - byte depth = *(Main_visible_image_depth_buffer.Image+i); - if (depth<=Main_current_layer) + int i; + for (i=0; iPages->Image[Main_current_layer].Pixels+i); - if (color != Main_backups->Pages->Transparent_color) // transparent color + byte depth = *(Main_visible_image_depth_buffer.Image+i); + if (depth<=Main_current_layer) { - *(Main_visible_image.Image+i) = color; - } - else - { - *(Main_visible_image.Image+i) = *(Main_backups->Pages->Image[depth].Pixels+i); + byte color = *(Main_backups->Pages->Image[Main_current_layer].Pixels+i); + if (color != Main_backups->Pages->Transparent_color) // transparent color + { + *(Main_visible_image.Image+i) = color; + } + else + { + *(Main_visible_image.Image+i) = *(Main_backups->Pages->Image[depth].Pixels+i); + } } } } -#endif } void Upload_infos_page_main(T_Page * page) @@ -672,83 +676,79 @@ void Free_page_of_a_list(T_List_of_pages * list) void Update_screen_targets(void) { - #ifndef NOLAYERS + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) + { Main_screen=Main_visible_image.Image; Screen_backup=Main_visible_image_backup.Image; - #else + } + else + { Main_screen=Main_backups->Pages->Image[Main_current_layer].Pixels; Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer].Pixels; - #endif + } Update_pixel_renderer(); } /// Update all the special image buffers, if necessary. int Update_buffers(int width, int height) { -#ifdef NOLAYERS - // unused args - (void) width; - (void) height; -#else - // At least one dimension is different - if (Main_visible_image.Width*Main_visible_image.Height != width*height) + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) { - // 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; + // 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; -#endif + 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; + } 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) { -#ifdef NOLAYERS - // unused args - (void) width; - (void) height; -#else - // At least one dimension is different - if (Spare_visible_image.Width*Spare_visible_image.Height != width*height) + if (Spare_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) { - // Current image - free(Spare_visible_image.Image); - Spare_visible_image.Image = (byte *)malloc(width * height); - if (Spare_visible_image.Image == NULL) - return 0; + // 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; + } - Spare_visible_image.Width = width; - Spare_visible_image.Height = height; - -#endif return 1; } @@ -783,7 +783,6 @@ int Init_all_backup_lists(int width,int height) return 0; memset(Main_backups->Pages->Image[i].Pixels, 0, width*height); } -#ifndef NOLAYERS Main_visible_image.Width = 0; Main_visible_image.Height = 0; Main_visible_image.Image = NULL; @@ -793,20 +792,17 @@ int Init_all_backup_lists(int width,int height) Spare_visible_image.Height = 0; Spare_visible_image.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(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); Update_FX_feedback(Config.FX_Feedback); @@ -872,6 +868,7 @@ int Backup_new_image(int layers,int width,int height) } Update_buffers(width, height); + memset(Main_visible_image_depth_buffer.Image, 0, width*height); Download_infos_page_main(Main_backups->Pages); @@ -926,13 +923,21 @@ int Backup_with_new_dimensions(int width,int height) // Same code as in End_of_modification(), // Without saving a safety backup: - #ifndef NOLAYERS + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) + { memcpy(Main_visible_image_backup.Image, Main_visible_image.Image, Main_image_width*Main_image_height); - #else + } + else + { + // Clear the depth buffer anyway, because we may use it later + memset(Main_visible_image_depth_buffer.Image, 0, + Main_image_width*Main_image_height); + + Update_screen_targets(); - #endif + } Update_FX_feedback(Config.FX_Feedback); // -- @@ -989,31 +994,32 @@ int Backup_in_place(int width,int height) // The following is part of Update_buffers() // (without changing the backup buffer) - #ifndef NOLAYERS - // At least one dimension is different - if (Main_visible_image.Width*Main_visible_image.Height != width*height) + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) { - // 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_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; + // 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; -#endif + 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; + + } Update_screen_targets(); return 1; @@ -1278,19 +1284,21 @@ void End_of_modification(void) //Update_buffers(Main_image_width, Main_image_height); -#ifndef NOLAYERS - // Backup buffer can have "wrong" size if a Lua script - // performs a resize. - Update_buffers(Main_image_width, Main_image_height); - // - - memcpy(Main_visible_image_backup.Image, - Main_visible_image.Image, - Main_image_width*Main_image_height); -#else - Update_screen_targets(); -#endif + if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION) + { + // Backup buffer can have "wrong" size if a Lua script + // performs a resize. + Update_buffers(Main_image_width, Main_image_height); + // + memcpy(Main_visible_image_backup.Image, + Main_visible_image.Image, + Main_image_width*Main_image_height); + } + else + { + Update_screen_targets(); + } Update_FX_feedback(Config.FX_Feedback); /* Last_backed_up_layers = 0; @@ -1306,6 +1314,7 @@ void End_of_modification(void) /// Add a new layer to latest page of a list. Returns 0 on success. byte Add_layer(T_List_of_pages *list, int layer) { + int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5}; T_Page * source_page; T_Page * new_page; byte * new_image; @@ -1313,7 +1322,7 @@ byte Add_layer(T_List_of_pages *list, int layer) source_page = list->Pages; - if (list->Pages->Nb_layers == MAX_NB_LAYERS) + if (list->Pages->Nb_layers >= max[list->Pages->Image_mode]) // MAX_NB_LAYERS return 1; // Keep the position reasonable