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) if (i == Spare_current_layer)
{ {
// Copy the 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 else
{ {
// Resize the original layer // Resize the original layer
Copy_part_of_image_to_another( 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, 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. /// Character to display in menus for an ellipsis.
#define ELLIPSIS_CHARACTER '…' #define ELLIPSIS_CHARACTER '…'
#define NB_LAYERS 1 ///< Initial number of layers for a new image #define NB_LAYERS 1 ///< Initial number of layers for a new image
#ifdef NOLAYERS
#define MAX_NB_LAYERS 999 ///< Maximum number of layers that can be used in grafx2. Note that 32 is upper limit because of a few bit fields.
#else
#define MAX_NB_LAYERS 16 ///< Maximum number of layers that can be used in grafx2. Note that 32 is upper limit because of a few bit fields. #define MAX_NB_LAYERS 16 ///< Maximum number of layers that can be used in grafx2. Note that 32 is upper limit because of a few bit fields.
#endif
#define BRUSH_CONTAINER_PREVIEW_WIDTH 16 ///< Size for preview of a brush in Brush container #define BRUSH_CONTAINER_PREVIEW_WIDTH 16 ///< Size for preview of a brush in Brush container
#define BRUSH_CONTAINER_PREVIEW_HEIGHT 16 ///< Size for preview of a brush in Brush container #define BRUSH_CONTAINER_PREVIEW_HEIGHT 16 ///< Size for preview of a brush in Brush container
#define BRUSH_CONTAINER_COLUMNS 4 ///< Number of columns in the Brush container #define BRUSH_CONTAINER_COLUMNS 4 ///< Number of columns in the Brush container
@ -289,6 +293,12 @@ enum BUTTON_NUMBERS
BUTTON_LAYER_REMOVE, BUTTON_LAYER_REMOVE,
BUTTON_LAYER_UP, BUTTON_LAYER_UP,
BUTTON_LAYER_DOWN, 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, BUTTON_LAYER_SELECT,
// Main menu // Main menu

View File

@ -79,6 +79,12 @@ char * Menu_tooltip[NB_BUTTONS]=
"Drop layer ", "Drop layer ",
"Raise layer ", "Raise layer ",
"Lower 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 ", "Layer select / toggle ",
"Paintbrush choice ", "Paintbrush choice ",
"Adjust / Transform menu ", "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++) for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{ {
Copy_part_of_image_to_another( 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, 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(); Redraw_layered_image();
@ -326,9 +326,9 @@ int L_SetSparePictureSize(lua_State* L)
for (i=0; i<Spare_backups->Pages->Nb_layers; i++) for (i=0; i<Spare_backups->Pages->Nb_layers; i++)
{ {
Copy_part_of_image_to_another( 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, 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(); Redraw_spare_image();
@ -637,7 +637,7 @@ int L_GetSpareLayerPixel(lua_State* L)
lua_pushinteger(L, Spare_backups->Pages->Transparent_color); lua_pushinteger(L, Spare_backups->Pages->Transparent_color);
return 1; 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; return 1;
} }

View File

@ -1706,18 +1706,26 @@ typedef struct
typedef struct typedef struct
{ {
// byte Block_identifier : 0x21 byte Block_identifier; // 0x21
// byte Function : 0xF9 byte Function; // 0xF9
// byte Block_size // 4 byte Block_size; // 4
byte Packed_fields; // 11100000 : Reserved byte Packed_fields; // 11100000 : Reserved
// 00011100 : Disposal method // 00011100 : Disposal method
// 00000010 : User input flag // 00000010 : User input flag
// 00000001 : Transparent flag // 00000001 : Transparent flag
word Delay_time; // Time for this frame to stay displayed word Delay_time; // Time for this frame to stay displayed
byte Transparent_color; // Which color index acts as transparent byte Transparent_color; // Which color index acts as transparent
//word Bloc_terminator; // 0x00 word Block_terminator; // 0x00
} T_GIF_GCE; // Graphic Control Extension } 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 -------------------------------- // -- Tester si un fichier est au format GIF --------------------------------
void Test_GIF(T_IO_Context * context) void Test_GIF(T_IO_Context * context)
@ -1801,8 +1809,9 @@ word GIF_get_next_code(void)
// -- Affiche un nouveau pixel -- // -- 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); Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color);
GIF_pos_X++; GIF_pos_X++;
@ -1872,7 +1881,11 @@ void Load_GIF(T_IO_Context * context)
word value_eof; // Valeur <=> End d'image word value_eof; // Valeur <=> End d'image
long file_size; long file_size;
int number_LID; // Nombre d'images trouvées dans le fichier 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 // /////////////////////////////////////////////////// FIN DES DECLARATIONS //
@ -1972,19 +1985,23 @@ void Load_GIF(T_IO_Context * context)
&& Read_word_le(GIF_file,&(GCE.Delay_time)) && Read_word_le(GIF_file,&(GCE.Delay_time))
&& Read_byte(GIF_file,&(GCE.Transparent_color))) && 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 (GCE.Packed_fields & 1)
{ {
if (number_LID == 0) if (number_LID == 0)
context->Background_transparent = 1; context->Background_transparent = 1;
context->Transparent_color= GCE.Transparent_color;
} }
else else
{ {
if (number_LID == 0) if (number_LID == 0)
context->Background_transparent = 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 else
File_error=2; File_error=2;
@ -2117,7 +2134,35 @@ void Load_GIF(T_IO_Context * context)
// Attempt to add a layer to current image // Attempt to add a layer to current image
current_layer++; current_layer++;
Set_loading_layer(context, current_layer); Set_loading_layer(context, current_layer);
#ifdef NOLAYERS
if (context->Type == CONTEXT_MAIN_IMAGE)
{
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++; number_LID++;
// lecture de 10 derniers octets // 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; special_case=alphabet_stack[alphabet_stack_pos++]=GIF_current_code;
do 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); while (alphabet_stack_pos!=0);
alphabet_prefix[alphabet_free ]=old_code; alphabet_prefix[alphabet_free ]=old_code;
@ -2222,7 +2267,7 @@ void Load_GIF(T_IO_Context * context)
alphabet_free =(1<<initial_nb_bits)+2; alphabet_free =(1<<initial_nb_bits)+2;
special_case =GIF_get_next_code(); special_case =GIF_get_next_code();
old_code =GIF_current_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 else
@ -2371,7 +2416,7 @@ void Save_GIF(T_IO_Context * context)
word current_string; // Code de la chaîne en cours de traitement word current_string; // Code de la chaîne en cours de traitement
byte current_char; // Caractère à coder byte current_char; // Caractère à coder
word index; // index de recherche de chaîne word index; // index de recherche de chaîne
short current_layer; int current_layer;
/////////////////////////////////////////////////// FIN DES DECLARATIONS // /////////////////////////////////////////////////// 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); // Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\xLL\xSS\xSS\x00",19);
// LL : 01 to loop // LL : 01 to loop
// SSSS : number of loops // SSSS : number of loops
#ifdef NOLAYERS
if (context->Nb_layers>1)
Write_bytes(GIF_file,"\x21\xFF\x0BNETSCAPE2.0\x03\x01\x00\x00\x00",19);
#endif
// Ecriture du commentaire // Ecriture du commentaire
if (context->Comment[0]) if (context->Comment[0])
@ -2471,24 +2520,36 @@ void Save_GIF(T_IO_Context * context)
current_layer++) current_layer++)
{ {
// Write a Graphic Control Extension // Write a Graphic Control Extension
byte GCE_block[] = "\x21\xF9\x04\x04\x05\x00\x00\x00"; T_GIF_GCE GCE;
// '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;
Set_saving_layer(context, current_layer); 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) if (current_layer == context->Nb_layers -1)
{ GCE.Delay_time=0xFFFF; // Infinity (10 minutes)
// "Infinite" delay for last frame #endif
GCE_block[4] = 255; GCE.Transparent_color=context->Transparent_color;
GCE_block[5] = 255; GCE.Block_terminator=0x00;
}
if (Write_bytes(GIF_file,GCE_block,8)) 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 // 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. /// 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; GFX2_GLOBAL short Main_magnifier_offset_Y;
/// Index of layer currently being edited /// 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. /// 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; GFX2_GLOBAL dword Main_layers_visible;
/// Index to use next time, when creating incremental backups, to make unique filename. /// 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. /// 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; GFX2_GLOBAL short Spare_magnifier_offset_Y;
/// Index of layer currently being edited /// 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. /// 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; GFX2_GLOBAL dword Spare_layers_visible;
/// Index to use next time, when creating incremental backups, to make unique filename. /// 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 #ifdef GLOBAL_VARIABLES
= =
{{MENU_WIDTH, 9, 1, 45, {NULL,NULL,NULL}, 20, BUTTON_HIDE }, // Status {{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 {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 {MENU_WIDTH, 35, 1, 0, {NULL,NULL,NULL}, 254, BUTTON_CHOOSE_COL }} // Main
#endif #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++) for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{ {
Copy_part_of_image_to_another( 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, 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(); Redraw_layered_image();
} }
@ -655,7 +655,7 @@ void Remap_spare(void)
short y_pos; // Variable de balayage de la brosse short y_pos; // Variable de balayage de la brosse
byte used[256]; // Tableau de booléens "La couleur est utilisée" byte used[256]; // Tableau de booléens "La couleur est utilisée"
int color; int color;
byte layer; int layer;
// On commence par initialiser le tableau de booléens à faux // On commence par initialiser le tableau de booléens à faux
for (color=0;color<=255;color++) 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 (layer=0; layer<Spare_backups->Pages->Nb_layers; layer++)
for (y_pos=0;y_pos<Spare_image_height;y_pos++) for (y_pos=0;y_pos<Spare_image_height;y_pos++)
for (x_pos=0;x_pos<Spare_image_width;x_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 // On va maintenant se servir de la table "used" comme table de
// conversion: pour chaque indice, la table donne une couleur 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 // qui craint un peu, on peut faire l'échange dans la brosse de toutes les
// teintes. // teintes.
for (layer=0; layer<Spare_backups->Pages->Nb_layers; layer++) 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 // Change transparent color index
Spare_backups->Pages->Transparent_color=used[Spare_backups->Pages->Transparent_color]; 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) 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) 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 // 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. // ressemble un peu plus à ce à quoi l'utilisateur peut s'attendre.
if (top_reached>Limit_top) 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_left,Limit_top, // Pos X et Y dans source
(Limit_right-Limit_left)+1, // width copie (Limit_right-Limit_left)+1, // width copie
top_reached-Limit_top,// height copie top_reached-Limit_top,// height copie
Main_image_width, // width de la source 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 Limit_left,Limit_top, // Pos X et Y destination
Main_image_width); // width destination Main_image_width); // width destination
if (bottom_reached<Limit_bottom) 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_left,bottom_reached+1,
(Limit_right-Limit_left)+1, (Limit_right-Limit_left)+1,
Limit_bottom-bottom_reached, 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); Limit_left,bottom_reached+1,Main_image_width);
if (left_reached>Limit_left) 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, Limit_left,top_reached,
left_reached-Limit_left, left_reached-Limit_left,
(bottom_reached-top_reached)+1, (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); Limit_left,top_reached,Main_image_width);
if (right_reached<Limit_right) 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, right_reached+1,top_reached,
Limit_right-right_reached, Limit_right-right_reached,
(bottom_reached-top_reached)+1, (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); right_reached+1,top_reached,Main_image_width);
for (y_pos=top_reached;y_pos<=bottom_reached;y_pos++) 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) 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); return Read_pixel_from_feedback_screen(x,y);
} }
@ -2974,16 +2974,16 @@ byte Read_pixel_from_current_screen (word x,word y)
byte color; byte color;
if (Main_current_layer==4) 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); color = *(Main_screen+y*Main_image_width+x);
if (color != Main_backups->Pages->Transparent_color) // transparent color if (color != Main_backups->Pages->Transparent_color) // transparent color
return color; return color;
depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
return *(Main_backups->Pages->Image[depth] + x+y*Main_image_width); return *(Main_backups->Pages->Image[depth].Pixels + x+y*Main_image_width);
#else #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 #endif
} }
@ -2993,30 +2993,29 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview)
if (!Constraint_mode) if (!Constraint_mode)
{ {
byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); 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 ( depth <= Main_current_layer)
{ {
if (color == Main_backups->Pages->Transparent_color) // transparent color if (color == Main_backups->Pages->Transparent_color) // transparent color
// fetch pixel color from the topmost visible layer // 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; *(x+y*Main_image_width+Main_screen)=color;
if (with_preview) if (with_preview)
Pixel_preview(x,y,color); Pixel_preview(x,y,color);
} }
} }
else if ( Main_current_layer == 4) else if ( Main_current_layer == 4)
{ {
if (color<4) if (color<4)
{ {
// Paste in layer // 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 // Paste in depth buffer
*(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color; *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color;
// Fetch pixel color from the target raster layer // 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 // Draw that color on the visible image buffer
*(x+y*Main_image_width+Main_screen)=color; *(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; byte depth;
// Paste in layer // 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 // 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) 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; 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); depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width);
if ( depth <= Main_current_layer) if ( depth <= Main_current_layer)
{ {
if (color == Main_backups->Pages->Transparent_color) // transparent color if (color == Main_backups->Pages->Transparent_color) // transparent color
// fetch pixel color from the topmost visible layer // 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; *(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 #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) if (with_preview)
Pixel_preview(x,y,color); Pixel_preview(x,y,color);
#endif #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) 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) 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) 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 (" Next : %s", SPECIAL_NEXT_USER_BACKCOLOR)
HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR) HELP_LINK (" Previous: %s", SPECIAL_PREVIOUS_USER_BACKCOLOR)
HELP_TEXT ("") HELP_TEXT ("")
HELP_TEXT ("LAYERS") HELP_TEXT ("LAYERS / ANIMATION FRAMES")
HELP_TEXT ("") HELP_TEXT ("")
HELP_LINK (" Menu : %s", 0x100+BUTTON_LAYER_MENU) HELP_LINK (" Menu : %s", 0x100+BUTTON_LAYER_MENU)
HELP_LINK (" Add new : %s", 0x100+BUTTON_LAYER_ADD) HELP_LINK (" Add new : %s", 0x100+BUTTON_LAYER_ADD)
HELP_LINK (" Delete : %s", 0x100+BUTTON_LAYER_REMOVE) HELP_LINK (" Delete : %s", 0x100+BUTTON_LAYER_REMOVE)
#ifndef NOLAYERS
HELP_LINK (" Merge : %s", 0x100+BUTTON_LAYER_MERGE) HELP_LINK (" Merge : %s", 0x100+BUTTON_LAYER_MERGE)
#endif
HELP_LINK (" Move up : %s", 0x100+BUTTON_LAYER_UP) HELP_LINK (" Move up : %s", 0x100+BUTTON_LAYER_UP)
HELP_LINK (" Move down : %s", 0x100+BUTTON_LAYER_DOWN) HELP_LINK (" Move down : %s", 0x100+BUTTON_LAYER_DOWN)
//HELP_LINK (" Set transp: %s", 0x100+BUTTON_LAYER_COLOR) //HELP_LINK (" Set transp: %s", 0x100+BUTTON_LAYER_COLOR)
#ifndef NOLAYERS
HELP_TEXT (" Select :") HELP_TEXT (" Select :")
HELP_LINK (" 1 : %s", SPECIAL_LAYER1_SELECT) HELP_LINK (" 1 : %s", SPECIAL_LAYER1_SELECT)
HELP_LINK (" 2 : %s", SPECIAL_LAYER2_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 (" 6 : %s", SPECIAL_LAYER6_TOGGLE)
HELP_LINK (" 7 : %s", SPECIAL_LAYER7_TOGGLE) HELP_LINK (" 7 : %s", SPECIAL_LAYER7_TOGGLE)
HELP_LINK (" 8 : %s", SPECIAL_LAYER8_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_TEXT ("")
HELP_LINK (" Format check : %s", SPECIAL_FORMAT_CHECKER) HELP_LINK (" Format check : %s", SPECIAL_FORMAT_CHECKER)
HELP_LINK (" Format check menu: %s", SPECIAL_FORMAT_CHECKER_MENU) 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_layerdel)
HELP_TABLE_DECLARATION(helptable_layerup) HELP_TABLE_DECLARATION(helptable_layerup)
HELP_TABLE_DECLARATION(helptable_layerdown) 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_layerselect)
HELP_TABLE_DECLARATION(helptable_paintbrush) HELP_TABLE_DECLARATION(helptable_paintbrush)
HELP_TABLE_DECLARATION(helptable_adjust) HELP_TABLE_DECLARATION(helptable_adjust)

View File

@ -1657,6 +1657,54 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
true, true,
0, 0,
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]= word Ordering[NB_SHORTCUTS]=
@ -1861,4 +1909,10 @@ word Ordering[NB_SHORTCUTS]=
SPECIAL_CYCLE_MODE, SPECIAL_CYCLE_MODE,
SPECIAL_FORMAT_CHECKER, SPECIAL_FORMAT_CHECKER,
SPECIAL_FORMAT_CHECKER_MENU, 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 // Layerbar
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "layer bar")) if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "layer bar"))
return 1; 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; 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 // Status bar
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "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) // Layerbar (selected)
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "selected layer bar")) if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "selected layer bar"))
return 1; 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; 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) // Status bar (selected)
if (GUI_seek_down(gui, &cursor_x, &cursor_y, neutral_color, "selected status bar")) 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], memcpy(gfx->Menu_block[2], gfx->Menu_block[0],
Menu_bars[MENUBAR_TOOLS].Skin_width*Menu_bars[MENUBAR_TOOLS].Height); Menu_bars[MENUBAR_TOOLS].Skin_width*Menu_bars[MENUBAR_TOOLS].Height);
memcpy(gfx->Layerbar_block[2], gfx->Layerbar_block[0], 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], memcpy(gfx->Statusbar_block[2], gfx->Statusbar_block[0],
Menu_bars[MENUBAR_STATUS].Skin_width*Menu_bars[MENUBAR_STATUS].Height); Menu_bars[MENUBAR_STATUS].Skin_width*Menu_bars[MENUBAR_STATUS].Height);
@ -1146,6 +1162,7 @@ void Init_buttons(void)
FAMILY_INSTANT); FAMILY_INSTANT);
// Layer bar // Layer bar
#ifndef NOLAYERS
Init_button(BUTTON_LAYER_MENU, Init_button(BUTTON_LAYER_MENU,
0,0, 0,0,
57,9, 57,9,
@ -1210,6 +1227,89 @@ void Init_buttons(void)
0,0, 0,0,
Do_nothing, Do_nothing,
FAMILY_INSTANT); 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 // Status bar
Init_button(BUTTON_HIDE, Init_button(BUTTON_HIDE,
0,0, 0,0,
@ -2695,7 +2795,11 @@ void Set_current_skin(const char *skinfile, T_Gui_skin *gfx)
for (i=0; i<3; i++) for (i=0; i<3; i++)
{ {
Menu_bars[MENUBAR_TOOLS ].Skin[i] = (byte*)&(gfx->Menu_block[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]); 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]); Menu_bars[MENUBAR_STATUS].Skin[i] = (byte*)&(gfx->Statusbar_block[i]);
} }
} }

