Re-integrated anim in trunk, fixing the 999-layer limit at the same time

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1841 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2011-10-19 23:35:56 +00:00
parent 775ee56ed0
commit 8fb16e7089
28 changed files with 753 additions and 174 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1620,15 +1620,15 @@ void Copy_image_only(void)
if (i == Spare_current_layer)
{
// Copy the current layer
memcpy(Spare_backups->Pages->Image[i],Main_backups->Pages->Image[Main_current_layer],Main_image_width*Main_image_height);
memcpy(Spare_backups->Pages->Image[i].Pixels,Main_backups->Pages->Image[Main_current_layer].Pixels,Main_image_width*Main_image_height);
}
else
{
// Resize the original layer
Copy_part_of_image_to_another(
Spare_backups->Pages->Next->Image[i],0,0,Min(old_width,Spare_image_width),
Spare_backups->Pages->Next->Image[i].Pixels,0,0,Min(old_width,Spare_image_width),
Min(old_height,Spare_image_height),old_width,
Spare_backups->Pages->Image[i],0,0,Spare_image_width);
Spare_backups->Pages->Image[i].Pixels,0,0,Spare_image_width);
}
}

View File

@ -71,7 +71,11 @@
/// 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_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
@ -289,6 +293,12 @@ enum BUTTON_NUMBERS
BUTTON_LAYER_REMOVE,
BUTTON_LAYER_UP,
BUTTON_LAYER_DOWN,
BUTTON_ANIM_TIME,
BUTTON_ANIM_FIRST_FRAME,
BUTTON_ANIM_PREV_FRAME,
BUTTON_ANIM_NEXT_FRAME,
BUTTON_ANIM_LAST_FRAME,
BUTTON_ANIM_PLAY,
BUTTON_LAYER_SELECT,
// Main menu

View File

@ -79,6 +79,12 @@ char * Menu_tooltip[NB_BUTTONS]=
"Drop layer ",
"Raise layer ",
"Lower layer ",
"Set frame time ",
"Go to first frame ",
"Go to previous frame ",
"Go to next frame ",
"Go to last frame ",
"Preview animation ",
"Layer select / toggle ",
"Paintbrush choice ",
"Adjust / Transform menu ",

View File

@ -299,9 +299,9 @@ int L_SetPictureSize(lua_State* L)
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Copy_part_of_image_to_another(
Main_backups->Pages->Next->Image[i],0,0,Min(Main_backups->Pages->Next->Width,Main_image_width),
Main_backups->Pages->Next->Image[i].Pixels,0,0,Min(Main_backups->Pages->Next->Width,Main_image_width),
Min(Main_backups->Pages->Next->Height,Main_image_height),Main_backups->Pages->Next->Width,
Main_backups->Pages->Image[i],0,0,Main_image_width);
Main_backups->Pages->Image[i].Pixels,0,0,Main_image_width);
}
Redraw_layered_image();
@ -326,9 +326,9 @@ int L_SetSparePictureSize(lua_State* L)
for (i=0; i<Spare_backups->Pages->Nb_layers; i++)
{
Copy_part_of_image_to_another(
Spare_backups->Pages->Next->Image[i],0,0,Min(Spare_backups->Pages->Next->Width,Spare_image_width),
Spare_backups->Pages->Next->Image[i].Pixels,0,0,Min(Spare_backups->Pages->Next->Width,Spare_image_width),
Min(Spare_backups->Pages->Next->Height,Spare_image_height),Spare_backups->Pages->Next->Width,
Spare_backups->Pages->Image[i],0,0,Spare_image_width);
Spare_backups->Pages->Image[i].Pixels,0,0,Spare_image_width);
}
Redraw_spare_image();
@ -637,7 +637,7 @@ int L_GetSpareLayerPixel(lua_State* L)
lua_pushinteger(L, Spare_backups->Pages->Transparent_color);
return 1;
}
lua_pushinteger(L, *(Spare_backups->Pages->Image[Spare_current_layer] + y*Spare_image_width + x));
lua_pushinteger(L, *(Spare_backups->Pages->Image[Spare_current_layer].Pixels + y*Spare_image_width + x));
return 1;
}

View File

