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
This commit is contained in:
Yves Rizoud 2012-03-02 23:19:47 +00:00
parent db50b4ebdc
commit e73eb2786a
8 changed files with 358 additions and 335 deletions

View File

@ -548,11 +548,23 @@ void Button_Toggle_toolbar(void)
case 0: // tools case 0: // tools
Set_bar_visibility(MENUBAR_TOOLS, !Menu_bars[MENUBAR_TOOLS].Visible); Set_bar_visibility(MENUBAR_TOOLS, !Menu_bars[MENUBAR_TOOLS].Visible);
break; break;
case 1: // anim case 1: // layers
if (Menu_bars[MENUBAR_ANIMATION].Visible && !Menu_bars[MENUBAR_LAYERS].Visible) if (Menu_bars[MENUBAR_ANIMATION].Visible && !Menu_bars[MENUBAR_LAYERS].Visible)
Set_bar_visibility(MENUBAR_ANIMATION, 0); Set_bar_visibility(MENUBAR_ANIMATION, 0);
Set_bar_visibility(MENUBAR_LAYERS, !Menu_bars[MENUBAR_LAYERS].Visible); 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) if (Main_backups->Pages->Image_mode == IMAGE_MODE_LAYERED)
{ {
// Exceptionally, this doesn't require a backup because a single-frame // 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; 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; break;
} }
} }

View File

@ -70,11 +70,8 @@
/// Character to display in menus for an ellipsis. /// Character to display in menus for an ellipsis.
#define ELLIPSIS_CHARACTER '…' #define ELLIPSIS_CHARACTER '…'
#define NB_LAYERS 1 ///< Initial number of layers for a new image #define NB_LAYERS 1 ///< Initial number of layers for a new image
#ifdef NOLAYERS #define MAX_NB_FRAMES 999 ///< Maximum number of frames that can be used in a grafx2 animation.
#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_LAYERS 16 ///< Maximum number of layers that can be used in grafx2. Note that 32 is upper limit because of a few bit fields. #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_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_PREVIEW_HEIGHT 16 ///< Size for preview of a brush in Brush container
#define BRUSH_CONTAINER_COLUMNS 4 ///< Number of columns in the Brush container #define BRUSH_CONTAINER_COLUMNS 4 ///< Number of columns in the Brush container

View File

