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:
parent
db50b4ebdc
commit
e73eb2786a
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
30
src/graph.c
30
src/graph.c
@ -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
|
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/layers.c
25
src/layers.c
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/misc.c
12
src/misc.c
@ -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)
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
|
|||||||
91
src/pages.c
91
src/pages.c
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user