@ -1706,18 +1706,26 @@ typedef struct
typedef struct
{
// byte Block_identifier : 0x21
// byte Function : 0xF9
// byte Block_size // 4
byte Block_identifier; // 0x21
byte Function; // 0xF9
byte Block_size; // 4
byte Packed_fields; // 11100000 : Reserved
// 00011100 : Disposal method
// 00000010 : User input flag
// 00000001 : Transparent flag
word Delay_time; // Time for this frame to stay displayed
byte Transparent_color; // Which color index acts as transparent
//word Bloc_terminator; // 0x00
word Block_terminator; // 0x00
} T_GIF_GCE; // Graphic Control Extension
enum DISPOSAL_METHOD
{
DISPOSAL_METHOD_UNDEFINED = 0,
DISPOSAL_METHOD_DO_NOT_DISPOSE = 1,
DISPOSAL_METHOD_RESTORE_BGCOLOR = 2,
DISPOSAL_METHOD_RESTORE_PREVIOUS = 3,
};
// -- Tester si un fichier est au format GIF --------------------------------
void Test_GIF(T_IO_Context * context)
@ -1801,8 +1809,9 @@ word GIF_get_next_code(void)
// -- Affiche un nouveau pixel --
void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, byte color)
void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, int is_transparent, byte color)
{
if (!is_transparent || color!=context->Transparent_color)
Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
GIF_pos_X++;
@ -1872,7 +1881,11 @@ void Load_GIF(T_IO_Context * context)
word value_eof; // Valeur <=> End d'image
long file_size;
int number_LID; // Nombre d'images trouvées dans le fichier
short current_layer = 0;
int current_layer = 0;
int last_delay = 0;
byte is_transparent = 0;
byte disposal_method = DISPOSAL_METHOD_RESTORE_BGCOLOR;
byte previous_disposal_method = DISPOSAL_METHOD_RESTORE_BGCOLOR;
/////////////////////////////////////////////////// FIN DES DECLARATIONS //
@ -1972,19 +1985,23 @@ void Load_GIF(T_IO_Context * context)
&& Read_word_le(GIF_file,&(GCE.Delay_time))
&& Read_byte(GIF_file,&(GCE.Transparent_color)))
{
previous_disposal_method = disposal_method;
disposal_method = (GCE.Packed_fields >> 2) & 7;
last_delay = GCE.Delay_time;
context->Transparent_color= GCE.Transparent_color;
if (GCE.Packed_fields & 1)
{
if (number_LID == 0)
context->Background_transparent = 1;
context->Transparent_color= GCE.Transparent_color;
}
else
{
if (number_LID == 0)
context->Background_transparent = 0;
context->Transparent_color = 0; // Reset transparent color
}
is_transparent =
(previous_disposal_method==DISPOSAL_METHOD_DO_NOT_DISPOSE
||previous_disposal_method==DISPOSAL_METHOD_UNDEFINED);
}
else
File_error=2;
@ -2117,7 +2134,35 @@ 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 (is_transparent)
// Copy the content of previous layer, in case of loading a GIF
// that uses transparency compression
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
memset(
Main_backups->Pages->Image[Main_current_layer].Pixels,
LSDB.Backcol,
Main_backups->Pages->Width*Main_backups->Pages->Height);
}
#endif
}
else
{
if (context->Type == CONTEXT_MAIN_IMAGE)
memset(
Main_backups->Pages->Image[Main_current_layer].Pixels,
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++;
// lecture de 10 derniers octets
@ -2202,7 +2247,7 @@ void Load_GIF(T_IO_Context * context)
special_case=alphabet_stack[alphabet_stack_pos++]=GIF_current_code;
do
GIF_new_pixel(context, &IDB, alphabet_stack[--alphabet_stack_pos]);
GIF_new_pixel(context, &IDB, is_transparent, alphabet_stack[--alphabet_stack_pos]);
while (alphabet_stack_pos!=0);
alphabet_prefix[alphabet_free ]=old_code;
@ -2222,7 +2267,7 @@ void Load_GIF(T_IO_Context * context)
alphabet_free =(1<<initial_nb_bits)+2;
special_case =GIF_get_next_code();
old_code =GIF_current_code;
GIF_new_pixel(context, &IDB, GIF_current_code);
GIF_new_pixel(context, &IDB, is_transparent, GIF_current_code);
}
}
else
@ -2371,7 +2416,7 @@ void Save_GIF(T_IO_Context * context)
word current_string; // Code de la chaîne en cours de traitement
byte current_char; // Caractère à coder
word index; // index de recherche de chaîne
short current_layer;
int current_layer;
/////////////////////////////////////////////////// FIN DES DECLARATIONS //
@ -2436,6 +2481,10 @@ 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
// Ecriture du commentaire
if (context->Comment[0])
@ -2471,24 +2520,36 @@ void Save_GIF(T_IO_Context * context)
current_layer++)
{
// Write a Graphic Control Extension
byte GCE_block[] = "\x21\xF9\x04\x04\x05\x00\x00\x00";
// 'Default' values:
// Disposal method "Do not dispose"
// Duration 5/100s (minimum viable value for current web browsers)
if (current_layer > 0 || context->Background_transparent)
GCE_block[3] |= 1; // Transparent color flag
GCE_block[6] = context->Transparent_color;
T_GIF_GCE GCE;
Set_saving_layer(context, current_layer);
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);
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)
{
// "Infinite" delay for last frame
GCE_block[4] = 255;
GCE_block[5] = 255;
}
if (Write_bytes(GIF_file,GCE_block,8))
GCE.Delay_time=0xFFFF; // Infinity (10 minutes)
#endif
GCE.Transparent_color=context->Transparent_color;
GCE.Block_terminator=0x00;
if (Write_byte(GIF_file,GCE.Block_identifier)
&& Write_byte(GIF_file,GCE.Function)
&& Write_byte(GIF_file,GCE.Block_size)
&& Write_byte(GIF_file,GCE.Packed_fields)
&& Write_word_le(GIF_file,GCE.Delay_time)
&& Write_byte(GIF_file,GCE.Transparent_color)
&& Write_byte(GIF_file,GCE.Block_terminator)
)
{
// On va écrire un block indicateur d'IDB et l'IDB du fichier

View File

@ -336,7 +336,7 @@ GFX2_GLOBAL short Main_magnifier_offset_X;
/// Y position (in image space) of the pixel to display in the top left corner of the magnified view.
GFX2_GLOBAL short Main_magnifier_offset_Y;
/// Index of layer currently being edited
GFX2_GLOBAL byte Main_current_layer;
GFX2_GLOBAL int Main_current_layer;
/// Bitfield that records which layers are visible. 2^0 for 0, 2^1 for 1, 2^2 for 2, etc.
GFX2_GLOBAL dword Main_layers_visible;
/// Index to use next time, when creating incremental backups, to make unique filename.
@ -402,7 +402,7 @@ GFX2_GLOBAL short Spare_magnifier_offset_X;
/// Y position (in image space) of the pixel to display in the top left corner of the magnified view.
GFX2_GLOBAL short Spare_magnifier_offset_Y;
/// Index of layer currently being edited
GFX2_GLOBAL byte Spare_current_layer;
GFX2_GLOBAL int Spare_current_layer;
/// Bitfield that records which layers are visible. 2^0 for 0, 2^1 for 1, 2^2 for 2, etc.
GFX2_GLOBAL dword Spare_layers_visible;
/// Index to use next time, when creating incremental backups, to make unique filename.
@ -495,7 +495,11 @@ GFX2_GLOBAL T_Menu_Bar Menu_bars[MENUBAR_COUNT]
#ifdef GLOBAL_VARIABLES
=
{{MENU_WIDTH, 9, 1, 45, {NULL,NULL,NULL}, 20, BUTTON_HIDE }, // Status
#ifdef NOLAYERS
{MENU_WIDTH, 14, 1, 35, {NULL,NULL,NULL}, 236, BUTTON_LAYER_SELECT }, // Animation
#else
{MENU_WIDTH, 10, 1, 35, {NULL,NULL,NULL}, 144, BUTTON_LAYER_SELECT }, // Layers
#endif
{MENU_WIDTH, 35, 1, 0, {NULL,NULL,NULL}, 254, BUTTON_CHOOSE_COL }} // Main
#endif
;

View File

@ -632,9 +632,9 @@ void Resize_image(word chosen_width,word chosen_height)
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Copy_part_of_image_to_another(
Main_backups->Pages->Next->Image[i],0,0,Min(old_width,Main_image_width),
Main_backups->Pages->Next->Image[i].Pixels,0,0,Min(old_width,Main_image_width),
Min(old_height,Main_image_height),old_width,
Main_backups->Pages->Image[i],0,0,Main_image_width);
Main_backups->Pages->Image[i].Pixels,0,0,Main_image_width);
}
Redraw_layered_image();
}
@ -655,7 +655,7 @@ void Remap_spare(void)
short y_pos; // Variable de balayage de la brosse
byte used[256]; // Tableau de booléens "La couleur est utilisée"
int color;
byte layer;
int layer;
// On commence par initialiser le tableau de booléens à faux
for (color=0;color<=255;color++)
@ -665,7 +665,7 @@ void Remap_spare(void)
for (layer=0; layer<Spare_backups->Pages->Nb_layers; layer++)
for (y_pos=0;y_pos<Spare_image_height;y_pos++)
for (x_pos=0;x_pos<Spare_image_width;x_pos++)
used[*(Spare_backups->Pages->Image[layer]+(y_pos*Spare_image_width+x_pos))]=1;
used[*(Spare_backups->Pages->Image[layer].Pixels+(y_pos*Spare_image_width+x_pos))]=1;
// On va maintenant se servir de la table "used" comme table de
// conversion: pour chaque indice, la table donne une couleur de
@ -682,7 +682,7 @@ void Remap_spare(void)
// qui craint un peu, on peut faire l'échange dans la brosse de toutes les
// teintes.
for (layer=0; layer<Spare_backups->Pages->Nb_layers; layer++)
Remap_general_lowlevel(used,Spare_backups->Pages->Image[layer],Spare_backups->Pages->Image[layer],Spare_image_width,Spare_image_height,Spare_image_width);
Remap_general_lowlevel(used,Spare_backups->Pages->Image[layer].Pixels,Spare_backups->Pages->Image[layer].Pixels,Spare_image_width,Spare_image_height,Spare_image_width);
// Change transparent color index
Spare_backups->Pages->Transparent_color=used[Spare_backups->Pages->Transparent_color];
@ -979,7 +979,7 @@ void Fill(short * top_reached , short * bottom_reached,
byte Read_pixel_from_backup_layer(word x,word y)
{
return *((y)*Main_image_width+(x)+Main_backups->Pages->Next->Image[Main_current_layer]);
return *((y)*Main_image_width+(x)+Main_backups->Pages->Next->Image[Main_current_layer].Pixels);
}
void Fill_general(byte fill_color)
@ -1035,34 +1035,34 @@ void Fill_general(byte fill_color)
// Il va maintenant falloir qu'on "turn" ce gros caca "into" un truc qui
// ressemble un peu plus à ce à quoi l'utilisateur peut s'attendre.
if (top_reached>Limit_top)
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer], // source
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer].Pixels, // source
Limit_left,Limit_top, // Pos X et Y dans source
(Limit_right-Limit_left)+1, // width copie
top_reached-Limit_top,// height copie
Main_image_width, // width de la source
Main_backups->Pages->Image[Main_current_layer], // Destination
Main_backups->Pages->Image[Main_current_layer].Pixels, // Destination
Limit_left,Limit_top, // Pos X et Y destination
Main_image_width); // width destination
if (bottom_reached<Limit_bottom)
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer],
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer].Pixels,
Limit_left,bottom_reached+1,
(Limit_right-Limit_left)+1,
Limit_bottom-bottom_reached,
Main_image_width,Main_backups->Pages->Image[Main_current_layer],
Main_image_width,Main_backups->Pages->Image[Main_current_layer].Pixels,
Limit_left,bottom_reached+1,Main_image_width);
if (left_reached>Limit_left)
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer],
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer].Pixels,
Limit_left,top_reached,
left_reached-Limit_left,
(bottom_reached-top_reached)+1,
Main_image_width,Main_backups->Pages->Image[Main_current_layer],
Main_image_width,Main_backups->Pages->Image[Main_current_layer].Pixels,
Limit_left,top_reached,Main_image_width);
if (right_reached<Limit_right)
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer],
Copy_part_of_image_to_another(Main_backups->Pages->Next->Image[Main_current_layer].Pixels,
right_reached+1,top_reached,
Limit_right-right_reached,
(bottom_reached-top_reached)+1,
Main_image_width,Main_backups->Pages->Image[Main_current_layer],
Main_image_width,Main_backups->Pages->Image[Main_current_layer].Pixels,
right_reached+1,top_reached,Main_image_width);
for (y_pos=top_reached;y_pos<=bottom_reached;y_pos++)
@ -2924,7 +2924,7 @@ byte Effect_layer_copy(word x,word y,byte color)
{
if (color<Main_backups->Pages->Nb_layers)
{
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[color]);
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[color].Pixels);
}
return Read_pixel_from_feedback_screen(x,y);
}
@ -2974,16 +2974,16 @@ byte Read_pixel_from_current_screen (word x,word y)
byte color;
if (Main_current_layer==4)
return *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width);
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] + 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]);
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels);
#endif
}
@ -2993,30 +2993,29 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
if (!Constraint_mode)
{
byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
*(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color;
if ( depth <= Main_current_layer)
{
if (color == Main_backups->Pages->Transparent_color) // transparent color
// fetch pixel color from the topmost visible layer
color=*(Main_backups->Pages->Image[depth] + x+y*Main_image_width);
color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width);
*(x+y*Main_image_width+Main_screen)=color;
if (with_preview)
Pixel_preview(x,y,color);
}
}
else if ( Main_current_layer == 4)
{
if (color<4)
{
// Paste in layer
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
*(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color;
// Paste in depth buffer
*(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color;
// Fetch pixel color from the target raster layer
color=*(Main_backups->Pages->Image[color] + x+y*Main_image_width);
color=*(Main_backups->Pages->Image[color].Pixels + x+y*Main_image_width);
// Draw that color on the visible image buffer
*(x+y*Main_image_width+Main_screen)=color;
@ -3029,9 +3028,9 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
byte depth;
// Paste in layer
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
*(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color;
// Search depth
depth = *(Main_backups->Pages->Image[4] + x+y*Main_image_width);
depth = *(Main_backups->Pages->Image[4].Pixels + x+y*Main_image_width);
if ( depth == Main_current_layer)
{
@ -3046,13 +3045,13 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
{
byte depth;
*(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color;
*(Main_backups->Pages->Image[Main_current_layer].Pixels + x+y*Main_image_width)=color;
depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
if ( depth <= Main_current_layer)
{
if (color == Main_backups->Pages->Transparent_color) // transparent color
// fetch pixel color from the topmost visible layer
color=*(Main_backups->Pages->Image[depth] + x+y*Main_image_width);
color=*(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width);
*(x+y*Main_image_width+Main_screen)=color;
@ -3061,7 +3060,7 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
}
}
#else
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color;
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels)=color;
if (with_preview)
Pixel_preview(x,y,color);
#endif
@ -3069,15 +3068,15 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
void Pixel_in_spare(word x,word y, byte color)
{
*((y)*Spare_image_width+(x)+Spare_backups->Pages->Image[Spare_current_layer])=color;
*((y)*Spare_image_width+(x)+Spare_backups->Pages->Image[Spare_current_layer].Pixels)=color;
}
void Pixel_in_current_layer(word x,word y, byte color)
{
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color;
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels)=color;
}
byte Read_pixel_from_current_layer(word x,word y)
{
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer]);
return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer].Pixels);
}

View File

@ -306,15 +306,18 @@ static const T_Help_table helptable_help[] =
HELP_LINK (" Next : %s", SPECIAL_NEXT_USER_BACKCOLOR)
HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR)
HELP_TEXT ("")
HELP_TEXT ("LAYERS")
HELP_TEXT ("LAYERS / ANIMATION FRAMES")
HELP_TEXT ("")
HELP_LINK (" Menu : %s", 0x100+BUTTON_LAYER_MENU)
HELP_LINK (" Add new : %s", 0x100+BUTTON_LAYER_ADD)
HELP_LINK (" Delete : %s", 0x100+BUTTON_LAYER_REMOVE)
#ifndef NOLAYERS
HELP_LINK (" Merge : %s", 0x100+BUTTON_LAYER_MERGE)
#endif
HELP_LINK (" Move up : %s", 0x100+BUTTON_LAYER_UP)
HELP_LINK (" Move down : %s", 0x100+BUTTON_LAYER_DOWN)
//HELP_LINK (" Set transp: %s", 0x100+BUTTON_LAYER_COLOR)
#ifndef NOLAYERS
HELP_TEXT (" Select :")
HELP_LINK (" 1 : %s", SPECIAL_LAYER1_SELECT)
HELP_LINK (" 2 : %s", SPECIAL_LAYER2_SELECT)
@ -333,6 +336,13 @@ static const T_Help_table helptable_help[] =
HELP_LINK (" 6 : %s", SPECIAL_LAYER6_TOGGLE)
HELP_LINK (" 7 : %s", SPECIAL_LAYER7_TOGGLE)
HELP_LINK (" 8 : %s", SPECIAL_LAYER8_TOGGLE)
#else
HELP_LINK (" Go to first: %s", 0x100+BUTTON_ANIM_FIRST_FRAME)
HELP_LINK (" Go to previous: %s", 0x100+BUTTON_ANIM_PREV_FRAME)
HELP_LINK (" Go to next: %s", 0x100+BUTTON_ANIM_NEXT_FRAME)
HELP_LINK (" Go to last: %s", 0x100+BUTTON_ANIM_LAST_FRAME)
HELP_LINK (" Set duration: %s", 0x100+BUTTON_ANIM_TIME)
#endif
HELP_TEXT ("")
HELP_LINK (" Format check : %s", SPECIAL_FORMAT_CHECKER)
HELP_LINK (" Format check menu: %s", SPECIAL_FORMAT_CHECKER_MENU)
@ -2924,6 +2934,14 @@ T_Help_section Help_section[] =
HELP_TABLE_DECLARATION(helptable_layerdel)
HELP_TABLE_DECLARATION(helptable_layerup)
HELP_TABLE_DECLARATION(helptable_layerdown)
// TODO: implement specific help sections for anim buttons
HELP_TABLE_DECLARATION(helptable_layerselect)
HELP_TABLE_DECLARATION(helptable_layerselect)
HELP_TABLE_DECLARATION(helptable_layerselect)
HELP_TABLE_DECLARATION(helptable_layerselect)
HELP_TABLE_DECLARATION(helptable_layerselect)
HELP_TABLE_DECLARATION(helptable_layerselect)
//
HELP_TABLE_DECLARATION(helptable_layerselect)
HELP_TABLE_DECLARATION(helptable_paintbrush)
HELP_TABLE_DECLARATION(helptable_adjust)