@ -60,7 +60,6 @@
#include "struct.h" #include "struct.h"
#include "io.h" #include "io.h"
#include "windows.h" // Best_color() #include "windows.h" // Best_color()
#include "pages.h" // Add_layer()
//////////////////////////////////// IMG //////////////////////////////////// //////////////////////////////////// IMG ////////////////////////////////////
@ -2025,7 +2024,13 @@ void Load_GIF(T_IO_Context * context)
else if (!memcmp(aeb,"NETSCAPE2.0",0x0B)) else if (!memcmp(aeb,"NETSCAPE2.0",0x0B))
{ {
// The well-known Netscape extension. // 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 do
{ {
if (! Read_byte(GIF_file,&size_to_read)) 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 // Attempt to add a layer to current image
current_layer++; current_layer++;
Set_loading_layer(context, current_layer); Set_loading_layer(context, current_layer);
#ifdef NOLAYERS if (context->Type == CONTEXT_MAIN_IMAGE && Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION)
if (context->Type == CONTEXT_MAIN_IMAGE)
{ {
if (is_transparent) if (is_transparent)
// Copy the content of previous layer, in case of loading a GIF // 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, LSDB.Backcol,
Main_backups->Pages->Width*Main_backups->Pages->Height); Main_backups->Pages->Width*Main_backups->Pages->Height);
} }
#endif
} }
else else
{ {
@ -2165,7 +2168,6 @@ void Load_GIF(T_IO_Context * context)
LSDB.Backcol, LSDB.Backcol,
Main_backups->Pages->Width*Main_backups->Pages->Height); Main_backups->Pages->Width*Main_backups->Pages->Height);
} }
// Duration was set in the previously loaded GCE // Duration was set in the previously loaded GCE
Set_frame_duration(context, last_delay*10); Set_frame_duration(context, last_delay*10);
number_LID++; 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); // Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\xLL\xSS\xSS\x00",19);
// LL : 01 to loop // LL : 01 to loop
// SSSS : number of loops // SSSS : number of loops
#ifdef NOLAYERS if (context->Type == CONTEXT_MAIN_IMAGE && Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION)
if (context->Nb_layers>1) if (context->Nb_layers>1)
Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\x01\x00\x00\x00",19); Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\x01\x00\x00\x00",19);
#endif
// Ecriture du commentaire // Ecriture du commentaire
if (context->Comment[0]) if (context->Comment[0])
@ -2543,10 +2544,16 @@ void Save_GIF(T_IO_Context * context)
GCE.Block_identifier = 0x21; GCE.Block_identifier = 0x21;
GCE.Function = 0xF9; GCE.Function = 0xF9;
GCE.Block_size=4; GCE.Block_size=4;
#ifdef NOLAYERS
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.Packed_fields=(2<<2)|(context->Background_transparent);
GCE.Delay_time=Get_frame_duration(context)/10; GCE.Delay_time=Get_frame_duration(context)/10;
#else }
else
{
// Layered image
if (current_layer==0) if (current_layer==0)
GCE.Packed_fields=(1<<2)|(context->Background_transparent); GCE.Packed_fields=(1<<2)|(context->Background_transparent);
else else
@ -2554,7 +2561,7 @@ void Save_GIF(T_IO_Context * context)
GCE.Delay_time=5; // Duration 5/100s (minimum viable value for current web browsers) GCE.Delay_time=5; // Duration 5/100s (minimum viable value for current web browsers)
if (current_layer == context->Nb_layers -1) if (current_layer == context->Nb_layers -1)
GCE.Delay_time=0xFFFF; // Infinity (10 minutes) GCE.Delay_time=0xFFFF; // Infinity (10 minutes)
#endif }
GCE.Transparent_color=context->Transparent_color; GCE.Transparent_color=context->Transparent_color;
GCE.Block_terminator=0x00; GCE.Block_terminator=0x00;

View File

@ -3005,10 +3005,15 @@ void Redraw_grid(short x, short y, unsigned short w, unsigned short h)
byte Read_pixel_from_current_screen (word x,word y) byte Read_pixel_from_current_screen (word x,word y)
{ {
#ifndef NOLAYERS
byte depth; byte depth;
byte color; 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_backups->Pages->Image_mode == IMAGE_MODE_MODE5)
if (Main_current_layer==4) if (Main_current_layer==4)
return *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width); return *(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width);
@ -3019,26 +3024,21 @@ byte Read_pixel_from_current_screen (word x,word y)
depth = *(Main_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].Pixels + 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. /// Paint a a single pixel in image only : as-is.
void Pixel_in_screen_direct(word x,word y,byte color) 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. /// 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) 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); Pixel_preview(x,y,color);
} }
#ifndef NOLAYERS
/// Paint a a single pixel in image only : using layered display. /// Paint a a single pixel in image only : using layered display.
void Pixel_in_screen_layered(word x,word y,byte color) 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); Pixel_preview(x,y,color);
} }
} }
#endif
Func_pixel Pixel_in_current_screen=Pixel_in_screen_direct; Func_pixel Pixel_in_current_screen=Pixel_in_screen_direct;
Func_pixel Pixel_in_current_screen_with_preview=Pixel_in_screen_direct_with_preview; 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) 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) if (Main_backups->Pages->Image_mode == IMAGE_MODE_LAYERED)
{ {
// layered // layered
@ -3188,9 +3193,4 @@ void Update_pixel_renderer(void)
Pixel_in_current_screen = Pixel_in_screen_layered; Pixel_in_current_screen = Pixel_in_screen_layered;
Pixel_in_current_screen_with_preview = Pixel_in_screen_layered_with_preview; 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
} }

View File

