Huge rewrite of the file loading/saving system. Normally safer in case of problem. Added incremental safety backups at regular intervals in the 'application data' directory (Windows) or $HOME/.grafx2 (unix). Keeps 8 files, saves every 30-60s and/or every 10-30 clicks.

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1245 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Yves Rizoud 2010-01-13 02:09:47 +00:00
parent c93a9bd1c1
commit 8bdd163ede
14 changed files with 1903 additions and 1480 deletions

260
buttons.c
View File

@ -543,15 +543,19 @@ byte Button_Quit_local_function(void)
{ {
case 1 : return 0; // Rester case 1 : return 0; // Rester
case 2 : // Sauver et enregistrer case 2 : // Sauver et enregistrer
Get_full_filename(filename,0); Get_full_filename(filename, Main_backups->Pages->Filename, Main_backups->Pages->File_directory);
if ( (!File_exists(filename)) || Confirmation_box("Erase old file ?") ) if ( (!File_exists(filename)) || Confirmation_box("Erase old file ?") )
{ {
T_IO_Context save_context;
Hide_cursor(); Hide_cursor();
old_cursor_shape=Cursor_shape; old_cursor_shape=Cursor_shape;
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape=CURSOR_SHAPE_HOURGLASS;
Display_cursor(); Display_cursor();
Save_image(1); Init_context_layered_image(&save_context, Main_backups->Pages->Filename, Main_backups->Pages->File_directory);
Save_image(&save_context);
Destroy_context(&save_context);
Hide_cursor(); Hide_cursor();
Cursor_shape=old_cursor_shape; Cursor_shape=old_cursor_shape;
@ -1226,6 +1230,16 @@ void Button_Page(void)
SWAP_BYTES (Main_current_layer,Spare_current_layer) SWAP_BYTES (Main_current_layer,Spare_current_layer)
SWAP_DWORDS(Main_layers_visible,Spare_layers_visible) SWAP_DWORDS(Main_layers_visible,Spare_layers_visible)
SWAP_DWORDS(Main_safety_number,Spare_safety_number)
SWAP_DWORDS(Main_edits_since_safety_backup,Spare_edits_since_safety_backup)
SWAP_BYTES(Main_safety_backup_prefix,Spare_safety_backup_prefix)
{
Uint32 a;
a=Main_time_of_safety_backup;
Main_time_of_safety_backup=Spare_time_of_safety_backup;
Spare_time_of_safety_backup=a;
}
//Redraw_layered_image(); //Redraw_layered_image();
// replaced by // replaced by
Update_buffers(Main_image_width, Main_image_height); Update_buffers(Main_image_width, Main_image_height);
@ -2560,95 +2574,46 @@ int Best_video_mode(void)
return best_mode; return best_mode;
} }
void Swap_data_of_image_and_brush(void)
{
char temp_string[MAX_PATH_CHARACTERS];
byte temp_byte;
short temp_int;
strcpy(temp_string ,Brush_file_directory);
strcpy(Brush_file_directory ,Main_file_directory);
strcpy(Main_file_directory,temp_string);
strcpy(temp_string ,Brush_filename);
strcpy(Brush_filename ,Main_filename);
strcpy(Main_filename,temp_string);
temp_byte =Brush_fileformat;
Brush_fileformat =Main_fileformat;
Main_fileformat=temp_byte;
temp_byte=Brush_format;
Brush_format =Main_format;
Main_format=temp_byte;
temp_int =Brush_fileselector_position;
Brush_fileselector_position =Main_fileselector_position;
Main_fileselector_position=temp_int;
temp_int =Brush_fileselector_offset;
Brush_fileselector_offset =Main_fileselector_offset;
Main_fileselector_offset=temp_int;
strcpy(temp_string ,Brush_current_directory);
strcpy(Brush_current_directory ,Main_current_directory);
strcpy(Main_current_directory,temp_string);
strcpy(temp_string ,Brush_comment);
strcpy(Brush_comment ,Main_comment);
strcpy(Main_comment,temp_string);
}
void Load_picture(byte image) void Load_picture(byte image)
// Image=1 => On charge/sauve une image // Image=1 => On charge/sauve une image
// Image=0 => On charge/sauve une brosse // Image=0 => On charge/sauve une brosse
{ {
// Données initiales du fichier (au cas où on voudrait annuler) byte confirm;
char initial_file_directory[MAX_PATH_CHARACTERS];
char initial_filename[MAX_PATH_CHARACTERS];
byte initial_file_format;
byte do_not_restore;
byte use_brush_palette = 0; byte use_brush_palette = 0;
T_Components * initial_palette=NULL;
byte old_cursor_shape; byte old_cursor_shape;
short initial_main_image_width=Main_image_width;
short initial_main_image_height=Main_image_height;
//char initial_comment[COMMENT_SIZE+1];
int new_mode; int new_mode;
T_IO_Context context;
static char filename [MAX_PATH_CHARACTERS];
static char directory[MAX_PATH_CHARACTERS];
if (image)
if (!image)
Swap_data_of_image_and_brush();
strcpy(initial_file_directory,Main_file_directory);
strcpy(initial_filename ,Main_filename);
initial_file_format=Main_fileformat;
if (!image)
{ {
initial_palette=(T_Components *)malloc(sizeof(T_Palette)); strcpy(filename, Main_backups->Pages->Filename);
memcpy(initial_palette,Main_palette,sizeof(T_Palette)); strcpy(directory, Main_backups->Pages->File_directory);
Init_context_layered_image(&context, filename, directory);
} }
else
{
strcpy(filename, Brush_filename);
strcpy(directory, Main_current_directory);
Init_context_brush(&context, Brush_filename, Main_current_directory);
}
confirm=Button_Load_or_Save(1, &context);
do_not_restore=Button_Load_or_Save(1,image); if (confirm)
if (do_not_restore)
{ {
if (image) if (image)
{ {
if (Main_image_is_modified) if (Main_image_is_modified)
do_not_restore=Confirmation_box("Discard unsaved changes?"); confirm=Confirmation_box("Discard unsaved changes?");
} }
else else
use_brush_palette=Confirmation_box("Use the palette of the brush?"); use_brush_palette=Confirmation_box("Use the palette of the brush?");
} }
// do_not_restore is modified inside the first if, that's why we check it // confirm is modified inside the first if, that's why we check it
// again here // again here
if (do_not_restore) if (confirm)
{ {
old_cursor_shape=Cursor_shape; old_cursor_shape=Cursor_shape;
Hide_cursor(); Hide_cursor();
@ -2657,23 +2622,16 @@ void Load_picture(byte image)
if (image) if (image)
{ {
// Si c'est une image qu'on charge, on efface l'ancien commentaire
// C'est loin d'être indispensable, m'enfin bon...
if (! Get_fileformat(Main_fileformat)->Palette_only)
Main_comment[0]='\0';
Original_screen_X=0; Original_screen_X=0;
Original_screen_Y=0; Original_screen_Y=0;
} }
else
Pixel_load_function=Pixel_load_in_brush;
Load_image(image); Load_image(&context);
if (!image) if (!image)
{ {
if (!use_brush_palette) //if (!use_brush_palette)
memcpy(Main_palette,initial_palette,sizeof(T_Palette)); // memcpy(Main_palette,initial_palette,sizeof(T_Palette));
if (File_error==3) // On ne peut pas allouer la brosse if (File_error==3) // On ne peut pas allouer la brosse
{ {
@ -2688,13 +2646,7 @@ void Load_picture(byte image)
Smear_brush_height=MAX_PAINTBRUSH_SIZE; Smear_brush_height=MAX_PAINTBRUSH_SIZE;
Smear_brush_width=MAX_PAINTBRUSH_SIZE; Smear_brush_width=MAX_PAINTBRUSH_SIZE;
} }
else
{
Brush_width=Main_image_width;
Brush_height=Main_image_height;
Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
}
Tiling_offset_X=0; Tiling_offset_X=0;
Tiling_offset_Y=0; Tiling_offset_Y=0;
@ -2702,10 +2654,6 @@ void Load_picture(byte image)
Brush_offset_X=(Brush_width>>1); Brush_offset_X=(Brush_width>>1);
Brush_offset_Y=(Brush_height>>1); Brush_offset_Y=(Brush_height>>1);
Main_image_width=initial_main_image_width;
Main_image_height=initial_main_image_height;
Pixel_load_function=Pixel_load_in_current_screen;
Select_button(BUTTON_DRAW,LEFT_SIDE); Select_button(BUTTON_DRAW,LEFT_SIDE);
if (Config.Auto_discontinuous) if (Config.Auto_discontinuous)
{ {
@ -2723,9 +2671,9 @@ void Load_picture(byte image)
Cursor_shape=old_cursor_shape; Cursor_shape=old_cursor_shape;
} }
if ( (File_error==1) || (Get_fileformat(Main_fileformat)->Palette_only) ) if ( (File_error==1) || (Get_fileformat(Main_fileformat)->Palette_only) )
{ {
do_not_restore=0;
if (File_error!=1) if (File_error!=1)
Compute_optimal_menu_colors(Main_palette); Compute_optimal_menu_colors(Main_palette);
} }
@ -2752,16 +2700,16 @@ void Load_picture(byte image)
} }
// In window mode, activate wide or tall pixels if the image says so. // In window mode, activate wide or tall pixels if the image says so.
else if (!Video_mode[Current_resolution].Fullscreen && else if (!Video_mode[Current_resolution].Fullscreen &&
((Ratio_of_loaded_image == PIXEL_WIDE && ((context.Ratio == PIXEL_WIDE &&
Pixel_ratio != PIXEL_WIDE && Pixel_ratio != PIXEL_WIDE2) || Pixel_ratio != PIXEL_WIDE && Pixel_ratio != PIXEL_WIDE2) ||
(Ratio_of_loaded_image == PIXEL_TALL && (context.Ratio == PIXEL_TALL &&
Pixel_ratio != PIXEL_TALL && Pixel_ratio != PIXEL_TALL2))) Pixel_ratio != PIXEL_TALL && Pixel_ratio != PIXEL_TALL2)))
{ {
Init_mode_video( Init_mode_video(
Video_mode[Current_resolution].Width, Video_mode[Current_resolution].Width,
Video_mode[Current_resolution].Height, Video_mode[Current_resolution].Height,
Video_mode[Current_resolution].Fullscreen, Video_mode[Current_resolution].Fullscreen,
Ratio_of_loaded_image); context.Ratio);
Display_menu(); Display_menu();
} }
else else
@ -2780,21 +2728,15 @@ void Load_picture(byte image)
if (image) if (image)
Main_image_is_modified=0; Main_image_is_modified=0;
} }
Destroy_context(&context);
Display_menu(); Display_menu();
Display_cursor(); Display_cursor();
} }
free(initial_palette); //if (!image)
// Swap_data_of_image_and_brush();
if (!do_not_restore)
{
strcpy(Main_filename ,initial_filename);
strcpy(Main_file_directory,initial_file_directory);
Main_fileformat =initial_file_format;
}
if (!image)
Swap_data_of_image_and_brush();
Hide_cursor(); Hide_cursor();
Print_filename(); Print_filename();
Display_cursor(); Display_cursor();
@ -2823,6 +2765,8 @@ void Button_Reload(void)
if ( (!Main_image_is_modified) || Confirmation_box("Discard unsaved changes ?") ) if ( (!Main_image_is_modified) || Confirmation_box("Discard unsaved changes ?") )
{ {
T_IO_Context context;
Hide_cursor(); Hide_cursor();
old_cursor_shape=Cursor_shape; old_cursor_shape=Cursor_shape;
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape=CURSOR_SHAPE_HOURGLASS;
@ -2830,7 +2774,9 @@ void Button_Reload(void)
Original_screen_X=0; Original_screen_X=0;
Original_screen_Y=0; Original_screen_Y=0;
Load_image(1);
Init_context_layered_image(&context, Main_backups->Pages->Filename, Main_backups->Pages->File_directory);
Load_image(&context);
Hide_cursor(); Hide_cursor();
Cursor_shape=old_cursor_shape; Cursor_shape=old_cursor_shape;
@ -2857,16 +2803,16 @@ void Button_Reload(void)
} }
// In window mode, activate wide or tall pixels if the image says so. // In window mode, activate wide or tall pixels if the image says so.
else if (!Video_mode[Current_resolution].Fullscreen && else if (!Video_mode[Current_resolution].Fullscreen &&
((Ratio_of_loaded_image == PIXEL_WIDE && ((context.Ratio == PIXEL_WIDE &&
Pixel_ratio != PIXEL_WIDE && Pixel_ratio != PIXEL_WIDE2) || Pixel_ratio != PIXEL_WIDE && Pixel_ratio != PIXEL_WIDE2) ||
(Ratio_of_loaded_image == PIXEL_TALL && (context.Ratio == PIXEL_TALL &&
Pixel_ratio != PIXEL_TALL && Pixel_ratio != PIXEL_TALL2))) Pixel_ratio != PIXEL_TALL && Pixel_ratio != PIXEL_TALL2)))
{ {
Init_mode_video( Init_mode_video(
Video_mode[Current_resolution].Width, Video_mode[Current_resolution].Width,
Video_mode[Current_resolution].Height, Video_mode[Current_resolution].Height,
Video_mode[Current_resolution].Fullscreen, Video_mode[Current_resolution].Fullscreen,
Ratio_of_loaded_image); context.Ratio);
Display_menu(); Display_menu();
} }
else else
@ -2881,6 +2827,7 @@ void Button_Reload(void)
Main_image_is_modified=0; Main_image_is_modified=0;
} }
Destroy_context(&context);
} }
else else
Hide_cursor(); Hide_cursor();
@ -2901,7 +2848,7 @@ void Backup_filename(char * fname, char * backup_name)
short i; short i;
strcpy(backup_name,fname); strcpy(backup_name,fname);
for (i=strlen(fname)-strlen(Main_filename); backup_name[i]!='.'; i++); for (i=strlen(fname)-strlen(Main_backups->Pages->Filename); backup_name[i]!='.'; i++);
backup_name[i+1]='\0'; backup_name[i+1]='\0';
strcat(backup_name,"BAK"); strcat(backup_name,"BAK");
} }
@ -2912,7 +2859,7 @@ void Backup_existing_file(void)
char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier
char new_filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier backup char new_filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier backup
Get_full_filename(filename,0); Get_full_filename(filename, Main_backups->Pages->Filename, Main_backups->Pages->File_directory);
// Calcul du nom complet du fichier backup // Calcul du nom complet du fichier backup
Backup_filename(filename,new_filename); Backup_filename(filename,new_filename);
@ -2938,76 +2885,63 @@ void Save_picture(byte image)
// image=1 => On charge/sauve une image // image=1 => On charge/sauve une image
// image=0 => On charge/sauve une brosse // image=0 => On charge/sauve une brosse
{ {
// Données initiales du fichier (au cas où on voudrait annuler) byte confirm;
char initial_file_directory[MAX_PATH_CHARACTERS];
char initial_filename[MAX_PATH_CHARACTERS];
byte initial_file_format;
byte do_not_restore;
byte old_cursor_shape; byte old_cursor_shape;
short initial_main_image_width=Main_image_width; T_IO_Context save_context;
short initial_main_image_height=Main_image_height; static char filename [MAX_PATH_CHARACTERS];
//char initial_comment[COMMENT_SIZE+1]; static char directory[MAX_PATH_CHARACTERS];
if (image)
if (!image)
Swap_data_of_image_and_brush();
strcpy(initial_file_directory,Main_file_directory);
strcpy(initial_filename ,Main_filename);
initial_file_format=Main_fileformat;
do_not_restore=Button_Load_or_Save(0,image);
if (do_not_restore && File_exists(Main_filename))
{ {
do_not_restore=Confirmation_box("Erase old file ?"); strcpy(filename, Main_backups->Pages->Filename);
if ((do_not_restore) && (Config.Backup)) strcpy(directory, Main_backups->Pages->File_directory);
Init_context_layered_image(&save_context, filename, directory);
save_context.Format = Main_fileformat;
}
else
{
strcpy(filename, Brush_filename);
strcpy(directory, Brush_file_directory);
Init_context_brush(&save_context, filename, directory);
save_context.Format = Main_fileformat;
}
//if (!image)
// Swap_data_of_image_and_brush();
confirm=Button_Load_or_Save(0, &save_context);
if (confirm && File_exists(save_context.File_name))
{
confirm=Confirmation_box("Erase old file ?");
if (confirm && (Config.Backup))
{ {
Backup_existing_file(); Backup_existing_file();
if (File_error) if (File_error)
{ {
do_not_restore=0; confirm=0;
Error(0); Error(0);
} }
} }
} }
if (do_not_restore) if (confirm)
{ {
old_cursor_shape=Cursor_shape; old_cursor_shape=Cursor_shape;
Hide_cursor(); Hide_cursor();
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape=CURSOR_SHAPE_HOURGLASS;
Display_cursor(); Display_cursor();
if (image) Save_image(&save_context);
Save_image(image);
else
{
Main_image_width=Brush_width;
Main_image_height=Brush_height;
Save_image(image);
Main_image_width=initial_main_image_width;
Main_image_height=initial_main_image_height;
}
Hide_cursor(); Hide_cursor();
Cursor_shape=old_cursor_shape; Cursor_shape=old_cursor_shape;
if ((File_error==1) || (Get_fileformat(Main_fileformat)->Palette_only))
do_not_restore=0;
Display_cursor(); Display_cursor();
} }
Destroy_context(&save_context);
if (!do_not_restore) //if (!image)
{ // Swap_data_of_image_and_brush();
strcpy(Main_filename ,initial_filename);
strcpy(Main_file_directory,initial_file_directory);
Main_fileformat =initial_file_format;
}
if (!image)
Swap_data_of_image_and_brush();
Print_filename(); Print_filename();
Set_palette(Main_palette); Set_palette(Main_palette);
@ -3027,7 +2961,7 @@ void Button_Autosave(void)
byte file_already_exists; byte file_already_exists;
Get_full_filename(filename,0); Get_full_filename(filename, Main_backups->Pages->Filename, Main_backups->Pages->File_directory);
file_already_exists=File_exists(filename); file_already_exists=File_exists(filename);
if ( (!file_already_exists) || Confirmation_box("Erase old file ?") ) if ( (!file_already_exists) || Confirmation_box("Erase old file ?") )
@ -3041,11 +2975,15 @@ void Button_Autosave(void)
if (!File_error) if (!File_error)
{ {
T_IO_Context save_context;
old_cursor_shape=Cursor_shape; old_cursor_shape=Cursor_shape;
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape=CURSOR_SHAPE_HOURGLASS;
Display_cursor(); Display_cursor();
Save_image(1); Init_context_layered_image(&save_context, Main_backups->Pages->Filename, Main_backups->Pages->File_directory);
Save_image(&save_context);
Destroy_context(&save_context);
Hide_cursor(); Hide_cursor();
Cursor_shape=old_cursor_shape; Cursor_shape=old_cursor_shape;

File diff suppressed because it is too large Load Diff

155
filesel.c
View File

@ -70,6 +70,11 @@
T_Fileselector Filelist; T_Fileselector Filelist;
/// Name of the current directory
//static char Selector_directory[1024];
/// Filename (without directory) of the highlighted file
static char Selector_filename[256];
// Conventions: // Conventions:
// //
// * Le fileselect modifie le répertoire courant. Ceci permet de n'avoir // * Le fileselect modifie le répertoire courant. Ceci permet de n'avoir
@ -862,14 +867,13 @@ void Print_current_directory(void)
Update_window_area(10,84,37*8,8); Update_window_area(10,84,37*8,8);
} }
//
// Print the current file name
//
void Print_filename_in_fileselector(void) void Print_filename_in_fileselector(void)
//
// Affiche Main_filename dans le Fileselect
//
{ {
Window_rectangle(82,48,27*8,8,MC_Light); Window_rectangle(82,48,27*8,8,MC_Light);
Print_in_window_limited(82,48,Main_filename,27,MC_Black,MC_Light); Print_in_window_limited(82,48,Selector_filename,27,MC_Black,MC_Light);
Update_window_area(82,48,27*8,8); Update_window_area(82,48,27*8,8);
} }
@ -890,7 +894,7 @@ void Prepare_and_display_filelist(short Position, short offset, T_Scroller_butto
Update_window_area(8-1,95-1,144+2,80+2); Update_window_area(8-1,95-1,144+2,80+2);
// On récupère le nom du schmilblick à "accéder" // On récupère le nom du schmilblick à "accéder"
Get_selected_item(&Filelist, Position,offset,Main_filename,&Selected_type); Get_selected_item(&Filelist, Position,offset,Selector_filename,&Selected_type);
// On affiche le nouveau nom de fichier // On affiche le nouveau nom de fichier
Print_filename_in_fileselector(); Print_filename_in_fileselector();
// On affiche le nom du répertoire courant // On affiche le nom du répertoire courant
@ -935,7 +939,7 @@ void Scroll_fileselector(T_Scroller_button * file_scroller)
{ {
char old_filename[MAX_PATH_CHARACTERS]; char old_filename[MAX_PATH_CHARACTERS];
strcpy(old_filename,Main_filename); strcpy(old_filename,Selector_filename);
// On regarde si la liste a bougé // On regarde si la liste a bougé
if (file_scroller->Position!=Main_fileselector_position) if (file_scroller->Position!=Main_fileselector_position)
@ -945,8 +949,8 @@ void Scroll_fileselector(T_Scroller_button * file_scroller)
Window_draw_slider(file_scroller); Window_draw_slider(file_scroller);
} }
// On récupére le nom du schmilblick à "accéder" // On récupére le nom du schmilblick à "accéder"
Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Main_filename,&Selected_type); Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Selector_filename,&Selected_type);
if (strcmp(old_filename,Main_filename)) if (strcmp(old_filename,Selector_filename))
New_preview_is_needed=1; New_preview_is_needed=1;
// On affiche le nouveau nom de fichier // On affiche le nouveau nom de fichier
@ -1022,7 +1026,7 @@ char * Find_filename_match(T_Fileselector *list, char * fname)
return best_name_ptr; return best_name_ptr;
} }
byte Button_Load_or_Save(byte load, byte image) byte Button_Load_or_Save(byte load, T_IO_Context *context)
// load=1 => On affiche le menu du bouton LOAD // load=1 => On affiche le menu du bouton LOAD
// load=0 => On affiche le menu du bouton SAVE // load=0 => On affiche le menu du bouton SAVE
{ {
@ -1035,36 +1039,26 @@ byte Button_Load_or_Save(byte load, byte image)
byte save_or_load_image=0; byte save_or_load_image=0;
byte has_clicked_ok=0;// Indique si on a clické sur Load ou Save ou sur byte has_clicked_ok=0;// Indique si on a clické sur Load ou Save ou sur
//un bouton enclenchant Load ou Save juste après. //un bouton enclenchant Load ou Save juste après.
T_Components * initial_palette; // | Données concernant l'image qui byte initial_back_color; // | fout en l'air (c'te conne).
byte initial_image_is_modified; // | sont mémorisées pour pouvoir
short initial_image_width; // |- être restaurées en sortant,
short initial_image_height; // | parce que la preview elle les
byte old_back_color; // | fout en l'air (c'te conne).
char initial_filename[MAX_PATH_CHARACTERS]; // Sert à laisser le nom courant du fichier en cas de sauvegarde
char previous_directory[MAX_PATH_CHARACTERS]; // Répertoire d'où l'on vient après un CHDIR char previous_directory[MAX_PATH_CHARACTERS]; // Répertoire d'où l'on vient après un CHDIR
char initial_comment[COMMENT_SIZE+1];
char quicksearch_filename[MAX_PATH_CHARACTERS]=""; char quicksearch_filename[MAX_PATH_CHARACTERS]="";
char save_filename[MAX_PATH_CHARACTERS]; char save_filename[MAX_PATH_CHARACTERS];
char initial_comment[COMMENT_SIZE+1];
char * most_matching_filename; char * most_matching_filename;
short window_shortcut; short window_shortcut;
if (image) if (context->Type == CONTEXT_MAIN_IMAGE)
window_shortcut = load?(0x100+BUTTON_LOAD):(0x100+BUTTON_SAVE); window_shortcut = load?(0x100+BUTTON_LOAD):(0x100+BUTTON_SAVE);
else else
window_shortcut = load?SPECIAL_LOAD_BRUSH:SPECIAL_SAVE_BRUSH; window_shortcut = load?SPECIAL_LOAD_BRUSH:SPECIAL_SAVE_BRUSH;
initial_palette=(T_Components *)malloc(sizeof(T_Palette)); // Backup data that needs be restored on "cancel"
memcpy(initial_palette,Main_palette,sizeof(T_Palette)); initial_back_color=Back_color;
strcpy(initial_comment,context->Comment);
old_back_color=Back_color;
initial_image_is_modified=Main_image_is_modified;
initial_image_width=Main_image_width;
initial_image_height=Main_image_height;
strcpy(initial_filename,Main_filename);
strcpy(initial_comment,Main_comment);
if (load) if (load)
{ {
if (image) if (context->Type == CONTEXT_MAIN_IMAGE)
Open_window(310,200,"Load picture"); Open_window(310,200,"Load picture");
else else
Open_window(310,200,"Load brush"); Open_window(310,200,"Load brush");
@ -1072,7 +1066,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
else else
{ {
if (image) if (context->Type == CONTEXT_MAIN_IMAGE)
Open_window(310,200,"Save picture"); Open_window(310,200,"Save picture");
else else
Open_window(310,200,"Save brush"); Open_window(310,200,"Save brush");
@ -1092,7 +1086,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
// Affichage du commentaire // Affichage du commentaire
if (Get_fileformat(Main_format)->Comment) if (Get_fileformat(Main_format)->Comment)
Print_in_window(47,70,Main_comment,MC_Black,MC_Light); Print_in_window(47,70,context->Comment,MC_Black,MC_Light);
} }
Window_set_normal_button(253,180,51,14,"Cancel",0,1,KEY_ESC); // 2 Window_set_normal_button(253,180,51,14,"Cancel",0,1,KEY_ESC); // 2
@ -1159,7 +1153,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
else else
{ {
chdir(Main_file_directory); chdir(context->File_directory);
getcwd(Main_current_directory,256); getcwd(Main_current_directory,256);
} }
@ -1170,12 +1164,11 @@ byte Button_Load_or_Save(byte load, byte image)
{ {
// On initialise le nom de fichier à celui en cours et non pas celui sous // On initialise le nom de fichier à celui en cours et non pas celui sous
// la barre de sélection // la barre de sélection
strcpy(Main_filename,initial_filename); strcpy(Selector_filename,context->File_name);
// On affiche le nouveau nom de fichier // On affiche le nouveau nom de fichier
Print_filename_in_fileselector(); Print_filename_in_fileselector();
} }
Pixel_load_function=Pixel_load_in_preview;
New_preview_is_needed=1; New_preview_is_needed=1;
Update_window_area(0,0,Window_width, Window_height); Update_window_area(0,0,Window_width, Window_height);
@ -1195,10 +1188,10 @@ byte Button_Load_or_Save(byte load, byte image)
if(load) if(load)
{ {
// Determine the type // Determine the type
if(File_exists(Main_filename)) if(File_exists(Selector_filename))
{ {
Selected_type = 0; Selected_type = 0;
if(Directory_exists(Main_filename)) Selected_type = 1; if(Directory_exists(Selector_filename)) Selected_type = 1;
} }
else else
{ {
@ -1207,7 +1200,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
else else
{ {
if(Directory_exists(Main_filename)) Selected_type = 1; if(Directory_exists(Selector_filename)) Selected_type = 1;
else Selected_type = 0; else Selected_type = 0;
} }
has_clicked_ok=1; has_clicked_ok=1;
@ -1217,7 +1210,7 @@ byte Button_Load_or_Save(byte load, byte image)
break; break;
case 3 : // Delete case 3 : // Delete
if (Filelist.Nb_elements && (*Main_filename!='.') && Selected_type!=2) if (Filelist.Nb_elements && (*Selector_filename!='.') && Selected_type!=2)
{ {
char * message; char * message;
Hide_cursor(); Hide_cursor();
@ -1235,10 +1228,10 @@ byte Button_Load_or_Save(byte load, byte image)
// Si c'est un fichier // Si c'est un fichier
if (Main_fileselector_position+Main_fileselector_offset>=Filelist.Nb_directories) if (Main_fileselector_position+Main_fileselector_offset>=Filelist.Nb_directories)
// On efface le fichier (si on peut) // On efface le fichier (si on peut)
temp=(!remove(Main_filename)); temp=(!remove(Selector_filename));
else // Si c'est un repertoire else // Si c'est un repertoire
// On efface le repertoire (si on peut) // On efface le repertoire (si on peut)
temp=(!rmdir(Main_filename)); temp=(!rmdir(Selector_filename));
if (temp) // temp indique si l'effacement s'est bien passé if (temp) // temp indique si l'effacement s'est bien passé
{ {
@ -1291,7 +1284,7 @@ byte Button_Load_or_Save(byte load, byte image)
Main_fileselector_offset=temp; Main_fileselector_offset=temp;
// On récupére le nom du schmilblick à "accéder" // On récupére le nom du schmilblick à "accéder"
Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Main_filename,&Selected_type); Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Selector_filename,&Selected_type);
// On affiche le nouveau nom de fichier // On affiche le nouveau nom de fichier
Print_filename_in_fileselector(); Print_filename_in_fileselector();
// On affiche à nouveau la liste // On affiche à nouveau la liste
@ -1309,7 +1302,7 @@ byte Button_Load_or_Save(byte load, byte image)
// certains cas, on risque de sauvegarder avec le nom du fichier // certains cas, on risque de sauvegarder avec le nom du fichier
// actuel au lieu de changer de répertoire. // actuel au lieu de changer de répertoire.
if (Main_fileselector_position+Main_fileselector_offset<Filelist.Nb_directories) if (Main_fileselector_position+Main_fileselector_offset<Filelist.Nb_directories)
Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Main_filename,&Selected_type); Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Selector_filename,&Selected_type);
has_clicked_ok=1; has_clicked_ok=1;
New_preview_is_needed=1; New_preview_is_needed=1;
@ -1324,7 +1317,7 @@ byte Button_Load_or_Save(byte load, byte image)
Hide_cursor(); Hide_cursor();
Main_fileselector_position=Window_attribute2; Main_fileselector_position=Window_attribute2;
// On récupére le nom du schmilblick à "accéder" // On récupére le nom du schmilblick à "accéder"
Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Main_filename,&Selected_type); Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Selector_filename,&Selected_type);
// On affiche le nouveau nom de fichier // On affiche le nouveau nom de fichier
Print_filename_in_fileselector(); Print_filename_in_fileselector();
// On affiche à nouveau la liste // On affiche à nouveau la liste
@ -1350,30 +1343,30 @@ byte Button_Load_or_Save(byte load, byte image)
case 7 : // Saisie d'un commentaire pour la sauvegarde case 7 : // Saisie d'un commentaire pour la sauvegarde
if ( (!load) && (Get_fileformat(Main_format)->Comment) ) if ( (!load) && (Get_fileformat(Main_format)->Comment) )
{ {
Readline(45,70,Main_comment,32,0); Readline(45,70,context->Comment,32,0);
Display_cursor(); Display_cursor();
} }
break; break;
case 8 : // Saisie du nom de fichier case 8 : // Saisie du nom de fichier
// Save the filename // Save the filename
strcpy(save_filename, Main_filename); strcpy(save_filename, Selector_filename);
if (Readline(82,48,Main_filename,27,2)) if (Readline(82,48,Selector_filename,27,2))
{ {
// On regarde s'il faut rajouter une extension. C'est-à-dire s'il // On regarde s'il faut rajouter une extension. C'est-à-dire s'il
// n'y a pas de '.' dans le nom du fichier. // n'y a pas de '.' dans le nom du fichier.
for(temp=0,dummy=0; ((Main_filename[temp]) && (!dummy)); temp++) for(temp=0,dummy=0; ((Selector_filename[temp]) && (!dummy)); temp++)
if (Main_filename[temp]=='.') if (Selector_filename[temp]=='.')
dummy=1; dummy=1;
if (!dummy) if (!dummy)
{ {
if (Get_fileformat(Main_format)->Default_extension) if (Get_fileformat(Main_format)->Default_extension)
{ {
if(!Directory_exists(Main_filename)) if(!Directory_exists(Selector_filename))
{ {
strcat(Main_filename, "."); strcat(Selector_filename, ".");
strcat(Main_filename,Get_fileformat(Main_format)->Default_extension); strcat(Selector_filename,Get_fileformat(Main_format)->Default_extension);
} }
} }
else else
@ -1381,19 +1374,19 @@ byte Button_Load_or_Save(byte load, byte image)
// put default extension // put default extension
// (but maybe we should browse through all available ones until we find // (but maybe we should browse through all available ones until we find
// something suitable ?) // something suitable ?)
if(!Directory_exists(Main_filename)) if(!Directory_exists(Selector_filename))
{ {
strcat(Main_filename, ".pkm"); strcat(Selector_filename, ".pkm");
} }
} }
} }
if(load) if(load)
{ {
// Determine the type // Determine the type
if(File_exists(Main_filename)) if(File_exists(Selector_filename))
{ {
Selected_type = 0; Selected_type = 0;
if(Directory_exists(Main_filename)) Selected_type = 1; if(Directory_exists(Selector_filename)) Selected_type = 1;
} }
else else
{ {
@ -1402,7 +1395,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
else else
{ {
if(Directory_exists(Main_filename)) Selected_type = 1; if(Directory_exists(Selector_filename)) Selected_type = 1;
else Selected_type = 0; else Selected_type = 0;
} }
@ -1412,7 +1405,7 @@ byte Button_Load_or_Save(byte load, byte image)
else else
{ {
// Restore the old filename // Restore the old filename
strcpy(Main_filename, save_filename); strcpy(Selector_filename, save_filename);
Print_filename_in_fileselector(); Print_filename_in_fileselector();
} }
Display_cursor(); Display_cursor();
@ -1443,7 +1436,7 @@ byte Button_Load_or_Save(byte load, byte image)
if (Config.Bookmark_directory[clicked_button-10]) if (Config.Bookmark_directory[clicked_button-10])
{ {
*quicksearch_filename=0; *quicksearch_filename=0;
strcpy(Main_filename,Config.Bookmark_directory[clicked_button-10]); strcpy(Selector_filename,Config.Bookmark_directory[clicked_button-10]);
Selected_type=1; Selected_type=1;
has_clicked_ok=1; has_clicked_ok=1;
*quicksearch_filename=0; *quicksearch_filename=0;
@ -1567,7 +1560,7 @@ byte Button_Load_or_Save(byte load, byte image)
if (!strcmp(Filelist.First->Full_name,PARENT_DIR)) if (!strcmp(Filelist.First->Full_name,PARENT_DIR))
{ {
// On va dans le répertoire parent. // On va dans le répertoire parent.
strcpy(Main_filename,PARENT_DIR); strcpy(Selector_filename,PARENT_DIR);
Selected_type=1; Selected_type=1;
has_clicked_ok=1; has_clicked_ok=1;
} }
@ -1622,7 +1615,7 @@ byte Button_Load_or_Save(byte load, byte image)
has_clicked_ok=0; has_clicked_ok=0;
// On mémorise le répertoire dans lequel on était // On mémorise le répertoire dans lequel on était
if (strcmp(Main_filename,PARENT_DIR)) if (strcmp(Selector_filename,PARENT_DIR))
strcpy(previous_directory,Format_filename(PARENT_DIR, 1)); strcpy(previous_directory,Format_filename(PARENT_DIR, 1));
else else
{ {
@ -1632,7 +1625,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
// On doit rentrer dans le répertoire: // On doit rentrer dans le répertoire:
if (!chdir(Main_filename)) if (!chdir(Selector_filename))
{ {
getcwd(Main_current_directory,256); getcwd(Main_current_directory,256);
@ -1654,7 +1647,7 @@ byte Button_Load_or_Save(byte load, byte image)
} }
else // Sinon on essaye de charger ou sauver le fichier else // Sinon on essaye de charger ou sauver le fichier
{ {
strcpy(Main_file_directory,Main_current_directory); strcpy(context->File_directory,Main_current_directory);
if (!load) if (!load)
Main_fileformat=Main_format; Main_fileformat=Main_format;
save_or_load_image=1; save_or_load_image=1;
@ -1682,7 +1675,7 @@ byte Button_Load_or_Save(byte load, byte image)
// Affichage du commentaire // Affichage du commentaire
if ( (!load) && (Get_fileformat(Main_format)->Comment) ) if ( (!load) && (Get_fileformat(Main_format)->Comment) )
{ {
Print_in_window(45,70,Main_comment,MC_Black,MC_Light); Print_in_window(45,70,context->Comment,MC_Black,MC_Light);
} }
Display_cursor(); Display_cursor();
// Un update pour couvrir les 4 zones: 3 libellés plus le commentaire // Un update pour couvrir les 4 zones: 3 libellés plus le commentaire
@ -1704,20 +1697,17 @@ byte Button_Load_or_Save(byte load, byte image)
{ {
if ( (Main_fileselector_position+Main_fileselector_offset>=Filelist.Nb_directories) && (Filelist.Nb_elements) ) if ( (Main_fileselector_position+Main_fileselector_offset>=Filelist.Nb_directories) && (Filelist.Nb_elements) )
{ {
strcpy(Main_file_directory,Main_current_directory); T_IO_Context preview_context;
Init_context_preview(&preview_context, Selector_filename, Main_current_directory);
Hide_cursor(); Hide_cursor();
Load_image(image);
//Update_window_area(183,95,120,80); Load_image(&preview_context);
Destroy_context(&preview_context);
Update_window_area(0,0,Window_width,Window_height); Update_window_area(0,0,Window_width,Window_height);
Display_cursor(); Display_cursor();
// Après le chargement de la preview, on restaure tout ce qui aurait
// pu être modifié par le chargement de l'image:
memcpy(Main_palette,initial_palette,sizeof(T_Palette));
Main_image_is_modified=initial_image_is_modified;
Main_image_width=initial_image_width;
Main_image_height=initial_image_height;
} }
Timer_state=2; // On arrête le chrono Timer_state=2; // On arrête le chrono
@ -1725,19 +1715,22 @@ byte Button_Load_or_Save(byte load, byte image)
} }
while ( (!has_clicked_ok) && (clicked_button!=2) ); while ( (!has_clicked_ok) && (clicked_button!=2) );
// Si on annule, on restaure l'ancien commentaire if (has_clicked_ok)
if (clicked_button==2) {
strcpy(Main_comment,initial_comment); strcpy(context->File_name, Selector_filename);
strcpy(context->File_directory, Main_current_directory);
}
else
{
// Data to restore
strcpy(context->Comment, initial_comment);
}
// On restaure les données de l'image qui ont certainement été modifiées // On restaure les données de l'image qui ont certainement été modifiées
// par la preview. // par la preview.
memcpy(Main_palette,initial_palette,sizeof(T_Palette));
Set_palette(Main_palette);
Back_color=old_back_color;
Main_image_is_modified=initial_image_is_modified;
Main_image_width=initial_image_width;
Main_image_height=initial_image_height;
Set_palette(Main_palette); Set_palette(Main_palette);
Back_color=initial_back_color;
Compute_optimal_menu_colors(Main_palette); Compute_optimal_menu_colors(Main_palette);
temp=(Window_pos_Y+(Window_height*Menu_factor_Y)<Menu_Y_before_window); temp=(Window_pos_Y+(Window_height*Menu_factor_Y)<Menu_Y_before_window);
@ -1751,9 +1744,5 @@ byte Button_Load_or_Save(byte load, byte image)
Display_cursor(); Display_cursor();
Free_fileselector_list(&Filelist); Free_fileselector_list(&Filelist);
Pixel_load_function=Pixel_load_in_current_screen;
free(initial_palette);
return save_or_load_image; return save_or_load_image;
} }

View File

@ -27,8 +27,9 @@
#define __FILESEL_H__ #define __FILESEL_H__
#include "struct.h" #include "struct.h"
#include "loadsave.h"
byte Button_Load_or_Save(byte load, byte image); byte Button_Load_or_Save(byte load, T_IO_Context *context);
void Add_element_to_list(T_Fileselector *list, const char * fname, int type); void Add_element_to_list(T_Fileselector *list, const char * fname, int type);
/// ///

View File

@ -341,6 +341,14 @@ GFX2_GLOBAL short Main_magnifier_offset_Y;
GFX2_GLOBAL byte Main_current_layer; GFX2_GLOBAL byte 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.
GFX2_GLOBAL long Main_safety_number;
/// Number of edit actions since the last safety backup
GFX2_GLOBAL long Main_edits_since_safety_backup;
/// SDL Time of the previous safety backup
GFX2_GLOBAL Uint32 Main_time_of_safety_backup;
/// Letter prefix for the filenames of safety backups. a or b
GFX2_GLOBAL byte Main_safety_backup_prefix;
// -- Spare page data // -- Spare page data
@ -405,6 +413,15 @@ GFX2_GLOBAL short Spare_magnifier_offset_Y;
GFX2_GLOBAL byte Spare_current_layer; GFX2_GLOBAL byte 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.
GFX2_GLOBAL long Spare_safety_number;
/// Number of edit actions since the last safety backup
GFX2_GLOBAL long Spare_edits_since_safety_backup;
/// SDL Time of the previous safety backup
GFX2_GLOBAL Uint32 Spare_time_of_safety_backup;
/// Letter prefix for the filenames of safety backups. a or b
GFX2_GLOBAL byte Spare_safety_backup_prefix;
// -- Image backups // -- Image backups
/// Backup of the current screen, used during drawing when FX feedback is OFF. /// Backup of the current screen, used during drawing when FX feedback is OFF.
@ -801,8 +818,6 @@ GFX2_GLOBAL byte Selected_curve_mode;
GFX2_GLOBAL byte Selected_line_mode; GFX2_GLOBAL byte Selected_line_mode;
/// Determines which color appears in the first cell of the menu palette. Change this value to "scroll" the palette. /// Determines which color appears in the first cell of the menu palette. Change this value to "scroll" the palette.
GFX2_GLOBAL byte First_color_in_palette; GFX2_GLOBAL byte First_color_in_palette;
/// Boolean, true if Grafx2 was run with a file as command-line argument, which must be open immediately.
GFX2_GLOBAL byte File_in_command_line;
/// Boolean, true if Grafx2 was run with a command-line argument to set a resolution on startup (overrides config) /// Boolean, true if Grafx2 was run with a command-line argument to set a resolution on startup (overrides config)
GFX2_GLOBAL byte Resolution_in_command_line; GFX2_GLOBAL byte Resolution_in_command_line;
@ -912,14 +927,6 @@ GFX2_GLOBAL struct
GFX2_GLOBAL signed char File_error; GFX2_GLOBAL signed char File_error;
/// Current line number when reading/writing gfx2.ini /// Current line number when reading/writing gfx2.ini
GFX2_GLOBAL int Line_number_in_INI_file; GFX2_GLOBAL int Line_number_in_INI_file;
///
/// Pointer to a pixel-loading function. This is used by the generic loading
/// function to load a preview, a brush or an image.
GFX2_GLOBAL Func_pixel Pixel_load_function;
///
/// Pointer to a pixel-reading function. This is used by the generic saving
/// function to save a brush or an image.
GFX2_GLOBAL Func_read Read_pixel_function;
// -- Specific to SDL // -- Specific to SDL

16
io.c
View File

@ -252,8 +252,12 @@ void For_each_file(const char * directory_name, void Callback(const char *))
strcpy(full_filename, directory_name); strcpy(full_filename, directory_name);
current_directory=opendir(directory_name); current_directory=opendir(directory_name);
if(current_directory == NULL) return; // Répertoire invalide ... if(current_directory == NULL) return; // Répertoire invalide ...
filename_position = strlen(full_filename);
if (filename_position==0 || strcmp(full_filename+filename_position-1,PATH_SEPARATOR))
{
strcat(full_filename, PATH_SEPARATOR); strcat(full_filename, PATH_SEPARATOR);
filename_position = strlen(full_filename); filename_position = strlen(full_filename);
}
while ((entry=readdir(current_directory))) while ((entry=readdir(current_directory)))
{ {
struct stat Infos_enreg; struct stat Infos_enreg;
@ -267,3 +271,15 @@ void For_each_file(const char * directory_name, void Callback(const char *))
closedir(current_directory); closedir(current_directory);
} }
void Get_full_filename(char * output_name, char * file_name, char * directory_name)
{
strcpy(output_name,directory_name);
// Append a separator at the end of path, if there isn't one already.
// This handles the case of directory variables which contain one,
// as well as directories like "/" on Unix.
if (output_name[strlen(output_name)-1]!=PATH_SEPARATOR[0])
strcat(output_name,PATH_SEPARATOR);
strcat(output_name,file_name);
}

5
io.h
View File

@ -89,3 +89,8 @@ int Directory_exists(char * directory);
/// Scans a directory, calls Callback for each file in it, /// Scans a directory, calls Callback for each file in it,
void For_each_file(const char * directory_name, void Callback(const char *)); void For_each_file(const char * directory_name, void Callback(const char *));
///
/// Creates a fully qualified name from a directory and filename.
/// The point is simply to insert a PATH_SEPARATOR when needed.
void Get_full_filename(char * output_name, char * file_name, char * directory_name);

View File

@ -10,7 +10,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "const.h"
#include "global.h" #include "global.h"
#include "struct.h"
#include "loadsave.h"
unsigned short addrCalc(unsigned char vcc, unsigned char rcc, unsigned char hcc, unsigned char cclk, unsigned char r1, unsigned char r12, unsigned char r13) unsigned short addrCalc(unsigned char vcc, unsigned char rcc, unsigned char hcc, unsigned char cclk, unsigned char r1, unsigned char r12, unsigned char r13)
{ {
@ -26,35 +29,35 @@ unsigned short addrCalc(unsigned char vcc, unsigned char rcc, unsigned char hcc,
return addr; return addr;
} }
unsigned char mode0interlace(unsigned char x, unsigned char y) unsigned char mode0interlace(T_IO_Context * context, unsigned char x, unsigned char y)
{ {
unsigned char mode0pixel[] = {0, 64, 4, 68, 16, 80, 20, 84, 1, 65, 5, 69, 17, 81, 21, 85}; unsigned char mode0pixel[] = {0, 64, 4, 68, 16, 80, 20, 84, 1, 65, 5, 69, 17, 81, 21, 85};
return mode0pixel[Read_pixel_function(x,y)] << 1 | mode0pixel[Read_pixel_function(x+1,y)]; return mode0pixel[Get_pixel(context,x,y)] << 1 | mode0pixel[Get_pixel(context,x+1,y)];
} }
unsigned char mode1interlace(unsigned char x, unsigned char y) unsigned char mode1interlace(T_IO_Context * context, unsigned char x, unsigned char y)
{ {
unsigned char mode1pixel[] = {0, 16, 1, 17}; unsigned char mode1pixel[] = {0, 16, 1, 17};
return mode1pixel[Read_pixel_function(x,y)] << 3 | mode1pixel[Read_pixel_function(x+1,y)] << 2 | mode1pixel[Read_pixel_function(x+2,y)] << 1 | mode1pixel[Read_pixel_function(x+3,y)]; return mode1pixel[Get_pixel(context,x,y)] << 3 | mode1pixel[Get_pixel(context,x+1,y)] << 2 | mode1pixel[Get_pixel(context,x+2,y)] << 1 | mode1pixel[Get_pixel(context,x+3,y)];
} }
unsigned char mode2interlace(unsigned char x, unsigned char y) unsigned char mode2interlace(T_IO_Context * context, unsigned char x, unsigned char y)
{ {
unsigned char out = 0; unsigned char out = 0;
int i; int i;
for(i = 0; i < 8; i++) out += ((Read_pixel_function(x+7-i,y)&1) << i); for(i = 0; i < 8; i++) out += ((Get_pixel(context,x+7-i,y)&1) << i);
return out; return out;
} }
unsigned char mode3interlace(unsigned char x, unsigned char y) unsigned char mode3interlace(T_IO_Context * context, unsigned char x, unsigned char y)
{ {
unsigned char mode3pixel[] = {0, 16, 1, 17}; unsigned char mode3pixel[] = {0, 16, 1, 17};
return mode3pixel[Read_pixel_function(x,y)] << 3 | mode3pixel[Read_pixel_function(x+1,y)] << 2; return mode3pixel[Get_pixel(context, x,y)] << 3 | mode3pixel[Get_pixel(context,x+1,y)] << 2;
} }
unsigned char (*ptrMode)(unsigned char x, unsigned char y); unsigned char (*ptrMode)(T_IO_Context * context, unsigned char x, unsigned char y);
unsigned char *raw2crtc(unsigned short width, unsigned short height, unsigned char mode, unsigned char r9, unsigned long *outSize, unsigned char *r1, unsigned char r12, unsigned char r13) unsigned char *raw2crtc(T_IO_Context *context, unsigned short width, unsigned short height, unsigned char mode, unsigned char r9, unsigned long *outSize, unsigned char *r1, unsigned char r12, unsigned char r13)
{ {
unsigned char *outBuffer; unsigned char *outBuffer;
unsigned char *tmpBuffer; unsigned char *tmpBuffer;
@ -137,7 +140,7 @@ unsigned char *raw2crtc(unsigned short width, unsigned short height, unsigned ch
{ {
x = (hcc << 1 | cclk); x = (hcc << 1 | cclk);
y = vcc*(r9+1) + rcc; y = vcc*(r9+1) + rcc;
*(tmpBuffer + addrCalc(vcc, rcc, hcc, cclk, *r1, r12, r13)) = (*ptrMode)(x,y); *(tmpBuffer + addrCalc(vcc, rcc, hcc, cclk, *r1, r12, r13)) = (*ptrMode)(context,x,y);
*(allocationBuffer + addrCalc(vcc, rcc, hcc, cclk, *r1, r12, r13)) += 1; *(allocationBuffer + addrCalc(vcc, rcc, hcc, cclk, *r1, r12, r13)) += 1;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -24,30 +24,108 @@
/// Also handles showing the preview in fileselectors. /// Also handles showing the preview in fileselectors.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#ifndef __LOADSAVE_H__
#define __LOADSAVE_H__
#include <stdio.h>
enum CONTEXT_TYPE {
CONTEXT_MAIN_IMAGE,
CONTEXT_BRUSH,
CONTEXT_PREVIEW,
};
typedef struct
{
/// Kind of context. Internally used to differentiate the "sub-classes"
enum CONTEXT_TYPE Type;
// File properties
char * File_name;
char * File_directory;
byte Format;
// Image properties
T_Palette Palette;
short Width;
short Height;
byte Nb_layers;
char Comment[COMMENT_SIZE+1];
short Transparent_color;
/// Pixel ratio of the image
enum PIXEL_RATIO Ratio;
/// Load/save address of first pixel
byte *Target_address;
/// Pitch: Difference of addresses between one pixel and the one just "below" it
long Pitch;
/// Internal: Used to mark truecolor images on loading. Only used by preview.
//byte Is_truecolor;
/// Internal: Temporary RGB buffer when loading 24bit images
T_Components *Buffer_image_24b;
/// Internal: Temporary buffer when saving the flattened copy of something
byte *Buffer_image;
// Internal: working data for preview case
short Preview_factor_X;
short Preview_factor_Y;
short Preview_pos_X;
short Preview_pos_Y;
} T_IO_Context;
/// Type of a function that can be called for a T_IO_Context. Kind of a method.
typedef void (* Func_IO) (T_IO_Context *);
/*
void Pixel_load_in_current_screen (word x_pos, word y_pos, byte color); void Pixel_load_in_current_screen (word x_pos, word y_pos, byte color);
void Pixel_load_in_preview (word x_pos, word y_pos, byte color); void Pixel_load_in_preview (word x_pos, word y_pos, byte color);
void Pixel_load_in_brush (word x_pos, word y_pos, byte color); void Pixel_load_in_brush (word x_pos, word y_pos, byte color);
*/
void Get_full_filename(char * filename, byte is_colorix_format); // Setup for loading a preview in fileselector
void Init_context_preview(T_IO_Context * context, char *file_name, char *file_directory);
// Setup for loading/saving the current main image
void Init_context_layered_image(T_IO_Context * context, char *file_name, char *file_directory);
// Setup for loading/saving the flattened version of current main image
void Init_context_flat_image(T_IO_Context * context, char *file_name, char *file_directory);
// Setup for loading/saving the user's brush
void Init_context_brush(T_IO_Context * context, char *file_name, char *file_directory);
// Setup for saving an arbitrary undo/redo step, from either the main or spare page.
void Init_context_history_step(T_IO_Context * context, T_Page *page);
// Cleans up resources (currently: the 24bit buffer)
void Destroy_context(T_IO_Context *context);
/// ///
/// High-level picture loading function. /// High-level picture loading function.
/// Handles loading an image or a brush, or previewing only. void Load_image(T_IO_Context *context);
/// @param image true if the fileselector is the one for loading images (not brush)
void Load_image(byte image);
/// ///
/// High-level picture saving function. /// High-level picture saving function.
/// @param image true if the image should be saved (instead of the brush) void Save_image(T_IO_Context *context);
void Save_image(byte image);
///
/// Checks if there are any pending safety backups, and then opens them.
/// Returns 0 if there were none
/// Returns non-zero if some backups were loaded.
int Check_recovery(void);
/// Remove safety backups. Need to call on normal program exit.
void Delete_safety_backups(void);
/// Data for an image file format. /// Data for an image file format.
typedef struct { typedef struct {
byte Identifier; ///< Identifier for this format in enum :FILE_FORMATS byte Identifier; ///< Identifier for this format in enum :FILE_FORMATS
char *Label; ///< Five-letter label char *Label; ///< Five-letter label
Func_action Test; ///< Function which tests if the file is of this format Func_IO Test; ///< Function which tests if the file is of this format
Func_action Load; ///< Function which loads an image of this format Func_IO Load; ///< Function which loads an image of this format
Func_action Save; ///< Function which saves an image of this format Func_IO Save; ///< Function which saves an image of this format
byte Palette_only; ///< Boolean, true if this format saves/loads only the palette. byte Palette_only; ///< Boolean, true if this format saves/loads only the palette.
byte Comment; ///< This file format allows a text comment byte Comment; ///< This file format allows a text comment
byte Supports_layers; ///< Boolean, true if this format preserves layers on saving byte Supports_layers; ///< Boolean, true if this format preserves layers on saving
@ -63,8 +141,10 @@ extern T_Format File_formats[];
/// called in case of SIGSEGV. /// called in case of SIGSEGV.
void Image_emergency_backup(void); void Image_emergency_backup(void);
/*
/// Pixel ratio of last loaded image: one of :PIXEL_SIMPLE, :PIXEL_WIDE or :PIXEL_TALL /// Pixel ratio of last loaded image: one of :PIXEL_SIMPLE, :PIXEL_WIDE or :PIXEL_TALL
extern enum PIXEL_RATIO Ratio_of_loaded_image; extern enum PIXEL_RATIO Ratio_of_loaded_image;
*/
T_Format * Get_fileformat(byte format); T_Format * Get_fileformat(byte format);
@ -77,6 +157,25 @@ T_Format * Get_fileformat(byte format);
#define NB_KNOWN_FORMATS 18 ///< Total number of known file formats. #define NB_KNOWN_FORMATS 18 ///< Total number of known file formats.
#endif #endif
// Internal use
/// Generic allocation and similar stuff, done at beginning of image load, as soon as size is known.
void Pre_load(T_IO_Context *context, short width, short height, long file_size, int format, enum PIXEL_RATIO ratio, byte truecolor);
/// Remaps the window. To call after palette (last) changes.
void Remap_fileselector(T_IO_Context *context);
/// Generic cleanup done on end of loading (ex: color-conversion from the temporary 24b buffer)
//void Post_load(T_IO_Context *context);
/// Query the color of a pixel (to save)
byte Get_pixel(T_IO_Context *context, short x, short y);
/// Set the color of a pixel (on load)
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_layer(T_IO_Context *context, byte layer);
// ================================================================= // =================================================================
// What follows here are the definitions of functions and data // What follows here are the definitions of functions and data
// useful for fileformats.c, miscfileformats.c etc. // useful for fileformats.c, miscfileformats.c etc.
@ -96,6 +195,7 @@ typedef struct
// Data for 24bit loading // Data for 24bit loading
/*
typedef void (* Func_24b_display) (short,short,byte,byte,byte); typedef void (* Func_24b_display) (short,short,byte,byte,byte);
extern int Image_24b; extern int Image_24b;
@ -104,14 +204,16 @@ extern Func_24b_display Pixel_load_24b;
void Init_preview_24b(short width,short height,long size,int format); void Init_preview_24b(short width,short height,long size,int format);
void Pixel_load_in_24b_preview(short x_pos,short y_pos,byte r,byte g,byte b); void Pixel_load_in_24b_preview(short x_pos,short y_pos,byte r,byte g,byte b);
*/
// //
void Set_file_error(int value); void Set_file_error(int value);
void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio);
/*
void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio);
*/
void Init_write_buffer(void); void Init_write_buffer(void);
void Write_one_byte(FILE *file, byte b); void Write_one_byte(FILE *file, byte b);
void End_write(FILE *file); void End_write(FILE *file);
void Remap_fileselector(void); #endif

181
main.c
View File

@ -212,12 +212,13 @@ struct {
#define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof(x[0])) #define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof(x[0]))
// --------------------- Analyse de la ligne de commande --------------------- // --------------------- Analyse de la ligne de commande ---------------------
void Analyze_command_line(int argc, char * argv[]) int Analyze_command_line(int argc, char * argv[], char *main_filename, char *main_directory, char *spare_filename, char *spare_directory)
{ {
char *buffer ; char *buffer ;
int index; int index;
int file_in_command_line;
File_in_command_line = 0; file_in_command_line = 0;
Resolution_in_command_line = 0; Resolution_in_command_line = 0;
Current_resolution = Config.Default_resolution; Current_resolution = Config.Default_resolution;
@ -347,7 +348,7 @@ void Analyze_command_line(int argc, char * argv[])
break; break;
default: default:
// Si ce n'est pas un paramètre, c'est le nom du fichier à ouvrir // Si ce n'est pas un paramètre, c'est le nom du fichier à ouvrir
if (File_in_command_line > 1) if (file_in_command_line > 1)
{ {
// Il y a déjà 2 noms de fichiers et on vient d'en trouver un 3ème // Il y a déjà 2 noms de fichiers et on vient d'en trouver un 3ème
Error(ERROR_COMMAND_LINE); Error(ERROR_COMMAND_LINE);
@ -356,22 +357,22 @@ void Analyze_command_line(int argc, char * argv[])
} }
else if (File_exists(argv[index])) else if (File_exists(argv[index]))
{ {
File_in_command_line ++; file_in_command_line ++;
buffer = Realpath(argv[index], NULL); buffer = Realpath(argv[index], NULL);
if (File_in_command_line == 1) if (file_in_command_line == 1)
{ {
// Separate path from filename // Separate path from filename
Extract_path(Main_file_directory, buffer); Extract_path(main_directory, buffer);
Extract_filename(Main_filename, buffer); Extract_filename(main_filename, buffer);
free(buffer);
} }
else else
{ {
Extract_path(Spare_file_directory, buffer); // Separate path from filename
Extract_filename(Spare_filename, buffer); Extract_path(spare_directory, buffer);
free(buffer); Extract_filename(spare_filename, buffer);
} }
free(buffer);
} }
else else
{ {
@ -382,6 +383,7 @@ void Analyze_command_line(int argc, char * argv[])
break; break;
} }
} }
return file_in_command_line;
} }
// ------------------------ Initialiser le programme ------------------------- // ------------------------ Initialiser le programme -------------------------
@ -390,8 +392,15 @@ int Init_program(int argc,char * argv[])
{ {
int temp; int temp;
int starting_videomode; int starting_videomode;
char program_directory[MAX_PATH_CHARACTERS]; static char program_directory[MAX_PATH_CHARACTERS];
T_Gui_skin *gfx; T_Gui_skin *gfx;
int file_in_command_line;
static char main_filename [MAX_PATH_CHARACTERS];
static char main_directory[MAX_PATH_CHARACTERS];
static char spare_filename [MAX_PATH_CHARACTERS];
static char spare_directory[MAX_PATH_CHARACTERS];
// On crée dès maintenant les descripteurs des listes de pages pour la page // On crée dès maintenant les descripteurs des listes de pages pour la page
// principale et la page de brouillon afin que leurs champs ne soient pas // principale et la page de brouillon afin que leurs champs ne soient pas
@ -415,19 +424,15 @@ int Init_program(int argc,char * argv[])
// On en profite pour le mémoriser dans le répertoire principal: // On en profite pour le mémoriser dans le répertoire principal:
strcpy(Initial_directory,Main_current_directory); strcpy(Initial_directory,Main_current_directory);
// On initialise les données sur le nom de fichier de l'image principale:
strcpy(Main_file_directory,Main_current_directory);
strcpy(Main_filename,"NO_NAME.GIF");
Main_fileformat=DEFAULT_FILEFORMAT;
// On initialise les données sur le nom de fichier de l'image de brouillon: // On initialise les données sur le nom de fichier de l'image de brouillon:
strcpy(Spare_current_directory,Main_current_directory); strcpy(Spare_current_directory,Main_current_directory);
strcpy(Spare_file_directory,Main_file_directory);
strcpy(Spare_filename ,Main_filename); Main_fileformat=DEFAULT_FILEFORMAT;
Spare_fileformat =Main_fileformat; Spare_fileformat =Main_fileformat;
strcpy(Brush_current_directory,Main_current_directory); strcpy(Brush_current_directory,Main_current_directory);
strcpy(Brush_file_directory,Main_file_directory); strcpy(Brush_file_directory,Main_current_directory);
strcpy(Brush_filename ,Main_filename); strcpy(Brush_filename ,"NO_NAME.GIF");
Brush_fileformat =Main_fileformat; Brush_fileformat =Main_fileformat;
// On initialise ce qu'il faut pour que les fileselects ne plantent pas: // On initialise ce qu'il faut pour que les fileselects ne plantent pas:
@ -449,7 +454,6 @@ int Init_program(int argc,char * argv[])
// On initialise les commentaires des images à des chaînes vides // On initialise les commentaires des images à des chaînes vides
Main_comment[0]='\0'; Main_comment[0]='\0';
Spare_comment[0]='\0';
Brush_comment[0]='\0'; Brush_comment[0]='\0';
// On initialise d'ot' trucs // On initialise d'ot' trucs
@ -481,6 +485,12 @@ int Init_program(int argc,char * argv[])
Spare_magnifier_offset_Y=0; Spare_magnifier_offset_Y=0;
Keyboard_click_allowed = 0; Keyboard_click_allowed = 0;
Main_safety_backup_prefix = 'a';
Spare_safety_backup_prefix = 'b';
Main_time_of_safety_backup = 0;
Spare_time_of_safety_backup = 0;
// SDL // SDL
if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0) if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0)
{ {
@ -515,6 +525,7 @@ int Init_program(int argc,char * argv[])
SDL_FreeSurface(icon); SDL_FreeSurface(icon);
} }
} }
// Texte // Texte
Init_text(); Init_text();
@ -539,8 +550,6 @@ int Init_program(int argc,char * argv[])
Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND; Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND;
Paintbrush_hidden=0; Paintbrush_hidden=0;
Pixel_load_function=Pixel_load_in_current_screen;
// On initialise tout ce qui concerne les opérations et les effets // On initialise tout ce qui concerne les opérations et les effets
Operation_stack_size=0; Operation_stack_size=0;
Selected_freehand_mode=OPERATION_CONTINUOUS_DRAW; Selected_freehand_mode=OPERATION_CONTINUOUS_DRAW;
@ -618,7 +627,7 @@ int Init_program(int argc,char * argv[])
if (temp) if (temp)
Error(temp); Error(temp);
Analyze_command_line(argc, argv); file_in_command_line=Analyze_command_line(argc, argv, main_filename, main_directory, spare_filename, spare_directory);
Current_help_section=0; Current_help_section=0;
Help_position=0; Help_position=0;
@ -702,18 +711,6 @@ int Init_program(int argc,char * argv[])
// Allocation de mémoire pour les différents écrans virtuels (et brosse) // Allocation de mémoire pour les différents écrans virtuels (et brosse)
if (Init_all_backup_lists(Screen_width,Screen_height)==0) if (Init_all_backup_lists(Screen_width,Screen_height)==0)
Error(ERROR_MEMORY); Error(ERROR_MEMORY);
// On remet le nom par défaut pour la page de brouillon car il été modifié
// par le passage d'un fichier en paramètre lors du traitement précédent.
// Note: le fait que l'on ne modifie que les variables globales
// Brouillon_* et pas les infos contenues dans la page de brouillon
// elle-même ne m'inspire pas confiance mais ça a l'air de marcher sans
// poser de problèmes, alors...
if (File_in_command_line == 1)
{
strcpy(Spare_file_directory,Spare_current_directory);
strcpy(Spare_filename,"NO_NAME.GIF");
Spare_fileformat=DEFAULT_FILEFORMAT;
}
// Nettoyage de l'écran virtuel (les autres recevront celui-ci par copie) // Nettoyage de l'écran virtuel (les autres recevront celui-ci par copie)
memset(Main_screen,0,Main_image_width*Main_image_height); memset(Main_screen,0,Main_image_width*Main_image_height);
@ -745,6 +742,51 @@ int Init_program(int argc,char * argv[])
Brush_height=1; Brush_height=1;
Capture_brush(0,0,0,0,0); Capture_brush(0,0,0,0,0);
*Brush=MC_White; *Brush=MC_White;
// Test de recuperation de fichiers sauvés
if (Check_recovery())
{
// Some files were loaded from last crash-exit.
// Do not load files from command-line, nor show splash screen.
}
else
{
T_IO_Context context;
switch (file_in_command_line)
{
case 0:
if (Config.Opening_message)
Button_Message_initial();
break;
case 2:
// Load this file
Init_context_layered_image(&context, spare_filename, spare_directory);
Load_image(&context);
Destroy_context(&context);
Redraw_layered_image();
Button_Page();
// no break ! proceed with the other file now
case 1:
Init_context_layered_image(&context, main_filename, main_directory);
Load_image(&context);
Destroy_context(&context);
Redraw_layered_image();
Hide_cursor();
Compute_optimal_menu_colors(Main_palette);
Display_all_screen();
Display_menu();
Display_cursor();
Resolution_in_command_line = 0;
break;
default:
break;
}
}
return(1); return(1);
} }
@ -772,6 +814,9 @@ void Program_shutdown(void)
Config.Window_pos_y = 9999; Config.Window_pos_y = 9999;
#endif #endif
// Remove the safety backups, this is normal exit
Delete_safety_backups();
// On libère le buffer de gestion de lignes // On libère le buffer de gestion de lignes
if(Horizontal_line_buffer) free(Horizontal_line_buffer); if(Horizontal_line_buffer) free(Horizontal_line_buffer);
@ -815,73 +860,13 @@ void Program_shutdown(void)
// -------------------------- Procédure principale --------------------------- // -------------------------- Procédure principale ---------------------------
int main(int argc,char * argv[]) int main(int argc,char * argv[])
{ {
int phoenix_found=0;
int phoenix2_found=0;
char phoenix_filename1[MAX_PATH_CHARACTERS];
char phoenix_filename2[MAX_PATH_CHARACTERS];
if(!Init_program(argc,argv)) if(!Init_program(argc,argv))
{ {
Program_shutdown(); Program_shutdown();
return 0; return 0;
} }
// Test de recuperation de fichiers sauvés
strcpy(phoenix_filename1,Config_directory);
strcat(phoenix_filename1,"phoenix.img");
strcpy(phoenix_filename2,Config_directory);
strcat(phoenix_filename2,"phoenix2.img");
if (File_exists(phoenix_filename1))
phoenix_found=1;
if (File_exists(phoenix_filename2))
phoenix2_found=1;
if (phoenix_found || phoenix2_found)
{
if (phoenix2_found)
{
strcpy(Main_file_directory,Config_directory);
strcpy(Main_filename,"phoenix2.img");
chdir(Main_file_directory);
Button_Reload();
Main_image_is_modified=1;
Warning_message("Spare page recovered");
// I don't really like this, but...
remove(phoenix_filename2);
Button_Page();
}
if (phoenix_found)
{
strcpy(Main_file_directory,Config_directory);
strcpy(Main_filename,"phoenix.img");
chdir(Main_file_directory);
Button_Reload();
Main_image_is_modified=1;
Warning_message("Main page recovered");
// I don't really like this, but...
remove(phoenix_filename1);
}
}
else
{
if (Config.Opening_message && (!File_in_command_line))
Button_Message_initial();
switch (File_in_command_line)
{
case 2:
Button_Reload();
DEBUG(Main_filename, 0);
DEBUG(Spare_filename, 0);
Button_Page();
// no break ! proceed with the other file now
case 1:
Button_Reload();
Resolution_in_command_line = 0;
default:
break;
}
}
Main_handler(); Main_handler();
Program_shutdown(); Program_shutdown();

File diff suppressed because it is too large Load Diff

37
pages.c
View File

@ -153,8 +153,6 @@ void Download_infos_page_main(T_Page * page)
Main_image_height=page->Height; Main_image_height=page->Height;
memcpy(Main_palette,page->Palette,sizeof(T_Palette)); memcpy(Main_palette,page->Palette,sizeof(T_Palette));
strcpy(Main_comment,page->Comment); strcpy(Main_comment,page->Comment);
strcpy(Main_file_directory,page->File_directory);
strcpy(Main_filename,page->Filename);
Main_fileformat=page->File_format; Main_fileformat=page->File_format;
if (size_is_modified) if (size_is_modified)
@ -302,8 +300,6 @@ void Upload_infos_page_main(T_Page * page)
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));
strcpy(page->Comment,Main_comment); strcpy(page->Comment,Main_comment);
strcpy(page->File_directory,Main_file_directory);
strcpy(page->Filename,Main_filename);
page->File_format=Main_fileformat; page->File_format=Main_fileformat;
} }
} }
@ -316,9 +312,6 @@ void Download_infos_page_spare(T_Page * page)
Spare_image_width=page->Width; Spare_image_width=page->Width;
Spare_image_height=page->Height; Spare_image_height=page->Height;
memcpy(Spare_palette,page->Palette,sizeof(T_Palette)); memcpy(Spare_palette,page->Palette,sizeof(T_Palette));
strcpy(Spare_comment,page->Comment);
strcpy(Spare_file_directory,page->File_directory);
strcpy(Spare_filename,page->Filename);
Spare_fileformat=page->File_format; Spare_fileformat=page->File_format;
} }
} }
@ -331,9 +324,6 @@ void Upload_infos_page_spare(T_Page * page)
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));
strcpy(page->Comment,Spare_comment);
strcpy(page->File_directory,Spare_file_directory);
strcpy(page->Filename,Spare_filename);
page->File_format=Spare_fileformat; page->File_format=Spare_fileformat;
} }
} }
@ -659,6 +649,10 @@ int Init_all_backup_lists(int width,int height)
// On y met les infos sur la dimension de démarrage // On y met les infos sur la dimension de démarrage
Main_backups->Pages->Width=width; Main_backups->Pages->Width=width;
Main_backups->Pages->Height=height; Main_backups->Pages->Height=height;
strcpy(Main_backups->Pages->File_directory,Main_current_directory);
strcpy(Main_backups->Pages->Filename,"NO_NAME.GIF");
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]=New_layer(width*height);
@ -698,8 +692,8 @@ int Init_all_backup_lists(int width,int height)
Spare_backups->Pages->Height = height; Spare_backups->Pages->Height = height;
memcpy(Spare_backups->Pages->Palette,Main_palette,sizeof(T_Palette)); memcpy(Spare_backups->Pages->Palette,Main_palette,sizeof(T_Palette));
strcpy(Spare_backups->Pages->Comment,""); strcpy(Spare_backups->Pages->Comment,"");
strcpy(Spare_backups->Pages->File_directory,Spare_current_directory); strcpy(Spare_backups->Pages->File_directory,Main_current_directory);
strcpy(Spare_backups->Pages->Filename,"NO_NAME.GIF"); strcpy(Spare_backups->Pages->Filename,"NO_NAME2.GIF");
Spare_backups->Pages->File_format=DEFAULT_FILEFORMAT; Spare_backups->Pages->File_format=DEFAULT_FILEFORMAT;
// Copy this informations in the global Spare_ variables // Copy this informations in the global Spare_ variables
Download_infos_page_spare(Spare_backups->Pages); Download_infos_page_spare(Spare_backups->Pages);
@ -756,6 +750,8 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
Upload_infos_page_main(new_page); Upload_infos_page_main(new_page);
new_page->Width=width; new_page->Width=width;
new_page->Height=height; new_page->Height=height;
strcpy(new_page->Filename, Main_backups->Pages->Filename);
strcpy(new_page->File_directory, Main_backups->Pages->File_directory);
if (Create_new_page(new_page,Main_backups,0xFFFFFFFF)) if (Create_new_page(new_page,Main_backups,0xFFFFFFFF))
{ {
for (i=0; i<layers;i++) for (i=0; i<layers;i++)
@ -766,7 +762,17 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
Update_buffers(width, height); Update_buffers(width, height);
Download_infos_page_main(Main_backups->Pages); Download_infos_page_main(Main_backups->Pages);
End_of_modification();
// Same code as in End_of_modification():
#ifndef NOLAYERS
memcpy(Main_visible_image_backup.Image,
Main_visible_image.Image,
Main_image_width*Main_image_height);
#else
Update_screen_targets();
#endif
Download_infos_backup(Main_backups);
// --
return_code=1; return_code=1;
} }
@ -1001,6 +1007,11 @@ void End_of_modification(void)
Last_backed_up_layers = 0; Last_backed_up_layers = 0;
Backup(); Backup();
*/ */
//
// Processing safety backups
//
Main_edits_since_safety_backup++;
Rotate_safety_backups();
} }
/// 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.

View File

@ -741,10 +741,10 @@ void Print_filename(void)
// Determine maximum size, in characters // Determine maximum size, in characters
max_size = 12 + (Screen_width / Menu_factor_X - 320) / 8; max_size = 12 + (Screen_width / Menu_factor_X - 320) / 8;
string_size = strlen(Main_filename); string_size = strlen(Main_backups->Pages->Filename);
// Partial copy of the name // Partial copy of the name
strncpy(display_string, Main_filename, max_size); strncpy(display_string, Main_backups->Pages->Filename, max_size);
display_string[max_size]='\0'; display_string[max_size]='\0';
if (string_size > max_size) if (string_size > max_size)