View File

@ -1657,6 +1657,54 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
true,
0,
0},
{200,
"Set frame time",
"Opens a window where you",
"can set the current animation",
"frame duration.",
true,
0, // No shortcut
0},
{201,
"Go to first frame",
"Edits the first frame of",
"an animation",
"",
true,
0, // No shortcut
0},
{202,
"Go to last frame",
"Edits the last frame of",
"an animation",
"",
true,
0, // No shortcut
0},
{203,
"Go to previous frame",
"Edits the previous frame of",
"an animation",
"",
true,
0, // No shortcut
0},
{204,
"Go to next frame",
"Edits the next frame of",
"an animation",
"",
true,
0, // No shortcut
0},
{205,
"Preview animation",
"Runs the current animation.",
"",
"",
true,
0, // No shortcut
0},
};
word Ordering[NB_SHORTCUTS]=
@ -1861,4 +1909,10 @@ word Ordering[NB_SHORTCUTS]=
SPECIAL_CYCLE_MODE,
SPECIAL_FORMAT_CHECKER,
SPECIAL_FORMAT_CHECKER_MENU,
0x100+BUTTON_ANIM_TIME,
0x100+BUTTON_ANIM_FIRST_FRAME,
0x100+BUTTON_ANIM_LAST_FRAME,
0x100+BUTTON_ANIM_PREV_FRAME,
0x100+BUTTON_ANIM_NEXT_FRAME,
0x100+BUTTON_ANIM_PLAY,
};

View File