@ -41,8 +41,8 @@ void Layer_activate(int layer, short side)
// Keep a copy of which layers were visible // Keep a copy of which layers were visible
old_layers = Main_layers_visible; old_layers = Main_layers_visible;
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
if (side == RIGHT_SIDE) if (side == RIGHT_SIDE)
{ {
// Right-click on current layer // Right-click on current layer
@ -71,8 +71,10 @@ void Layer_activate(int layer, short side)
Main_current_layer = layer; Main_current_layer = layer;
Main_layers_visible |= 1<<layer; Main_layers_visible |= 1<<layer;
} }
#else }
// Handler for limited layers support: only allow one visible at a time else
{
// Only allow one visible at a time
if (side == LEFT_SIDE) if (side == LEFT_SIDE)
{ {
Main_current_layer = layer; Main_current_layer = layer;
@ -80,7 +82,7 @@ void Layer_activate(int layer, short side)
Update_screen_targets(); Update_screen_targets();
} }
#endif }
Hide_cursor(); Hide_cursor();
if (Main_layers_visible != old_layers) if (Main_layers_visible != old_layers)
@ -97,26 +99,31 @@ void Layer_activate(int layer, short side)
void Button_Layer_add(void) void Button_Layer_add(void)
{ {
int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5};
Hide_cursor(); Hide_cursor();
if (Main_backups->Pages->Nb_layers < MAX_NB_LAYERS) if (Main_backups->Pages->Nb_layers < max[Main_backups->Pages->Image_mode])
{ {
// Backup with unchanged layers // Backup with unchanged layers
Backup_layers(0); Backup_layers(0);
if (!Add_layer(Main_backups,Main_current_layer+1)) if (!Add_layer(Main_backups,Main_current_layer+1))
{ {
#ifdef NOLAYERS if (Main_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION)
{
// Make a copy of current image, so the display is unchanged // Make a copy of current image, so the display is unchanged
memcpy( memcpy(
Main_backups->Pages->Image[Main_current_layer].Pixels, Main_backups->Pages->Image[Main_current_layer].Pixels,
Main_backups->Pages->Image[Main_current_layer-1].Pixels, Main_backups->Pages->Image[Main_current_layer-1].Pixels,
Main_backups->Pages->Width*Main_backups->Pages->Height); Main_backups->Pages->Width*Main_backups->Pages->Height);
#else }
else
{
Update_depth_buffer(); Update_depth_buffer();
// I just noticed this might be unneeded, since the new layer // I just noticed this might be unneeded, since the new layer
// is transparent, it shouldn't have any visible effect. // is transparent, it shouldn't have any visible effect.
Display_all_screen(); Display_all_screen();
#endif }
Display_layerbar(); Display_layerbar();
End_of_modification(); End_of_modification();
} }

View File

@ -303,12 +303,14 @@ byte Read_pixel_from_spare_screen(word x,word y)
// (can be a bigger or smaller image) // (can be a bigger or smaller image)
if (x>=Spare_image_width || y>=Spare_image_height) if (x>=Spare_image_width || y>=Spare_image_height)
return Spare_backups->Pages->Transparent_color; return Spare_backups->Pages->Transparent_color;
#ifndef NOLAYERS if (Spare_backups->Pages->Image_mode == IMAGE_MODE_ANIMATION)
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); return *(Spare_backups->Pages->Image[Spare_current_layer].Pixels + y*Spare_image_width + x);
#endif }
else
{
return *(Spare_visible_image.Image + y*Spare_image_width + x);
}
} }
void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height) void Rotate_90_deg_lowlevel(byte * source, byte * dest, short width, short height)

View File

@ -2785,13 +2785,14 @@ void Scroll_12_0(void)
else else
{ {
Backup_layers(-1); // Main_layers_visible 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 // Ensure the backup visible image is up-to-date
// (after swapping some layers on/off, it gets outdated) // (after swapping some layers on/off, it gets outdated)
memcpy(Main_visible_image_backup.Image, memcpy(Main_visible_image_backup.Image,
Main_visible_image.Image, Main_visible_image.Image,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
#endif }
} }
Update_screen_targets(); Update_screen_targets();

View File

@ -38,12 +38,10 @@
// -- Layers data // -- Layers data
/// Array of two images, that contains the "flattened" version of the visible layers. /// 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;
T_Bitmap Main_visible_image_backup; T_Bitmap Main_visible_image_backup;
T_Bitmap Main_visible_image_depth_buffer; T_Bitmap Main_visible_image_depth_buffer;
T_Bitmap Spare_visible_image; T_Bitmap Spare_visible_image;
#endif
/// ///
/// GESTION DES PAGES /// GESTION DES PAGES
@ -200,7 +198,8 @@ void Download_infos_page_main(T_Page * page)
void Redraw_layered_image(void) void Redraw_layered_image(void)
{ {
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
// Re-construct the image with the visible layers // Re-construct the image with the visible layers
byte layer=0; byte layer=0;
// First layer // First layer
@ -263,15 +262,18 @@ void Redraw_layered_image(void)
} }
} }
} }
#else }
else
{
Update_screen_targets(); Update_screen_targets();
#endif }
Update_FX_feedback(Config.FX_Feedback); Update_FX_feedback(Config.FX_Feedback);
} }
void Update_depth_buffer(void) void Update_depth_buffer(void)
{ {
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
// Re-construct the depth buffer with the visible layers. // Re-construct the depth buffer with the visible layers.
// This function doesn't touch the visible buffer, it assumes // This function doesn't touch the visible buffer, it assumes
// that it was already up-to-date. (Ex. user only changed active layer) // that it was already up-to-date. (Ex. user only changed active layer)
@ -312,13 +314,14 @@ void Update_depth_buffer(void)
} }
} }
} }
#endif }
Update_FX_feedback(Config.FX_Feedback); Update_FX_feedback(Config.FX_Feedback);
} }
void Redraw_spare_image(void) void Redraw_spare_image(void)
{ {
#ifndef NOLAYERS if (Spare_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
// Re-construct the image with the visible layers // Re-construct the image with the visible layers
byte layer; byte layer;
// First layer // First layer
@ -359,12 +362,13 @@ void Redraw_spare_image(void)
} }
} }
} }
#endif }
} }
void Redraw_current_layer(void) void Redraw_current_layer(void)
{ {
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
int i; int i;
for (i=0; i<Main_image_width*Main_image_height; i++) for (i=0; i<Main_image_width*Main_image_height; i++)
{ {
@ -382,7 +386,7 @@ void Redraw_current_layer(void)
} }
} }
} }
#endif }
} }
void Upload_infos_page_main(T_Page * page) void Upload_infos_page_main(T_Page * page)
@ -672,24 +676,24 @@ void Free_page_of_a_list(T_List_of_pages * list)
void Update_screen_targets(void) void Update_screen_targets(void)
{ {
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
Main_screen=Main_visible_image.Image; Main_screen=Main_visible_image.Image;
Screen_backup=Main_visible_image_backup.Image; Screen_backup=Main_visible_image_backup.Image;
#else }
else
{
Main_screen=Main_backups->Pages->Image[Main_current_layer].Pixels; Main_screen=Main_backups->Pages->Image[Main_current_layer].Pixels;
Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer].Pixels; Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer].Pixels;
#endif }
Update_pixel_renderer(); Update_pixel_renderer();
} }
/// Update all the special image buffers, if necessary. /// Update all the special image buffers, if necessary.
int Update_buffers(int width, int height) int Update_buffers(int width, int height)
{ {
#ifdef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
// unused args {
(void) width;
(void) height;
#else
// At least one dimension is different // At least one dimension is different
if (Main_visible_image.Width*Main_visible_image.Height != width*height) if (Main_visible_image.Width*Main_visible_image.Height != width*height)
{ {
@ -723,19 +727,15 @@ int Update_buffers(int width, int height)
} }
Main_visible_image_depth_buffer.Width = width; Main_visible_image_depth_buffer.Width = width;
Main_visible_image_depth_buffer.Height = height; Main_visible_image_depth_buffer.Height = height;
}
#endif
Update_screen_targets(); Update_screen_targets();
return 1; return 1;
} }
/// Update all the special image buffers of the spare page, if necessary. /// Update all the special image buffers of the spare page, if necessary.
int Update_spare_buffers(int width, int height) int Update_spare_buffers(int width, int height)
{ {
#ifdef NOLAYERS if (Spare_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
// unused args {
(void) width;
(void) height;
#else
// At least one dimension is different // At least one dimension is different
if (Spare_visible_image.Width*Spare_visible_image.Height != width*height) if (Spare_visible_image.Width*Spare_visible_image.Height != width*height)
{ {
@ -748,7 +748,7 @@ int Update_spare_buffers(int width, int height)
Spare_visible_image.Width = width; Spare_visible_image.Width = width;
Spare_visible_image.Height = height; Spare_visible_image.Height = height;
#endif }
return 1; return 1;
} }
@ -783,7 +783,6 @@ int Init_all_backup_lists(int width,int height)
return 0; return 0;
memset(Main_backups->Pages->Image[i].Pixels, 0, width*height); memset(Main_backups->Pages->Image[i].Pixels, 0, width*height);
} }
#ifndef NOLAYERS
Main_visible_image.Width = 0; Main_visible_image.Width = 0;
Main_visible_image.Height = 0; Main_visible_image.Height = 0;
Main_visible_image.Image = NULL; 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.Height = 0;
Spare_visible_image.Image = NULL; Spare_visible_image.Image = NULL;
#endif
if (!Update_buffers(width, height)) if (!Update_buffers(width, height))
return 0; return 0;
if (!Update_spare_buffers(width, height)) if (!Update_spare_buffers(width, height))
return 0; return 0;
#ifndef NOLAYERS
// For speed, instead of Redraw_layered_image() we'll directly set the buffers. // 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.Image, 0, width*height);
memset(Main_visible_image_backup.Image, 0, width*height); memset(Main_visible_image_backup.Image, 0, width*height);
memset(Main_visible_image_depth_buffer.Image, 0, width*height); memset(Main_visible_image_depth_buffer.Image, 0, width*height);
memset(Spare_visible_image.Image, 0, width*height); memset(Spare_visible_image.Image, 0, width*height);
#endif
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
Update_FX_feedback(Config.FX_Feedback); Update_FX_feedback(Config.FX_Feedback);
@ -872,6 +868,7 @@ int Backup_new_image(int layers,int width,int height)
} }
Update_buffers(width, height); Update_buffers(width, height);
memset(Main_visible_image_depth_buffer.Image, 0, width*height);
Download_infos_page_main(Main_backups->Pages); 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(), // Same code as in End_of_modification(),
// Without saving a safety backup: // Without saving a safety backup:
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
memcpy(Main_visible_image_backup.Image, memcpy(Main_visible_image_backup.Image,
Main_visible_image.Image, Main_visible_image.Image,
Main_image_width*Main_image_height); 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(); Update_screen_targets();
#endif }
Update_FX_feedback(Config.FX_Feedback); Update_FX_feedback(Config.FX_Feedback);
// -- // --
@ -989,7 +994,8 @@ int Backup_in_place(int width,int height)
// The following is part of Update_buffers() // The following is part of Update_buffers()
// (without changing the backup buffer) // (without changing the backup buffer)
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
// At least one dimension is different // At least one dimension is different
if (Main_visible_image.Width*Main_visible_image.Height != width*height) if (Main_visible_image.Width*Main_visible_image.Height != width*height)
{ {
@ -1013,7 +1019,7 @@ int Backup_in_place(int width,int height)
Main_visible_image_depth_buffer.Width = width; Main_visible_image_depth_buffer.Width = width;
Main_visible_image_depth_buffer.Height = height; Main_visible_image_depth_buffer.Height = height;
#endif }
Update_screen_targets(); Update_screen_targets();
return 1; return 1;
@ -1278,7 +1284,8 @@ void End_of_modification(void)
//Update_buffers(Main_image_width, Main_image_height); //Update_buffers(Main_image_width, Main_image_height);
#ifndef NOLAYERS if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
{
// Backup buffer can have "wrong" size if a Lua script // Backup buffer can have "wrong" size if a Lua script
// performs a resize. // performs a resize.
Update_buffers(Main_image_width, Main_image_height); Update_buffers(Main_image_width, Main_image_height);
@ -1287,10 +1294,11 @@ void End_of_modification(void)
memcpy(Main_visible_image_backup.Image, memcpy(Main_visible_image_backup.Image,
Main_visible_image.Image, Main_visible_image.Image,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
#else }
else
{
Update_screen_targets(); Update_screen_targets();
#endif }
Update_FX_feedback(Config.FX_Feedback); Update_FX_feedback(Config.FX_Feedback);
/* /*
Last_backed_up_layers = 0; 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. /// Add a new layer to latest page of a list. Returns 0 on success.
byte Add_layer(T_List_of_pages *list, int layer) 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 * source_page;
T_Page * new_page; T_Page * new_page;
byte * new_image; byte * new_image;
@ -1313,7 +1322,7 @@ byte Add_layer(T_List_of_pages *list, int layer)
source_page = list->Pages; 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; return 1;
// Keep the position reasonable // Keep the position reasonable