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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
32
src/graph.c
32
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
|
||||
}
|
||||
|
||||
83
src/layers.c
83
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<<layer))
|
||||
// Right-click on current layer
|
||||
if (Main_current_layer == layer)
|
||||
{
|
||||
// Set all layers visible
|
||||
Main_layers_visible = 0xFFFFFFFF;
|
||||
if (Main_layers_visible == (dword)(1<<layer))
|
||||
{
|
||||
// Set all layers visible
|
||||
Main_layers_visible = 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set only this one visible
|
||||
Main_layers_visible = 1<<layer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set only this one visible
|
||||
Main_layers_visible = 1<<layer;
|
||||
// Right-click on an other layer : toggle its visibility
|
||||
Main_layers_visible ^= 1<<layer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Right-click on an other layer : toggle its visibility
|
||||
Main_layers_visible ^= 1<<layer;
|
||||
// Left-click on any layer
|
||||
Main_current_layer = layer;
|
||||
Main_layers_visible |= 1<<layer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Left-click on any layer
|
||||
Main_current_layer = layer;
|
||||
Main_layers_visible |= 1<<layer;
|
||||
// Only allow one visible at a time
|
||||
if (side == LEFT_SIDE)
|
||||
{
|
||||
Main_current_layer = layer;
|
||||
Main_layers_visible = 1<<layer;
|
||||
|
||||
Update_screen_targets();
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Handler for limited layers support: only allow one visible at a time
|
||||
if (side == LEFT_SIDE)
|
||||
{
|
||||
Main_current_layer = layer;
|
||||
Main_layers_visible = 1<<layer;
|
||||
|
||||
Update_screen_targets();
|
||||
}
|
||||
#endif
|
||||
|
||||
Hide_cursor();
|
||||
if (Main_layers_visible != old_layers)
|
||||
@ -97,26 +99,31 @@ void Layer_activate(int layer, short side)
|
||||
|
||||
void Button_Layer_add(void)
|
||||
{
|
||||
int max[] = {MAX_NB_LAYERS, MAX_NB_FRAMES, 5};
|
||||
|
||||
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_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();
|
||||
}
|
||||
|
||||
14
src/misc.c
14
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)
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
479
src/pages.c
479
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; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
{
|
||||
// Copy it in Main_visible_image
|
||||
memcpy(Main_visible_image.Image,
|
||||
Main_backups->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 (; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||
{
|
||||
byte color = *(Main_backups->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; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
{
|
||||
// Copy it in Main_visible_image
|
||||
memcpy(Main_visible_image.Image,
|
||||
Main_backups->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 (; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
// subsequent layer(s)
|
||||
for (; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||
// skip the current layer, whenever we reach it
|
||||
if (layer == Main_current_layer)
|
||||
continue;
|
||||
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
{
|
||||
byte color = *(Main_backups->Pages->Image[layer].Pixels+i);
|
||||
if (color != Main_backups->Pages->Transparent_color) // transparent color
|
||||
int i;
|
||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||
{
|
||||
*(Main_visible_image.Image+i) = color;
|
||||
if (layer != Main_current_layer)
|
||||
byte color = *(Main_backups->Pages->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; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
{
|
||||
// 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 (; layer<Main_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
// skip the current layer, whenever we reach it
|
||||
if (layer == Main_current_layer)
|
||||
continue;
|
||||
|
||||
if ((1<<layer) & Main_layers_visible)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||
{
|
||||
byte color = *(Main_backups->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; layer<Spare_backups->Pages->Nb_layers; layer++)
|
||||
if (Spare_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
|
||||
{
|
||||
if ((1<<layer) & Spare_layers_visible)
|
||||
// Re-construct the image with the visible layers
|
||||
byte layer;
|
||||
// First layer
|
||||
for (layer=0; layer<Spare_backups->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 (; layer<Spare_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Spare_layers_visible)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<Spare_image_width*Spare_image_height; i++)
|
||||
if ((1<<layer) & Spare_layers_visible)
|
||||
{
|
||||
byte color = *(Spare_backups->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 (; layer<Spare_backups->Pages->Nb_layers; layer++)
|
||||
{
|
||||
if ((1<<layer) & Spare_layers_visible)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<Spare_image_width*Spare_image_height; i++)
|
||||
{
|
||||
*(Spare_visible_image.Image+i) = color;
|
||||
//if (layer != Spare_current_layer)
|
||||
// *(Spare_visible_image_depth_buffer.Image+i) = layer;
|
||||
byte color = *(Spare_backups->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; i<Main_image_width*Main_image_height; i++)
|
||||
if (Main_backups->Pages->Image_mode != IMAGE_MODE_ANIMATION)
|
||||
{
|
||||
byte depth = *(Main_visible_image_depth_buffer.Image+i);
|
||||
if (depth<=Main_current_layer)
|
||||
int i;
|
||||
for (i=0; i<Main_image_width*Main_image_height; i++)
|
||||
{
|
||||
byte color = *(Main_backups->Pages->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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user