@ -374,9 +374,16 @@ byte Parse_skin(SDL_Surface * gui, T_Gui_skin *gfx)
// Layerbar
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "layer bar"))
return 1;
if (Read_GUI_block(gfx, gui, cursor_x, cursor_y, gfx->Layerbar_block[0], Menu_bars[MENUBAR_LAYERS].Skin_width, Menu_bars[MENUBAR_LAYERS].Height,"layer bar",0))
if (Read_GUI_block(gfx, gui, cursor_x, cursor_y, gfx->Layerbar_block[0], 144, 10,"layer bar",0))
return 1;
cursor_y+= Menu_bars[MENUBAR_LAYERS].Height;
cursor_y+= 10;
// Animbar
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "anim bar"))
return 1;
if (Read_GUI_block(gfx, gui, cursor_x, cursor_y, gfx->Animbar_block[0], 236, 14,"anim bar",0))
return 1;
cursor_y+= 14;
// Status bar
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "status bar"))
@ -395,9 +402,16 @@ byte Parse_skin(SDL_Surface * gui, T_Gui_skin *gfx)
// Layerbar (selected)
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "selected layer bar"))
return 1;
if (Read_GUI_block(gfx, gui, cursor_x, cursor_y, gfx->Layerbar_block[1], Menu_bars[MENUBAR_LAYERS].Skin_width, Menu_bars[MENUBAR_LAYERS].Height,"selected layer bar",0))
if (Read_GUI_block(gfx, gui, cursor_x, cursor_y, gfx->Layerbar_block[1], 144, 10,"selected layer bar",0))
return 1;
cursor_y+= Menu_bars[MENUBAR_LAYERS].Height;
cursor_y+= 10;
// Animbar (selected)
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "selected anim bar"))
return 1;
if (Read_GUI_block(gfx, gui, cursor_x, cursor_y, gfx->Animbar_block[1], 236, 14,"selected anim bar",0))
return 1;
cursor_y+= 14;
// Status bar (selected)
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "selected status bar"))
@ -635,7 +649,9 @@ byte Parse_skin(SDL_Surface * gui, T_Gui_skin *gfx)
memcpy(gfx->Menu_block[2], gfx->Menu_block[0],
Menu_bars[MENUBAR_TOOLS].Skin_width*Menu_bars[MENUBAR_TOOLS].Height);
memcpy(gfx->Layerbar_block[2], gfx->Layerbar_block[0],
Menu_bars[MENUBAR_LAYERS].Skin_width*Menu_bars[MENUBAR_LAYERS].Height);
sizeof(gfx->Layerbar_block[0]));
memcpy(gfx->Animbar_block[2], gfx->Animbar_block[0],
sizeof(gfx->Animbar_block[0]));
memcpy(gfx->Statusbar_block[2], gfx->Statusbar_block[0],
Menu_bars[MENUBAR_STATUS].Skin_width*Menu_bars[MENUBAR_STATUS].Height);
@ -1146,6 +1162,7 @@ void Init_buttons(void)
FAMILY_INSTANT);
// Layer bar
#ifndef NOLAYERS
Init_button(BUTTON_LAYER_MENU,
0,0,
57,9,
@ -1210,6 +1227,89 @@ void Init_buttons(void)
0,0,
Do_nothing,
FAMILY_INSTANT);
#else
// Anim bar
Init_button(BUTTON_LAYER_MENU,
0,0,
44,13,
BUTTON_SHAPE_RECTANGLE,
Button_Layer_menu, Button_Layer_menu,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_ANIM_TIME,
45,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Anim_time, Button_Anim_time,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_ANIM_FIRST_FRAME,
116,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Anim_first_frame, Button_Anim_first_frame,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_ANIM_PREV_FRAME,
130,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Anim_prev_frame, Button_Anim_continuous_prev,
0,1,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_ANIM_NEXT_FRAME,
144,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Anim_next_frame, Button_Anim_continuous_next,
0,1,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_ANIM_LAST_FRAME,
158,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Anim_last_frame, Button_Anim_last_frame,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_LAYER_ADD,
177,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Layer_add, Button_Layer_add,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_LAYER_REMOVE,
191,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Layer_remove, Button_Layer_remove,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_LAYER_DOWN,
205,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Layer_down, Button_Layer_down,
0,0,
Do_nothing,
FAMILY_INSTANT);
Init_button(BUTTON_LAYER_UP,
219,0,
13,13,
BUTTON_SHAPE_RECTANGLE,
Button_Layer_up, Button_Layer_up,
0,0,
Do_nothing,
FAMILY_INSTANT);
#endif
// Status bar
Init_button(BUTTON_HIDE,
0,0,
@ -2695,7 +2795,11 @@ void Set_current_skin(const char *skinfile, T_Gui_skin *gfx)
for (i=0; i<3; i++)
{
Menu_bars[MENUBAR_TOOLS ].Skin[i] = (byte*)&(gfx->Menu_block[i]);
#ifndef NOLAYERS
Menu_bars[MENUBAR_LAYERS].Skin[i] = (byte*)&(gfx->Layerbar_block[i]);
#else
Menu_bars[MENUBAR_LAYERS].Skin[i] = (byte*)&(gfx->Animbar_block[i]);
#endif
Menu_bars[MENUBAR_STATUS].Skin[i] = (byte*)&(gfx->Statusbar_block[i]);
}
}

View File