View File

@ -29,8 +29,9 @@
#include "input.h" #include "input.h"
#include "help.h" #include "help.h"
#include "misc.h" #include "misc.h"
#include "readline.h"
void Layer_activate(byte layer, short side) void Layer_activate(int layer, short side)
{ {
word old_layers; word old_layers;
@ -103,8 +104,18 @@ void Button_Layer_add(void)
Backup_layers(0); Backup_layers(0);
if (!Add_layer(Main_backups,Main_current_layer+1)) if (!Add_layer(Main_backups,Main_current_layer+1))
{ {
#ifdef NOLAYERS
// 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(); 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_all_screen();
#endif
Display_layerbar(); Display_layerbar();
End_of_modification(); End_of_modification();
} }
@ -154,7 +165,7 @@ void Button_Layer_select(void)
void Button_Layer_toggle(void) void Button_Layer_toggle(void)
{ {
short layer; int layer;
// Determine which button is clicked according to mouse position // Determine which button is clicked according to mouse position
layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width) layer = (Mouse_X/Menu_factor_X - Menu_bars[MENUBAR_LAYERS].Skin_width)
/ Layer_button_width; / Layer_button_width;
@ -318,7 +329,7 @@ void Button_Layer_up(void)
if (Main_current_layer < (Main_backups->Pages->Nb_layers-1)) if (Main_current_layer < (Main_backups->Pages->Nb_layers-1))
{ {
byte * tmp; T_Image tmp;
dword layer_flags; dword layer_flags;
// Backup with unchanged layers // Backup with unchanged layers
@ -357,7 +368,7 @@ void Button_Layer_down(void)
if (Main_current_layer > 0) if (Main_current_layer > 0)
{ {
byte * tmp; T_Image tmp;
dword layer_flags; dword layer_flags;
// Backup with unchanged layers // Backup with unchanged layers
@ -389,3 +400,250 @@ void Button_Layer_down(void)
Unselect_button(BUTTON_LAYER_DOWN); Unselect_button(BUTTON_LAYER_DOWN);
Display_cursor(); 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_down(void);
void Button_Layer_select(void); void Button_Layer_select(void);
void Button_Layer_toggle(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, /// Generic allocation and similar stuff, done at beginning of image load,
/// as soon as size is known. /// as soon as size is known.
@ -644,7 +667,7 @@ void Load_image(T_IO_Context *context)
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape=CURSOR_SHAPE_HOURGLASS;
Display_cursor(); Display_cursor();
Flush_update(); 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; File_error=2;
else else
{ {
@ -1213,7 +1236,7 @@ void Init_context_layered_image(T_IO_Context * context, char *file_name, char *f
context->Ratio=PIXEL_TALL; context->Ratio=PIXEL_TALL;
else else
context->Ratio=PIXEL_SIMPLE; 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; context->Pitch=Main_image_width;
// Color cyling ranges: // 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. /// 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; context->Current_layer = layer;
if (context->Type == CONTEXT_MAIN_IMAGE) 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. /// 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; 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_layers_visible = (2<<layer)-1;
} }
Main_current_layer = layer; 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; T_Palette Palette;
short Width; short Width;
short Height; short Height;
byte Nb_layers; int Nb_layers;
char Comment[COMMENT_SIZE+1]; char Comment[COMMENT_SIZE+1];
byte Background_transparent; byte Background_transparent;
byte Transparent_color; byte Transparent_color;
@ -83,7 +83,7 @@ typedef struct
T_Color_cycle Cycle_range[16]; T_Color_cycle Cycle_range[16];
/// Internal: during load, marks which layer is being loaded. /// 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. /// Internal: Used to mark truecolor images on loading. Only used by preview.
//byte Is_truecolor; //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) /// 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); 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. /// 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. /// 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 // 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 each layer
for (layer = 0; layer < Main_backups->Pages->Nb_layers; 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 each pixel in picture
for (i = 0; i < nb_pixels; i++) 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 int nb_pixels=0; //ECX
//al=color //al=color
//edi=Screen_pixels //edi=Screen_pixels
byte* pixel=Main_backups->Pages->Image[Main_current_layer]; byte* pixel=Main_backups->Pages->Image[Main_current_layer].Pixels;
int i; int i;
nb_pixels=Main_image_height*Main_image_width; 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 // Effacer l'image courante avec une certaine couleur
{ {
memset( memset(
Main_backups->Pages->Image[Main_current_layer], Main_backups->Pages->Image[Main_current_layer].Pixels,
color , color ,
Main_image_width * Main_image_height Main_image_width * Main_image_height
); );
@ -306,7 +306,7 @@ byte Read_pixel_from_spare_screen(word x,word y)
#ifndef NOLAYERS #ifndef NOLAYERS
return *(Spare_visible_image.Image + y*Spare_image_width + x); return *(Spare_visible_image.Image + y*Spare_image_width + x);
#else #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 #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) 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) byte* dest=Brush_original_pixels; //Adr dest brosse (EDI)
int dx; int dx;
@ -407,7 +407,7 @@ void Replace_colors_within_limits(byte * replace_table)
// Pour chaque pixel sur la ligne : // Pour chaque pixel sur la ligne :
for (x = Limit_left;x <= Limit_right;x ++) 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]; *pixel = replace_table[*pixel];
} }
} }

View File

@ -33,7 +33,7 @@
void Pixel_in_layer(word x,word y, byte layer, byte color) 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) 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++) 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; 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 // Get "mandatory colors" from layer 1
for (row=0;row<200;row++) 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) if (c<16)
{ {
line_color[row]=c; 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++) 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) if (c<16)
{ {
block_color[row/8][col]=c; 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++) for(x=0; x<4; x++)
{ {
byte bits; 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]) if (c==line_color[row*8+y])
// BG color // BG color

View File

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

View File

@ -57,16 +57,19 @@ long Stats_pages_number=0;
long long Stats_pages_memory=0; long long Stats_pages_memory=0;
/// Allocate and initialize a new page. /// Allocate and initialize a new page.
T_Page * New_page(byte nb_layers) T_Page * New_page(int nb_layers)
{ {
T_Page * page; 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) if (page!=NULL)
{ {
int i; int i;
for (i=0; i<nb_layers; 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->Width=0;
page->Height=0; page->Height=0;
memset(page->Palette,0,sizeof(T_Palette)); memset(page->Palette,0,sizeof(T_Palette));
@ -110,13 +113,13 @@ byte * New_layer(long pixel_size)
} }
/// Free a layer /// Free a layer
void Free_layer(T_Page * page, byte layer) void Free_layer(T_Page * page, int layer)
{ {
short * ptr; short * ptr;
if (page->Image[layer]==NULL) if (page->Image[layer].Pixels==NULL)
return; return;
ptr = (short *)(page->Image[layer]); ptr = (short *)(page->Image[layer].Pixels);
if (-- (*(ptr-1))) // Users-- if (-- (*(ptr-1))) // Users--
return; return;
else { else {
@ -189,7 +192,7 @@ void Download_infos_page_main(T_Page * page)
} }
//Update_buffers( page->Width, page->Height); //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; int i;
for (i=0; i< Main_image_width*Main_image_height; i++) for (i=0; i< Main_image_width*Main_image_height; i++)
{ {
layer = *(Main_backups->Pages->Image[4]+i); layer = *(Main_backups->Pages->Image[4].Pixels+i);
Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer]+i); Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer].Pixels+i);
} }
// Copy it to the depth buffer // Copy it to the depth buffer
memcpy(Main_visible_image_depth_buffer.Image, memcpy(Main_visible_image_depth_buffer.Image,
Main_backups->Pages->Image[4], Main_backups->Pages->Image[4].Pixels,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
// Next // Next
@ -226,7 +229,7 @@ void Redraw_layered_image(void)
{ {
// Copy it in Main_visible_image // Copy it in Main_visible_image
memcpy(Main_visible_image.Image, memcpy(Main_visible_image.Image,
Main_backups->Pages->Image[layer], Main_backups->Pages->Image[layer].Pixels,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
// Initialize the depth buffer // Initialize the depth buffer
@ -248,7 +251,7 @@ void Redraw_layered_image(void)
int i; int i;
for (i=0; i<Main_image_width*Main_image_height; i++) for (i=0; i<Main_image_width*Main_image_height; i++)
{ {
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 if (color != Main_backups->Pages->Transparent_color) // transparent color
{ {
*(Main_visible_image.Image+i) = color; *(Main_visible_image.Image+i) = color;
@ -299,7 +302,7 @@ void Update_depth_buffer(void)
int i; int i;
for (i=0; i<Main_image_width*Main_image_height; i++) for (i=0; i<Main_image_width*Main_image_height; i++)
{ {
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 if (color != Main_backups->Pages->Transparent_color) // transparent color
{ {
*(Main_visible_image_depth_buffer.Image+i) = layer; *(Main_visible_image_depth_buffer.Image+i) = layer;
@ -323,7 +326,7 @@ void Redraw_spare_image(void)
{ {
// Copy it in Spare_visible_image // Copy it in Spare_visible_image
memcpy(Spare_visible_image.Image, memcpy(Spare_visible_image.Image,
Spare_backups->Pages->Image[layer], Spare_backups->Pages->Image[layer].Pixels,
Spare_image_width*Spare_image_height); Spare_image_width*Spare_image_height);
// No depth buffer in the spare // No depth buffer in the spare
@ -344,7 +347,7 @@ void Redraw_spare_image(void)
int i; int i;
for (i=0; i<Spare_image_width*Spare_image_height; 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 if (color != Spare_backups->Pages->Transparent_color) // transparent color
{ {
*(Spare_visible_image.Image+i) = 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); byte depth = *(Main_visible_image_depth_buffer.Image+i);
if (depth<=Main_current_layer) 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 if (color != Main_backups->Pages->Transparent_color) // transparent color
{ {
*(Main_visible_image.Image+i) = color; *(Main_visible_image.Image+i) = color;
} }
else 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) if (page!=NULL)
{ {
//page->Image[Main_current_layer]=Main_screen; //page->Image[Main_current_layer].Pixels=Main_screen;
page->Width=Main_image_width; page->Width=Main_image_width;
page->Height=Main_image_height; page->Height=Main_image_height;
memcpy(page->Palette,Main_palette,sizeof(T_Palette)); memcpy(page->Palette,Main_palette,sizeof(T_Palette));
@ -409,7 +412,7 @@ void Upload_infos_page_spare(T_Page * page)
{ {
if (page!=NULL) if (page!=NULL)
{ {
//page->Image[Spare_current_layer]=Spare_screen; //page->Image[Spare_current_layer].Pixels=Spare_screen;
page->Width=Spare_image_width; page->Width=Spare_image_width;
page->Height=Spare_image_height; page->Height=Spare_image_height;
memcpy(page->Palette,Spare_palette,sizeof(T_Palette)); memcpy(page->Palette,Spare_palette,sizeof(T_Palette));
@ -423,9 +426,9 @@ void Update_FX_feedback(byte with_feedback)
{ {
if (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 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) void Clear_page(T_Page * page)
@ -435,7 +438,8 @@ void Clear_page(T_Page * page)
for (i=0; i<page->Nb_layers; i++) for (i=0; i<page->Nb_layers; i++)
{ {
Free_layer(page, 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 // 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++) for (i=0; i<new_page->Nb_layers; i++)
{ {
if ((1<<i) & layer_mask) 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 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; Main_screen=Main_visible_image.Image;
Screen_backup=Main_visible_image_backup.Image; Screen_backup=Main_visible_image_backup.Image;
#else #else
Main_screen=Main_backups->Pages->Image[Main_current_layer]; Main_screen=Main_backups->Pages->Image[Main_current_layer].Pixels;
Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer]; Screen_backup=Main_backups->Pages->Next->Image[Main_current_layer].Pixels;
#endif #endif
} }
@ -762,10 +767,10 @@ int Init_all_backup_lists(int width,int height)
for (i=0; i<Main_backups->Pages->Nb_layers; i++) for (i=0; i<Main_backups->Pages->Nb_layers; i++)
{ {
Main_backups->Pages->Image[i]=New_layer(width*height); Main_backups->Pages->Image[i].Pixels=New_layer(width*height);
if (! Main_backups->Pages->Image[i]) if (! Main_backups->Pages->Image[i].Pixels)
return 0; return 0;
memset(Main_backups->Pages->Image[i], 0, width*height); memset(Main_backups->Pages->Image[i].Pixels, 0, width*height);
} }
#ifndef NOLAYERS #ifndef NOLAYERS
Main_visible_image.Width = 0; Main_visible_image.Width = 0;
@ -811,10 +816,10 @@ int Init_all_backup_lists(int width,int height)
// Spare // Spare
for (i=0; i<NB_LAYERS; i++) for (i=0; i<NB_LAYERS; i++)
{ {
Spare_backups->Pages->Image[i]=New_layer(width*height); Spare_backups->Pages->Image[i].Pixels=New_layer(width*height);
if (! Spare_backups->Pages->Image[i]) if (! Spare_backups->Pages->Image[i].Pixels)
return 0; 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); //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) // (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 // Retourne 1 si une nouvelle page est disponible et 0 sinon
T_Page * new_page; T_Page * new_page;
@ -900,7 +905,7 @@ int Backup_with_new_dimensions(int width,int height)
// Fill with transparent color // Fill with transparent color
for (i=0; i<Main_backups->Pages->Nb_layers;i++) 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); Update_buffers(width, height);
@ -959,10 +964,10 @@ int Backup_in_place(int width,int height)
{ {
// Replace layers // Replace layers
Free_layer(Main_backups->Pages,i); 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 // 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; Main_backups->Pages->Width=width;
@ -1009,7 +1014,7 @@ int Backup_and_resize_the_spare(int width,int height)
T_Page * new_page; T_Page * new_page;
int return_code=0; int return_code=0;
byte nb_layers; int nb_layers;
nb_layers=Spare_backups->Pages->Nb_layers; nb_layers=Spare_backups->Pages->Nb_layers;
// On crée un descripteur pour la nouvelle page de brouillon // 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++) 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 // 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++) for (i=0; i<Main_backups->Pages->Nb_layers;i++)
{ {
if ((1<<i) & layer_mask) if ((1<<i) & layer_mask)
memcpy(Main_backups->Pages->Image[i], memcpy(Main_backups->Pages->Image[i].Pixels,
Main_backups->Pages->Next->Image[i], Main_backups->Pages->Next->Image[i].Pixels,
Main_image_width*Main_image_height); Main_image_width*Main_image_height);
} }
// Light up the 'has unsaved changes' indicator // 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++) for (i=0; i<Spare_backups->Pages->Nb_layers;i++)
{ {
if ((1<<i) & layer_mask) if ((1<<i) & layer_mask)
memcpy(Spare_backups->Pages->Image[i], memcpy(Spare_backups->Pages->Image[i].Pixels,
Spare_backups->Pages->Next->Image[i], Spare_backups->Pages->Next->Image[i].Pixels,
Spare_image_width*Spare_image_height); Spare_image_width*Spare_image_height);
} }
// Light up the 'has unsaved changes' indicator // 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. /// 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 * source_page;
T_Page * new_page; T_Page * new_page;
@ -1301,7 +1306,7 @@ byte Add_layer(T_List_of_pages *list, byte layer)
return 1; return 1;
} }
// Re-allocate the page itself, with room for one more pointer // 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) if (!new_page)
{ {
Error(0); 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[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 // Fill with transparency, initially
memset(new_image, Main_backups->Pages->Transparent_color, list->Pages->Height*list->Pages->Width); // transparent color 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. /// 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; T_Page * page;
int i; int i;
@ -1432,9 +1438,9 @@ byte Merge_layer()
int i; int i;
for (i=0; i<Main_image_width*Main_image_height; i++) for (i=0; i<Main_image_width*Main_image_height; i++)
{ {
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 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); 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 Download_infos_page_main(T_Page * page);
void Upload_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. /// 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. /// 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. /// Merges the current layer onto the one below it.
byte Merge_layer(); byte Merge_layer();
// private // private
T_Page * New_page(byte nb_layers); T_Page * New_page(int nb_layers);
void Download_infos_page_spare(T_Page * page); void Download_infos_page_spare(T_Page * page);
void Upload_infos_page_spare(T_Page * page); void Upload_infos_page_spare(T_Page * page);
void Clear_page(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); int Init_all_backup_lists(int width,int height);
void Set_number_of_backups(int nb_backups); 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); int Backup_with_new_dimensions(int width,int height);
/// ///
/// Resizes a backup step in-place (doesn't add a Undo/Redo step). /// 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 // Remap all layers
for (layer=0; layer<Main_backups->Pages->Nb_layers; layer++) 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 // Remap transparent color
Main_backups->Pages->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 // Ces structures sont manipulées à travers des fonctions de gestion du
// backup dans "graph.c". // 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 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. /// 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. /// 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. 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 Background_transparent; ///< Boolean, true if Layer 0 should have transparent pixels
byte Transparent_color; ///< Index of transparent color. 0 to 255. 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 #if __GNUC__ < 3
// gcc2 doesn't suport [], but supports [0] which does the same thing. // 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 #else
byte * Image[]; ///< Pixel data for the (first layer of) image. T_Image Image[]; ///< Pixel data for the (first layer of) image.
#endif #endif
// No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc. // No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc.
} T_Page; } T_Page;
@ -461,6 +467,7 @@ typedef struct
/// Bitmap data for the menu, a single rectangle. /// Bitmap data for the menu, a single rectangle.
byte Menu_block[3][35][MENU_WIDTH]; byte Menu_block[3][35][MENU_WIDTH];
byte Layerbar_block[3][10][144]; byte Layerbar_block[3][10][144];
byte Animbar_block[3][14][236];
byte Statusbar_block[3][9][20]; byte Statusbar_block[3][9][20];
/// Bitmap data for the icons that are displayed over the menu. /// Bitmap data for the icons that are displayed over the menu.
byte Menu_sprite[2][NB_MENU_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH]; 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 case 2 : // Flip X
for (i=0; i<Main_backups->Pages->Nb_layers; i++) 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); 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], Main_image_width, Main_image_height); Flip_X_lowlevel(Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height);
} }
break; break;
case 3 : // Flip Y case 3 : // Flip Y
for (i=0; i<Main_backups->Pages->Nb_layers; i++) 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); 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], Main_image_width, Main_image_height); Flip_Y_lowlevel(Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height);
} }
break; break;
case 4 : // -90° Rotation case 4 : // -90° Rotation
for (i=0; i<Main_backups->Pages->Nb_layers; i++) 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; break;
case 5 : // +90° Rotation case 5 : // +90° Rotation
for (i=0; i<Main_backups->Pages->Nb_layers; i++) 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; break;
case 6 : // 180° Rotation case 6 : // 180° Rotation
for (i=0; i<Main_backups->Pages->Nb_layers; i++) 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); 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], Main_image_width, Main_image_height); Rotate_180_deg_lowlevel(Main_backups->Pages->Image[i].Pixels, Main_image_width, Main_image_height);
} }
break; break;
case 7 : // Resize case 7 : // Resize
for (i=0; i<Main_backups->Pages->Nb_layers; i++) 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; break;
} }
@ -426,9 +426,9 @@ void Button_Transform_menu(void)
for (i=0; i<NB_LAYERS; i++) for (i=0; i<NB_LAYERS; i++)
{ {
Copy_part_of_image_to_another( 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, 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(); Redraw_layered_image();

View File

@ -464,6 +464,7 @@ void Draw_bar_remainder(word current_menu, word x_off)
/// Display / update the layer menubar /// Display / update the layer menubar
void Display_layerbar(void) void Display_layerbar(void)
{ {
#ifndef NOLAYERS
word x_off=0; word x_off=0;
word button_width = LAYER_SPRITE_WIDTH; word button_width = LAYER_SPRITE_WIDTH;
word button_number = Main_backups->Pages->Nb_layers; 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, Menu_Y+Menu_bars[MENUBAR_LAYERS].Top*Menu_factor_Y,
horiz_space*Menu_factor_X, horiz_space*Menu_factor_X,
Menu_bars[MENUBAR_LAYERS].Height*Menu_factor_Y); 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]); Remap_pixel(&Gfx->Statusbar_block[k][j][i]);
// Layer bar // Layer bar
for (k=0; k<3; k++) for (k=0; k<3; k++)
for (j=0; j<Menu_bars[MENUBAR_LAYERS].Height; j++) for (j=0; j<10; j++)
for (i=0; i<Menu_bars[MENUBAR_LAYERS].Skin_width; i++) for (i=0; i<144; i++)
Remap_pixel(&Gfx->Layerbar_block[k][j][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 // Help fonts
for (k=0; k<256; k++) for (k=0; k<256; k++)
for (j=0; j<8; j++) for (j=0; j<8; j++)