@ -29,8 +29,9 @@
#include "input.h"
#include "help.h"
#include "misc.h"
#include "readline.h"
void Layer_activate(byte layer, short side)
void Layer_activate(int layer, short side)
{
word old_layers;
@ -103,8 +104,18 @@ void Button_Layer_add(void)
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
Display_layerbar();
End_of_modification();
}
@ -154,7 +165,7 @@ void Button_Layer_select(void)
void Button_Layer_toggle(void)
{
short layer;
int layer;
// Determine which button is clicked according to mouse position
layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width)
/ Layer_button_width;
@ -318,7 +329,7 @@ void Button_Layer_up(void)
if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
{
byte * tmp;
T_Image tmp;
dword layer_flags;
// Backup with unchanged layers
@ -357,7 +368,7 @@ void Button_Layer_down(void)
if (Main_current_layer > 0)
{
byte * tmp;
T_Image tmp;
dword layer_flags;
// Backup with unchanged layers
@ -389,3 +400,250 @@ void Button_Layer_down(void)
Unselect_button(BUTTON_LAYER_DOWN);
Display_cursor();
}
int Interpret_delay(int delay)
{
// Firefox behavior
if (delay>30)
return delay;
if (delay==0)
return 100;
return 30;
}
void Button_Anim_time(void)
{
short clicked_button;
int mode=0;
int frame;
char buffer[5+1];
T_Special_button * input_duration_button;
int duration=Main_backups->Pages->Image[Main_current_layer].Duration;
Open_window(166,110,"Animation speed");
Print_in_window(80,20,"ms",MC_Black,MC_Light);
input_duration_button = Window_set_input_button(33,18,5); // 1
Num2str(duration,buffer,5);
Print_in_window_limited(input_duration_button->Pos_X+2,input_duration_button->Pos_Y+2,buffer,input_duration_button->Width/8,MC_Black,MC_Light);
Print_in_window(24,37,"Set this frame",MC_Black,MC_Light);
Window_set_normal_button(7, 34, 13,13,"X" , 0,1,KEY_NONE); // 2
Print_in_window(24,55,"Set all frames",MC_Black,MC_Light);
Window_set_normal_button(7, 52, 13,13,"" , 0,1,KEY_NONE); // 3
Print_in_window(24,73,"Add to all frames",MC_Black,MC_Light);
Window_set_normal_button(7, 70, 13,13,"" , 0,1,KEY_NONE); // 4
Window_set_normal_button( 7, 92, 51,14,"OK" , 0,1,SDLK_RETURN); // 5
Window_set_normal_button(63, 92, 51,14,"Cancel", 0,1,KEY_ESC); // 6
Update_window_area(0,0,Window_width, Window_height);
do
{
clicked_button=Window_clicked_button();
if (Is_shortcut(Key,0x100+BUTTON_HELP))
Window_help(BUTTON_ANIM_TIME, NULL);
switch(clicked_button)
{
case 1: // duration
Num2str(duration,buffer,5);
Hide_cursor();
if (Readline(input_duration_button->Pos_X+2,
input_duration_button->Pos_Y+2,
buffer,
5,
INPUT_TYPE_DECIMAL))
{
duration=atoi(buffer);
}
Print_in_window_limited(input_duration_button->Pos_X+2,input_duration_button->Pos_Y+2,buffer,input_duration_button->Width/8,MC_Black,MC_Light);
Display_cursor();
break;
case 2: // Radio: set 1
case 3: // Radio: set all
case 4: // Radio: add
mode=clicked_button-2;
Hide_cursor();
Print_in_window(10,37,mode==0?"X":" ",MC_Black,MC_Light);
Print_in_window(10,55,mode==1?"X":" ",MC_Black,MC_Light);
Print_in_window(10,73,mode==2?"X":" ",MC_Black,MC_Light);
Display_cursor();
break;
}
}
while (clicked_button<5);
// On exit
Hide_cursor();
Close_window();
if (clicked_button==5)
{
// Accept changes
Backup_layers(0);
switch(mode)
{
case 0:
if (duration<1)
duration=1;
Main_backups->Pages->Image[Main_current_layer].Duration = duration;
break;
case 1:
if (duration<1)
duration=1;
for (frame=0; frame<Main_backups->Pages->Nb_layers; frame++)
{
Main_backups->Pages->Image[frame].Duration = duration;
}
break;
case 2:
for (frame=0; frame<Main_backups->Pages->Nb_layers; frame++)
{
int cur_duration = Main_backups->Pages->Image[frame].Duration+duration;
if (cur_duration<1)
cur_duration=1;
else if (cur_duration>32767)
cur_duration=32767;
Main_backups->Pages->Image[frame].Duration = cur_duration;
}
break;
break;
}
End_of_modification();
}
Unselect_button(BUTTON_ANIM_TIME);
Display_cursor();
}
void Button_Anim_first_frame(void)
{
if (Main_current_layer>0)
Layer_activate(0,LEFT_SIDE);
Hide_cursor();
Unselect_button(BUTTON_ANIM_FIRST_FRAME);
Display_cursor();
}
void Button_Anim_prev_frame(void)
{
if (Main_backups->Pages->Nb_layers>1)
{
if (Main_current_layer==0)
Layer_activate(Main_backups->Pages->Nb_layers-1,LEFT_SIDE);
else
Layer_activate(Main_current_layer-1,LEFT_SIDE);
}
Hide_cursor();
Unselect_button(BUTTON_ANIM_PREV_FRAME);
Display_cursor();
}
void Button_Anim_next_frame(void)
{
if (Main_backups->Pages->Nb_layers>1)
{
if (Main_current_layer==Main_backups->Pages->Nb_layers-1)
Layer_activate(0,LEFT_SIDE);
else
Layer_activate(Main_current_layer+1,LEFT_SIDE);
}
Hide_cursor();
Unselect_button(BUTTON_ANIM_NEXT_FRAME);
Display_cursor();
}
void Button_Anim_last_frame(void)
{
if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
Layer_activate((Main_backups->Pages->Nb_layers-1),LEFT_SIDE);
Hide_cursor();
Unselect_button(BUTTON_ANIM_LAST_FRAME);
Display_cursor();
}
void Button_Anim_play(void)
{
Hide_cursor();
//
Unselect_button(BUTTON_ANIM_PLAY);
Display_cursor();
}
void Button_Anim_continuous_next(void)
{
Uint32 time_start;
int time_in_current_frame=0;
time_start = SDL_GetTicks();
do
{
int target_frame;
Uint32 time_now;
Get_input(20);
time_now=SDL_GetTicks();
time_in_current_frame += time_now-time_start;
time_start=time_now;
target_frame = Main_current_layer;
while (time_in_current_frame > Main_backups->Pages->Image[target_frame].Duration)
{
time_in_current_frame -= Interpret_delay(Main_backups->Pages->Image[target_frame].Duration);
target_frame = (target_frame+1) % Main_backups->Pages->Nb_layers;
}
if (target_frame != Main_current_layer)
{
Layer_activate(target_frame,LEFT_SIDE);
}
} while (Mouse_K);
Hide_cursor();
Unselect_button(BUTTON_ANIM_NEXT_FRAME);
Display_cursor();
}
void Button_Anim_continuous_prev(void)
{
Uint32 time_start;
int time_in_current_frame=0;
time_start = SDL_GetTicks();
do
{
int target_frame;
Uint32 time_now;
Get_input(20);
time_now=SDL_GetTicks();
time_in_current_frame += time_now-time_start;
time_start=time_now;
target_frame = Main_current_layer;
while (time_in_current_frame > Main_backups->Pages->Image[target_frame].Duration)
{
time_in_current_frame -= Interpret_delay(Main_backups->Pages->Image[target_frame].Duration);
target_frame = (target_frame+Main_backups->Pages->Nb_layers-1) % Main_backups->Pages->Nb_layers;
}
if (target_frame != Main_current_layer)
{
Layer_activate(target_frame,LEFT_SIDE);
}
} while (Mouse_K);
Hide_cursor();
Unselect_button(BUTTON_ANIM_NEXT_FRAME);
Display_cursor();
}

View File

@ -30,6 +30,12 @@ void Button_Layer_up(void);
void Button_Layer_down(void);
void Button_Layer_select(void);
void Button_Layer_toggle(void);
void Layer_activate(byte layer, short side);
void Layer_activate(int layer, short side);
void Button_Anim_time(void);
void Button_Anim_first_frame(void);
void Button_Anim_prev_frame(void);
void Button_Anim_next_frame(void);
void Button_Anim_last_frame(void);
void Button_Anim_play(void);
void Button_Anim_continuous_prev(void);
void Button_Anim_continuous_next(void);

View File

@ -321,6 +321,29 @@ void Set_palette_fake_24b(T_Palette palette)
}
}
void Set_frame_duration(T_IO_Context *context, int duration)
{
switch(context->Type)
{
case CONTEXT_MAIN_IMAGE:
Main_backups->Pages->Image[context->Current_layer].Duration = duration;
break;
default:
break;
}
}
int Get_frame_duration(T_IO_Context *context)
{
switch(context->Type)
{
case CONTEXT_MAIN_IMAGE:
return Main_backups->Pages->Image[context->Current_layer].Duration;
default:
return 0;
}
}
///
/// Generic allocation and similar stuff, done at beginning of image load,
/// as soon as size is known.
@ -644,7 +667,7 @@ void Load_image(T_IO_Context *context)
Cursor_shape=CURSOR_SHAPE_HOURGLASS;
Display_cursor();
Flush_update();
if (Convert_24b_bitmap_to_256(Main_backups->Pages->Image[0],context->Buffer_image_24b,context->Width,context->Height,context->Palette))
if (Convert_24b_bitmap_to_256(Main_backups->Pages->Image[0].Pixels,context->Buffer_image_24b,context->Width,context->Height,context->Palette))
File_error=2;
else
{
@ -1213,7 +1236,7 @@ void Init_context_layered_image(T_IO_Context * context, char *file_name, char *f
context->Ratio=PIXEL_TALL;
else
context->Ratio=PIXEL_SIMPLE;
context->Target_address=Main_backups->Pages->Image[0];
context->Target_address=Main_backups->Pages->Image[0].Pixels;
context->Pitch=Main_image_width;
// Color cyling ranges:
@ -1280,18 +1303,18 @@ void Init_context_surface(T_IO_Context * context, char *file_name, char *file_di
}
/// Function to call when need to switch layers.
void Set_saving_layer(T_IO_Context *context, byte layer)
void Set_saving_layer(T_IO_Context *context, int layer)
{
context->Current_layer = layer;
if (context->Type == CONTEXT_MAIN_IMAGE)
{
context->Target_address=Main_backups->Pages->Image[layer];
context->Target_address=Main_backups->Pages->Image[layer].Pixels;
}
}
/// Function to call when need to switch layers.
void Set_loading_layer(T_IO_Context *context, byte layer)
void Set_loading_layer(T_IO_Context *context, int layer)
{
context->Current_layer = layer;
@ -1311,7 +1334,7 @@ void Set_loading_layer(T_IO_Context *context, byte layer)
Main_layers_visible = (2<<layer)-1;
}
Main_current_layer = layer;
context->Target_address=Main_backups->Pages->Image[layer];
context->Target_address=Main_backups->Pages->Image[layer].Pixels;
}
}

View File

@ -62,7 +62,7 @@ typedef struct
T_Palette Palette;
short Width;
short Height;
byte Nb_layers;
int Nb_layers;
char Comment[COMMENT_SIZE+1];
byte Background_transparent;
byte Transparent_color;
@ -83,7 +83,7 @@ typedef struct
T_Color_cycle Cycle_range[16];
/// Internal: during load, marks which layer is being loaded.
short Current_layer;
int Current_layer;
/// Internal: Used to mark truecolor images on loading. Only used by preview.
//byte Is_truecolor;
@ -215,10 +215,13 @@ void Set_pixel(T_IO_Context *context, short x, short y, byte c);
/// Set the color of a 24bit pixel (on load)
void Set_pixel_24b(T_IO_Context *context, short x, short y, byte r, byte g, byte b);
/// Function to call when need to switch layers.
void Set_loading_layer(T_IO_Context *context, byte layer);
void Set_loading_layer(T_IO_Context *context, int layer);
/// Function to call when need to switch layers.
void Set_saving_layer(T_IO_Context *context, byte layer);
void Set_saving_layer(T_IO_Context *context, int layer);
/// Function to call when loading an image's duration
void Set_frame_duration(T_IO_Context *context, int duration);
/// Function to call to get an image's duration for saving
int Get_frame_duration(T_IO_Context *context);
// =================================================================
// What follows here are the definitions of functions and data

View File

@ -61,7 +61,7 @@ word Count_used_colors(dword* usage)
// For each layer
for (layer = 0; layer < Main_backups->Pages->Nb_layers; layer++)
{
current_pixel = Main_backups->Pages->Image[layer];
current_pixel = Main_backups->Pages->Image[layer].Pixels;
// For each pixel in picture
for (i = 0; i < nb_pixels; i++)
{
@ -188,7 +188,7 @@ void Clear_current_image_with_stencil(byte color, byte * stencil)
int nb_pixels=0; //ECX
//al=color
//edi=Screen_pixels
byte* pixel=Main_backups->Pages->Image[Main_current_layer];
byte* pixel=Main_backups->Pages->Image[Main_current_layer].Pixels;
int i;
nb_pixels=Main_image_height*Main_image_width;
@ -205,7 +205,7 @@ void Clear_current_image(byte color)
// Effacer l'image courante avec une certaine couleur
{
memset(
Main_backups->Pages->Image[Main_current_layer],
Main_backups->Pages->Image[Main_current_layer].Pixels,
color ,
Main_image_width * Main_image_height
);
@ -306,7 +306,7 @@ byte Read_pixel_from_spare_screen(word x,word y)
#ifndef NOLAYERS
return *(Spare_visible_image.Image + y*Spare_image_width + x);
#else
return *(Spare_backups->Pages->Image[Spare_current_layer] + y*Spare_image_width + x);
return *(Spare_backups->Pages->Image[Spare_current_layer].Pixels + y*Spare_image_width + x);
#endif
}
@ -362,7 +362,7 @@ void Remap_general_lowlevel(byte * conversion_table,byte * in_buffer, byte *out_
void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width)
{
byte* src=start_y*image_width+start_x+Main_backups->Pages->Image[Main_current_layer]; //Adr départ image (ESI)
byte* src=start_y*image_width+start_x+Main_backups->Pages->Image[Main_current_layer].Pixels; //Adr départ image (ESI)
byte* dest=Brush_original_pixels; //Adr dest brosse (EDI)
int dx;
@ -407,7 +407,7 @@ void Replace_colors_within_limits(byte * replace_table)
// Pour chaque pixel sur la ligne :
for (x = Limit_left;x <= Limit_right;x ++)
{
pixel = Main_backups->Pages->Image[Main_current_layer]+y*Main_image_width+x;
pixel = Main_backups->Pages->Image[Main_current_layer].Pixels+y*Main_image_width+x;
*pixel = replace_table[*pixel];
}
}

View File

@ -33,7 +33,7 @@
void Pixel_in_layer(word x,word y, byte layer, byte color)
{
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer])=color;
*((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer].Pixels)=color;
}
byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
@ -73,7 +73,7 @@ byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
{
for (x=0;x<4;x++)
{
byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2]);
byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
used_colors[row][col] |= 1<<c;
}
}
@ -81,7 +81,7 @@ byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
// Get "mandatory colors" from layer 1
for (row=0;row<200;row++)
{
byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0]);
byte c=*((row)*Main_image_width+0+Main_backups->Pages->Image[0].Pixels);
if (c<16)
{
line_color[row]=c;
@ -97,7 +97,7 @@ byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
{
for (col=0;col<40;col++)
{
byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1]);
byte c=*((row)*Main_image_width+(col*4)+Main_backups->Pages->Image[1].Pixels);
if (c<16)
{
block_color[row/8][col]=c;
@ -309,7 +309,7 @@ byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background)
for(x=0; x<4; x++)
{
byte bits;
byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2]);
byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2].Pixels);
if (c==line_color[row*8+y])
// BG color

View File

@ -2841,7 +2841,7 @@ void Scroll_12_5(void)
else
{
// One layer at once
Scroll_picture(Main_backups->Pages->Next->Image[Main_current_layer], Main_backups->Pages->Image[Main_current_layer], x_offset, y_offset);
Scroll_picture(Main_backups->Pages->Next->Image[Main_current_layer].Pixels, Main_backups->Pages->Image[Main_current_layer].Pixels, x_offset, y_offset);
Redraw_current_layer();
}
@ -2898,7 +2898,7 @@ void Scroll_0_5(void)
// Do the actual scroll operation on all layers.
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
//if ((1<<i) & Main_layers_visible)
Scroll_picture(Main_backups->Pages->Next->Image[i], Main_backups->Pages->Image[i], x_offset, y_offset);
Scroll_picture(Main_backups->Pages->Next->Image[i].Pixels, Main_backups->Pages->Image[i].Pixels, x_offset, y_offset);
// Update the depth buffer too ...
// It would be faster to scroll it, but we don't have method
// for in-place scrolling.

View File

@ -57,16 +57,19 @@ long Stats_pages_number=0;
long long Stats_pages_memory=0;
/// Allocate and initialize a new page.
T_Page * New_page(byte nb_layers)
T_Page * New_page(int nb_layers)
{
T_Page * page;
page = (T_Page *)malloc(sizeof(T_Page)+nb_layers*sizeof(byte *));
page = (T_Page *)malloc(sizeof(T_Page)+nb_layers*sizeof(T_Image));
if (page!=NULL)
{
int i;
for (i=0; i<nb_layers; i++)
page->Image[i]=NULL;
{
page->Image[i].Pixels=NULL;
page->Image[i].Duration=1;
}
page->Width=0;
page->Height=0;
memset(page->Palette,0,sizeof(T_Palette));
@ -110,13 +113,13 @@ byte * New_layer(long pixel_size)
}
/// Free a layer
void Free_layer(T_Page * page, byte layer)
void Free_layer(T_Page * page, int layer)
{
short * ptr;
if (page->Image[layer]==NULL)
if (page->Image[layer].Pixels==NULL)
return;
ptr = (short *)(page->Image[layer]);
ptr = (short *)(page->Image[layer].Pixels);
if (-- (*(ptr-1))) // Users--
return;
else {
@ -189,7 +192,7 @@ void Download_infos_page_main(T_Page * page)
}
//Update_buffers( page->Width, page->Height);
//memcpy(Main_screen, page->Image[Main_current_layer], page->Width*page->Height);
//memcpy(Main_screen, page->Image[Main_current_layer].Pixels, page->Width*page->Height);
}
@ -206,13 +209,13 @@ void Redraw_layered_image(void)
int i;
for (i=0; i< Main_image_width*Main_image_height; i++)
{
layer = *(Main_backups->Pages->Image[4]+i);
Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer]+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],
Main_backups->Pages->Image[4].Pixels,
Main_image_width*Main_image_height);
// Next
@ -226,7 +229,7 @@ void Redraw_layered_image(void)
{
// Copy it in Main_visible_image
memcpy(Main_visible_image.Image,
Main_backups->Pages->Image[layer],
Main_backups->Pages->Image[layer].Pixels,
Main_image_width*Main_image_height);
// Initialize the depth buffer
@ -248,7 +251,7 @@ void Redraw_layered_image(void)
int i;
for (i=0; i<Main_image_width*Main_image_height; i++)
{
byte color = *(Main_backups->Pages->Image[layer]+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;
@ -299,7 +302,7 @@ void Update_depth_buffer(void)
int i;
for (i=0; i<Main_image_width*Main_image_height; i++)
{
byte color = *(Main_backups->Pages->Image[layer]+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;
@ -323,7 +326,7 @@ void Redraw_spare_image(void)
{
// Copy it in Spare_visible_image
memcpy(Spare_visible_image.Image,
Spare_backups->Pages->Image[layer],
Spare_backups->Pages->Image[layer].Pixels,
Spare_image_width*Spare_image_height);
// No depth buffer in the spare
@ -344,7 +347,7 @@ void Redraw_spare_image(void)
int i;
for (i=0; i<Spare_image_width*Spare_image_height; i++)
{
byte color = *(Spare_backups->Pages->Image[layer]+i);
byte color = *(Spare_backups->Pages->Image[layer].Pixels+i);
if (color != Spare_backups->Pages->Transparent_color) // transparent color
{
*(Spare_visible_image.Image+i) = color;
@ -366,14 +369,14 @@ void Redraw_current_layer(void)
byte depth = *(Main_visible_image_depth_buffer.Image+i);
if (depth<=Main_current_layer)
{
byte color = *(Main_backups->Pages->Image[Main_current_layer]+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]+i);
*(Main_visible_image.Image+i) = *(Main_backups->Pages->Image[depth].Pixels+i);
}
}
}
@ -385,7 +388,7 @@ void Upload_infos_page_main(T_Page * page)
{
if (page!=NULL)
{
//page->Image[Main_current_layer]=Main_screen;
//page->Image[Main_current_layer].Pixels=Main_screen;
page->Width=Main_image_width;
page->Height=Main_image_height;
memcpy(page->Palette,Main_palette,sizeof(T_Palette));
@ -409,7 +412,7 @@ void Upload_infos_page_spare(T_Page * page)
{
if (page!=NULL)
{
//page->Image[Spare_current_layer]=Spare_screen;
//page->Image[Spare_current_layer].Pixels=Spare_screen;
page->Width=Spare_image_width;
page->Height=Spare_image_height;
memcpy(page->Palette,Spare_palette,sizeof(T_Palette));
@ -423,9 +426,9 @@ void Update_FX_feedback(byte with_feedback)
{
if (with_feedback)
FX_feedback_screen=Main_backups->Pages->Image[Main_current_layer];
FX_feedback_screen=Main_backups->Pages->Image[Main_current_layer].Pixels;
else
FX_feedback_screen=Main_backups->Pages->Next->Image[Main_current_layer];
FX_feedback_screen=Main_backups->Pages->Next->Image[Main_current_layer].Pixels;
}
void Clear_page(T_Page * page)
@ -435,7 +438,8 @@ void Clear_page(T_Page * page)
for (i=0; i<page->Nb_layers; i++)
{
Free_layer(page, i);
page->Image[i]=NULL;
page->Image[i].Pixels=NULL;
page->Image[i].Duration=1;
}
// Free_gradient() : This data is reference-counted
@ -621,9 +625,10 @@ int Create_new_page(T_Page * new_page, T_List_of_pages * list, dword layer_mask)
for (i=0; i<new_page->Nb_layers; i++)
{
if ((1<<i) & layer_mask)
new_page->Image[i]=New_layer(new_page->Height*new_page->Width);
new_page->Image[i].Pixels=New_layer(new_page->Height*new_page->Width);
else
new_page->Image[i]=Dup_layer(list->Pages->Image[i]);
new_page->Image[i].Pixels=Dup_layer(list->Pages->Image[i].Pixels);
new_page->Image[i].Duration=list->Pages->Image[i].Duration;
}
}
@ -669,8 +674,8 @@ void Update_screen_targets(void)
Main_screen=Main_visible_image.Image;
Screen_backup=Main_visible_image_backup.Image;
#else
Main_screen=Main_backups->Pages->Image[Main_current_layer];
Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer];
Main_screen=Main_backups->Pages->Image[Main_current_layer].Pixels;
Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer].Pixels;
#endif
}
@ -762,10 +767,10 @@ int Init_all_backup_lists(int width,int height)
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Main_backups->Pages->Image[i]=New_layer(width*height);
if (! Main_backups->Pages->Image[i])
Main_backups->Pages->Image[i].Pixels=New_layer(width*height);
if (! Main_backups->Pages->Image[i].Pixels)
return 0;
memset(Main_backups->Pages->Image[i], 0, width*height);
memset(Main_backups->Pages->Image[i].Pixels, 0, width*height);
}
#ifndef NOLAYERS
Main_visible_image.Width = 0;
@ -811,10 +816,10 @@ int Init_all_backup_lists(int width,int height)
// Spare
for (i=0; i<NB_LAYERS; i++)
{
Spare_backups->Pages->Image[i]=New_layer(width*height);
if (! Spare_backups->Pages->Image[i])
Spare_backups->Pages->Image[i].Pixels=New_layer(width*height);
if (! Spare_backups->Pages->Image[i].Pixels)
return 0;
memset(Spare_backups->Pages->Image[i], 0, width*height);
memset(Spare_backups->Pages->Image[i].Pixels, 0, width*height);
}
//memset(Spare_screen,0,Spare_image_width*Spare_image_height);
@ -833,7 +838,7 @@ void Set_number_of_backups(int nb_backups)
// (nb_backups = Nombre de backups, sans compter les pages courantes)
}
int Backup_new_image(byte layers,int width,int height)
int Backup_new_image(int layers,int width,int height)
{
// Retourne 1 si une nouvelle page est disponible et 0 sinon
T_Page * new_page;
@ -900,7 +905,7 @@ int Backup_with_new_dimensions(int width,int height)
// Fill with transparent color
for (i=0; i<Main_backups->Pages->Nb_layers;i++)
{
memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
memset(Main_backups->Pages->Image[i].Pixels, Main_backups->Pages->Transparent_color, width*height);
}
Update_buffers(width, height);
@ -959,10 +964,10 @@ int Backup_in_place(int width,int height)
{
// Replace layers
Free_layer(Main_backups->Pages,i);
Main_backups->Pages->Image[i]=new_layer[i];
Main_backups->Pages->Image[i].Pixels=new_layer[i];
// Fill with transparency
memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
memset(Main_backups->Pages->Image[i].Pixels, Main_backups->Pages->Transparent_color, width*height);
}
Main_backups->Pages->Width=width;
@ -1009,7 +1014,7 @@ int Backup_and_resize_the_spare(int width,int height)
T_Page * new_page;
int return_code=0;
byte nb_layers;
int nb_layers;
nb_layers=Spare_backups->Pages->Nb_layers;
// On crée un descripteur pour la nouvelle page de brouillon
@ -1032,7 +1037,7 @@ int Backup_and_resize_the_spare(int width,int height)
for (i=0; i<nb_layers;i++)
{
memset(Spare_backups->Pages->Image[i], Spare_backups->Pages->Transparent_color, width*height);
memset(Spare_backups->Pages->Image[i].Pixels, Spare_backups->Pages->Transparent_color, width*height);
}
// Update_buffers(width, height); // Not for spare
@ -1088,8 +1093,8 @@ void Backup_layers(dword layer_mask)
for (i=0; i<Main_backups->Pages->Nb_layers;i++)
{
if ((1<<i) & layer_mask)
memcpy(Main_backups->Pages->Image[i],
Main_backups->Pages->Next->Image[i],
memcpy(Main_backups->Pages->Image[i].Pixels,
Main_backups->Pages->Next->Image[i].Pixels,
Main_image_width*Main_image_height);
}
// Light up the 'has unsaved changes' indicator
@ -1122,8 +1127,8 @@ void Backup_the_spare(dword layer_mask)
for (i=0; i<Spare_backups->Pages->Nb_layers;i++)
{
if ((1<<i) & layer_mask)
memcpy(Spare_backups->Pages->Image[i],
Spare_backups->Pages->Next->Image[i],
memcpy(Spare_backups->Pages->Image[i].Pixels,
Spare_backups->Pages->Next->Image[i].Pixels,
Spare_image_width*Spare_image_height);
}
// Light up the 'has unsaved changes' indicator
@ -1277,7 +1282,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, byte layer)
byte Add_layer(T_List_of_pages *list, int layer)
{
T_Page * source_page;
T_Page * new_page;
@ -1301,7 +1306,7 @@ byte Add_layer(T_List_of_pages *list, byte layer)
return 1;
}
// Re-allocate the page itself, with room for one more pointer
new_page = realloc(source_page, sizeof(T_Page)+(list->Pages->Nb_layers+1)*sizeof(byte *));
new_page = realloc(source_page, sizeof(T_Page)+(list->Pages->Nb_layers+1)*sizeof(T_Image));
if (!new_page)
{
Error(0);
@ -1322,7 +1327,8 @@ byte Add_layer(T_List_of_pages *list, byte layer)
{
new_page->Image[i]=new_page->Image[i-1];
}
new_page->Image[layer]=new_image;
new_page->Image[layer].Pixels=new_image;
new_page->Image[layer].Duration=1;
// Fill with transparency, initially
memset(new_image, Main_backups->Pages->Transparent_color, list->Pages->Height*list->Pages->Width); // transparent color
@ -1359,7 +1365,7 @@ byte Add_layer(T_List_of_pages *list, byte layer)
}
/// Delete a layer from the latest page of a list. Returns 0 on success.
byte Delete_layer(T_List_of_pages *list, byte layer)
byte Delete_layer(T_List_of_pages *list, int layer)
{
T_Page * page;
int i;
@ -1432,9 +1438,9 @@ byte Merge_layer()
int i;
for (i=0; i<Main_image_width*Main_image_height; i++)
{
byte color = *(Main_backups->Pages->Image[Main_current_layer]+i);
byte color = *(Main_backups->Pages->Image[Main_current_layer].Pixels+i);
if (color != Main_backups->Pages->Transparent_color) // transparent color
*(Main_backups->Pages->Image[Main_current_layer-1]+i) = color;
*(Main_backups->Pages->Image[Main_current_layer-1].Pixels+i) = color;
}
return Delete_layer(Main_backups,Main_current_layer);
}

View File

@ -58,14 +58,14 @@ extern T_Bitmap Spare_visible_image;
void Download_infos_page_main(T_Page * page);
void Upload_infos_page_main(T_Page * page);
/// Add a new layer to latest page of a list. Returns 0 on success.
byte Add_layer(T_List_of_pages *list, byte layer);
byte Add_layer(T_List_of_pages *list, int layer);
/// Delete a layer from the latest page of a list. Returns 0 on success.
byte Delete_layer(T_List_of_pages *list, byte layer);
byte Delete_layer(T_List_of_pages *list, int layer);
/// Merges the current layer onto the one below it.
byte Merge_layer();
// private
T_Page * New_page(byte nb_layers);
T_Page * New_page(int nb_layers);
void Download_infos_page_spare(T_Page * page);
void Upload_infos_page_spare(T_Page * page);
void Clear_page(T_Page * page);
@ -95,7 +95,7 @@ void Free_page_of_a_list(T_List_of_pages * list);
int Init_all_backup_lists(int width,int height);
void Set_number_of_backups(int nb_backups);
int Backup_new_image(byte layers,int width,int height);
int Backup_new_image(int layers,int width,int height);
int Backup_with_new_dimensions(int width,int height);
///
/// Resizes a backup step in-place (doesn't add a Undo/Redo step).

View File

@ -315,7 +315,7 @@ void Remap_image_highlevel(byte * conversion_table)
// Remap all layers
for (layer=0; layer<Main_backups->Pages->Nb_layers; layer++)
Remap_general_lowlevel(conversion_table,Main_backups->Pages->Image[layer],Main_backups->Pages->Image[layer],Main_image_width,Main_image_height,Main_image_width);
Remap_general_lowlevel(conversion_table,Main_backups->Pages->Image[layer].Pixels,Main_backups->Pages->Image[layer].Pixels,Main_image_width,Main_image_height,Main_image_width);
// Remap transparent color
Main_backups->Pages->Transparent_color =

View File

@ -379,6 +379,12 @@ typedef struct
// Ces structures sont manipulées à travers des fonctions de gestion du
// backup dans "graph.c".
typedef struct T_Image
{
byte * Pixels;
int Duration;
} T_Image;
/// This is the data for one step of Undo/Redo, for one image.
/// This structure is resized dynamically to hold pointers to all of the layers in the picture.
/// The pointed layers are just byte* holding the raw pixel data. But at Image[0]-1 you will find a short that is used as a reference counter for each layer.
@ -399,12 +405,12 @@ typedef struct T_Page
T_Gradient_array *Gradients; ///< Pointer to the gradients used by the image.
byte Background_transparent; ///< Boolean, true if Layer 0 should have transparent pixels
byte Transparent_color; ///< Index of transparent color. 0 to 255.
byte Nb_layers; ///< Number of layers
int Nb_layers; ///< Number of layers
#if __GNUC__ < 3
// gcc2 doesn't suport [], but supports [0] which does the same thing.
byte * Image[0]; ///< Pixel data for the (first layer of) image.
T_Image Image[0]; ///< Pixel data for the (first layer of) image.
#else
byte * Image[]; ///< Pixel data for the (first layer of) image.
T_Image Image[]; ///< Pixel data for the (first layer of) image.
#endif
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.
} T_Page;
@ -461,6 +467,7 @@ typedef struct
/// Bitmap data for the menu, a single rectangle.
byte Menu_block[3][35][MENU_WIDTH];
byte Layerbar_block[3][10][144];
byte Animbar_block[3][14][236];
byte Statusbar_block[3][9][20];
/// Bitmap data for the icons that are displayed over the menu.
byte Menu_sprite[2][NB_MENU_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH];

View File

@ -385,40 +385,40 @@ void Button_Transform_menu(void)
case 2 : // Flip X
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
memcpy(Main_backups->Pages->Image[i],Main_backups->Pages->Next->Image[i],Main_image_width*Main_image_height);
Flip_X_lowlevel(Main_backups->Pages->Image[i], Main_image_width, Main_image_height);
memcpy(Main_backups->Pages->Image[i].Pixels,Main_backups->Pages->Next->Image[i].Pixels,Main_image_width*Main_image_height);
Flip_X_lowlevel(Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height);
}
break;
case 3 : // Flip Y
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
memcpy(Main_backups->Pages->Image[i],Main_backups->Pages->Next->Image[i],Main_image_width*Main_image_height);
Flip_Y_lowlevel(Main_backups->Pages->Image[i], Main_image_width, Main_image_height);
memcpy(Main_backups->Pages->Image[i].Pixels,Main_backups->Pages->Next->Image[i].Pixels,Main_image_width*Main_image_height);
Flip_Y_lowlevel(Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height);
}
break;
case 4 : // -90° Rotation
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Rotate_270_deg_lowlevel(Main_backups->Pages->Next->Image[i], Main_backups->Pages->Image[i], old_width, old_height);
Rotate_270_deg_lowlevel(Main_backups->Pages->Next->Image[i].Pixels, Main_backups->Pages->Image[i].Pixels, old_width, old_height);
}
break;
case 5 : // +90° Rotation
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Rotate_90_deg_lowlevel(Main_backups->Pages->Next->Image[i], Main_backups->Pages->Image[i], old_width, old_height);
Rotate_90_deg_lowlevel(Main_backups->Pages->Next->Image[i].Pixels, Main_backups->Pages->Image[i].Pixels, old_width, old_height);
}
break;
case 6 : // 180° Rotation
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
memcpy(Main_backups->Pages->Image[i],Main_backups->Pages->Next->Image[i],Main_image_width*Main_image_height);
Rotate_180_deg_lowlevel(Main_backups->Pages->Image[i], Main_image_width, Main_image_height);
memcpy(Main_backups->Pages->Image[i].Pixels,Main_backups->Pages->Next->Image[i].Pixels,Main_image_width*Main_image_height);
Rotate_180_deg_lowlevel(Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height);
}
break;
case 7 : // Resize
for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{
Rescale(Main_backups->Pages->Next->Image[i], old_width, old_height, Main_backups->Pages->Image[i], Main_image_width, Main_image_height, 0, 0);
Rescale(Main_backups->Pages->Next->Image[i].Pixels, old_width, old_height, Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height, 0, 0);
}
break;
}
@ -426,9 +426,9 @@ void Button_Transform_menu(void)
for (i=0; i<NB_LAYERS; i++)
{
Copy_part_of_image_to_another(
Main_backups->Pages->Next->Image[i],0,0,Min(old_width,Main_image_width),
Main_backups->Pages->Next->Image[i].Pixels,0,0,Min(old_width,Main_image_width),
Min(old_height,Main_image_height),old_width,
Main_backups->Pages->Image[i],0,0,Main_image_width);
Main_backups->Pages->Image[i].Pixels,0,0,Main_image_width);
}
*/
Redraw_layered_image();

View File

@ -464,6 +464,7 @@ void Draw_bar_remainder(word current_menu, word x_off)
/// Display / update the layer menubar
void Display_layerbar(void)
{
#ifndef NOLAYERS
word x_off=0;
word button_width = LAYER_SPRITE_WIDTH;
word button_number = Main_backups->Pages->Nb_layers;
@ -547,6 +548,21 @@ void Display_layerbar(void)
Menu_Y+Menu_bars[MENUBAR_LAYERS].Top*Menu_factor_Y,
horiz_space*Menu_factor_X,
Menu_bars[MENUBAR_LAYERS].Height*Menu_factor_Y);
#else
char str[8];
// Rest of horizontal line
Draw_bar_remainder(MENUBAR_LAYERS, Menu_bars[MENUBAR_LAYERS].Skin_width);
// Frame# background rectangle
// Block((Menu_bars[MENUBAR_LAYERS].Skin_width)*Menu_factor_X,(0+Menu_bars[MENUBAR_LAYERS].Top)*Menu_factor_Y+Menu_Y,8*8*Menu_factor_X,8*Menu_factor_Y,MC_Light);
// Frame #/#
snprintf(str, 5, "#%3d", Main_current_layer+1);
Print_general((82)*Menu_factor_X,(Menu_bars[MENUBAR_LAYERS].Top+3)*Menu_factor_Y+Menu_Y,str,MC_Black,MC_Light);
Update_rect(
(82)*Menu_factor_X,
(Menu_bars[MENUBAR_LAYERS].Top+3)*Menu_factor_Y+Menu_Y,
4*8*Menu_factor_X,
8*Menu_factor_Y);
#endif
}
@ -3172,10 +3188,14 @@ void Remap_menu_sprites()
Remap_pixel(&Gfx->Statusbar_block[k][j][i]);
// Layer bar
for (k=0; k<3; k++)
for (j=0; j<Menu_bars[MENUBAR_LAYERS].Height; j++)
for (i=0; i<Menu_bars[MENUBAR_LAYERS].Skin_width; i++)
for (j=0; j<10; j++)
for (i=0; i<144; i++)
Remap_pixel(&Gfx->Layerbar_block[k][j][i]);
// Anim bar
for (k=0; k<3; k++)
for (j=0; j<14; j++)
for (i=0; i<236; i++)
Remap_pixel(&Gfx->Animbar_block[k][j][i]);
// Help fonts
for (k=0; k<256; k++)
for (j=0; j<8; j++)