From 8bdd163ededfcbeeda4abf496e6a1bd7617a2810 Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Wed, 13 Jan 2010 02:09:47 +0000 Subject: [PATCH] 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 --- buttons.c | 308 +++++------ fileformats.c | 770 ++++++++++++++------------- filesel.c | 159 +++--- filesel.h | 3 +- global.h | 27 +- io.c | 18 +- io.h | 5 + libraw2crtc.c | 25 +- loadsave.c | 1284 ++++++++++++++++++++++++++++----------------- loadsave.h | 126 ++++- main.c | 181 +++---- miscfileformats.c | 436 +++++++-------- pages.c | 37 +- windows.c | 4 +- 14 files changed, 1903 insertions(+), 1480 deletions(-) diff --git a/buttons.c b/buttons.c index 0288332b..931fef94 100644 --- a/buttons.c +++ b/buttons.c @@ -543,30 +543,34 @@ byte Button_Quit_local_function(void) { case 1 : return 0; // Rester case 2 : // Sauver et enregistrer - Get_full_filename(filename,0); - if ( (!File_exists(filename)) || Confirmation_box("Erase old file ?") ) - { - Hide_cursor(); - old_cursor_shape=Cursor_shape; - Cursor_shape=CURSOR_SHAPE_HOURGLASS; - Display_cursor(); + Get_full_filename(filename, Main_backups->Pages->Filename, Main_backups->Pages->File_directory); + if ( (!File_exists(filename)) || Confirmation_box("Erase old file ?") ) + { + T_IO_Context save_context; - Save_image(1); - - Hide_cursor(); - Cursor_shape=old_cursor_shape; - Display_cursor(); - - if (!File_error) - // L'ayant sauvée avec succès, - return 1; // On peut quitter - else - // Il y a eu une erreur lors de la sauvegarde, - return 0; // On ne peut donc pas quitter - } - else - // L'utilisateur ne veut pas écraser l'ancien fichier, - return 0; // On doit donc rester + Hide_cursor(); + old_cursor_shape=Cursor_shape; + Cursor_shape=CURSOR_SHAPE_HOURGLASS; + Display_cursor(); + + 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(); + Cursor_shape=old_cursor_shape; + Display_cursor(); + + if (!File_error) + // L'ayant sauvée avec succès, + return 1; // On peut quitter + else + // Il y a eu une erreur lors de la sauvegarde, + return 0; // On ne peut donc pas quitter + } + else + // L'utilisateur ne veut pas écraser l'ancien fichier, + return 0; // On doit donc rester case 3 : return 1; // Quitter } return 0; @@ -1225,6 +1229,16 @@ void Button_Page(void) SWAP_BYTES (Main_current_layer,Spare_current_layer) 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(); // replaced by @@ -2560,95 +2574,46 @@ int Best_video_mode(void) 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) // Image=1 => On charge/sauve une image // Image=0 => On charge/sauve une brosse { - // Données initiales du fichier (au cas où on voudrait annuler) - char initial_file_directory[MAX_PATH_CHARACTERS]; - char initial_filename[MAX_PATH_CHARACTERS]; - byte initial_file_format; - byte do_not_restore; + byte confirm; byte use_brush_palette = 0; - T_Components * initial_palette=NULL; 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; - - - 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) + T_IO_Context context; + static char filename [MAX_PATH_CHARACTERS]; + static char directory[MAX_PATH_CHARACTERS]; + + if (image) { - initial_palette=(T_Components *)malloc(sizeof(T_Palette)); - memcpy(initial_palette,Main_palette,sizeof(T_Palette)); + strcpy(filename, Main_backups->Pages->Filename); + 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 (do_not_restore) + if (confirm) { if (image) { if (Main_image_is_modified) - do_not_restore=Confirmation_box("Discard unsaved changes?"); + confirm=Confirmation_box("Discard unsaved changes?"); } else 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 - if (do_not_restore) + if (confirm) { old_cursor_shape=Cursor_shape; Hide_cursor(); @@ -2657,23 +2622,16 @@ void Load_picture(byte 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_Y=0; } - else - Pixel_load_function=Pixel_load_in_brush; - Load_image(image); + Load_image(&context); if (!image) { - if (!use_brush_palette) - memcpy(Main_palette,initial_palette,sizeof(T_Palette)); + //if (!use_brush_palette) + // memcpy(Main_palette,initial_palette,sizeof(T_Palette)); 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_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_Y=0; @@ -2702,10 +2654,6 @@ void Load_picture(byte image) Brush_offset_X=(Brush_width>>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); if (Config.Auto_discontinuous) { @@ -2722,10 +2670,10 @@ void Load_picture(byte image) Hide_cursor(); Cursor_shape=old_cursor_shape; } - + + if ( (File_error==1) || (Get_fileformat(Main_fileformat)->Palette_only) ) { - do_not_restore=0; if (File_error!=1) 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. 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) || - (Ratio_of_loaded_image == PIXEL_TALL && + (context.Ratio == PIXEL_TALL && Pixel_ratio != PIXEL_TALL && Pixel_ratio != PIXEL_TALL2))) { Init_mode_video( Video_mode[Current_resolution].Width, Video_mode[Current_resolution].Height, Video_mode[Current_resolution].Fullscreen, - Ratio_of_loaded_image); + context.Ratio); Display_menu(); } else @@ -2780,21 +2728,15 @@ void Load_picture(byte image) if (image) Main_image_is_modified=0; } + + Destroy_context(&context); + Display_menu(); Display_cursor(); } - free(initial_palette); - - 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(); + //if (!image) + // Swap_data_of_image_and_brush(); Hide_cursor(); Print_filename(); Display_cursor(); @@ -2823,6 +2765,8 @@ void Button_Reload(void) if ( (!Main_image_is_modified) || Confirmation_box("Discard unsaved changes ?") ) { + T_IO_Context context; + Hide_cursor(); old_cursor_shape=Cursor_shape; Cursor_shape=CURSOR_SHAPE_HOURGLASS; @@ -2830,7 +2774,9 @@ void Button_Reload(void) Original_screen_X=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(); 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. 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) || - (Ratio_of_loaded_image == PIXEL_TALL && + (context.Ratio == PIXEL_TALL && Pixel_ratio != PIXEL_TALL && Pixel_ratio != PIXEL_TALL2))) { Init_mode_video( Video_mode[Current_resolution].Width, Video_mode[Current_resolution].Height, Video_mode[Current_resolution].Fullscreen, - Ratio_of_loaded_image); + context.Ratio); Display_menu(); } else @@ -2881,6 +2827,7 @@ void Button_Reload(void) Main_image_is_modified=0; } + Destroy_context(&context); } else Hide_cursor(); @@ -2901,7 +2848,7 @@ void Backup_filename(char * fname, char * backup_name) short i; 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'; strcat(backup_name,"BAK"); } @@ -2912,7 +2859,7 @@ void Backup_existing_file(void) char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier 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 Backup_filename(filename,new_filename); @@ -2938,76 +2885,63 @@ void Save_picture(byte image) // image=1 => On charge/sauve une image // image=0 => On charge/sauve une brosse { - // Données initiales du fichier (au cas où on voudrait annuler) - char initial_file_directory[MAX_PATH_CHARACTERS]; - char initial_filename[MAX_PATH_CHARACTERS]; - byte initial_file_format; - byte do_not_restore; + byte confirm; 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]; - - - 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)) + T_IO_Context save_context; + static char filename [MAX_PATH_CHARACTERS]; + static char directory[MAX_PATH_CHARACTERS]; + + if (image) { - do_not_restore=Confirmation_box("Erase old file ?"); - if ((do_not_restore) && (Config.Backup)) + strcpy(filename, Main_backups->Pages->Filename); + 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(); if (File_error) { - do_not_restore=0; + confirm=0; Error(0); } } } - if (do_not_restore) + if (confirm) { + old_cursor_shape=Cursor_shape; Hide_cursor(); Cursor_shape=CURSOR_SHAPE_HOURGLASS; Display_cursor(); - if (image) - 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; - } + Save_image(&save_context); Hide_cursor(); Cursor_shape=old_cursor_shape; - - if ((File_error==1) || (Get_fileformat(Main_fileformat)->Palette_only)) - do_not_restore=0; - Display_cursor(); } - - 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(); + Destroy_context(&save_context); + //if (!image) + // Swap_data_of_image_and_brush(); Print_filename(); Set_palette(Main_palette); @@ -3027,7 +2961,7 @@ void Button_Autosave(void) 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); if ( (!file_already_exists) || Confirmation_box("Erase old file ?") ) @@ -3041,11 +2975,15 @@ void Button_Autosave(void) if (!File_error) { + T_IO_Context save_context; + old_cursor_shape=Cursor_shape; Cursor_shape=CURSOR_SHAPE_HOURGLASS; 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(); Cursor_shape=old_cursor_shape; diff --git a/fileformats.c b/fileformats.c index 4d801eb9..8b98b8c2 100644 --- a/fileformats.c +++ b/fileformats.c @@ -41,7 +41,7 @@ //////////////////////////////////// IMG //////////////////////////////////// // -- Tester si un fichier est au format IMG -------------------------------- -void Test_IMG(void) +void Test_IMG(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -49,7 +49,7 @@ void Test_IMG(void) byte signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0}; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -75,7 +75,7 @@ void Test_IMG(void) // -- Lire un fichier au format IMG ----------------------------------------- -void Load_IMG(void) +void Load_IMG(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier byte * buffer; @@ -85,7 +85,7 @@ void Load_IMG(void) long file_size; T_IMG_Header IMG_header; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; if ((file=fopen(filename, "rb"))) @@ -102,23 +102,23 @@ void Load_IMG(void) buffer=(byte *)malloc(IMG_header.Width); - Init_preview(IMG_header.Width,IMG_header.Height,file_size,FORMAT_IMG,PIXEL_SIMPLE); + Pre_load(context, IMG_header.Width,IMG_header.Height,file_size,FORMAT_IMG,PIXEL_SIMPLE,0); if (File_error==0) { - memcpy(Main_palette,IMG_header.Palette,sizeof(T_Palette)); - Set_palette(Main_palette); - Remap_fileselector(); + memcpy(context->Palette,IMG_header.Palette,sizeof(T_Palette)); + Set_palette(context->Palette); + Remap_fileselector(context); - Main_image_width=IMG_header.Width; - Main_image_height=IMG_header.Height; + context->Width=IMG_header.Width; + context->Height=IMG_header.Height; width_read=IMG_header.Width; - for (y_pos=0;(y_posHeight) && (!File_error);y_pos++) { - if (Read_bytes(file,buffer,Main_image_width)) + if (Read_bytes(file,buffer,context->Width)) { - for (x_pos=0; x_posWidth;x_pos++) + Set_pixel(context, x_pos,y_pos,buffer[x_pos]); } else File_error=2; @@ -137,7 +137,7 @@ void Load_IMG(void) } // -- Sauver un fichier au format IMG --------------------------------------- -void Save_IMG(void) +void Save_IMG(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -145,7 +145,7 @@ void Save_IMG(void) T_IMG_Header IMG_header; byte signature[6]={0x01,0x00,0x47,0x12,0x6D,0xB0}; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -154,8 +154,8 @@ void Save_IMG(void) { memcpy(IMG_header.Filler1,signature,6); - IMG_header.Width=Main_image_width; - IMG_header.Height=Main_image_height; + IMG_header.Width=context->Width; + IMG_header.Height=context->Height; memset(IMG_header.Filler2,0,118); IMG_header.Filler2[4]=0xFF; @@ -163,7 +163,7 @@ void Save_IMG(void) IMG_header.Filler2[23]=0; // Hi(Longueur de la signature) memcpy(IMG_header.Filler2+23,"GRAFX2 by SunsetDesign (IMG format taken from PV (c)W.Wiedmann)",64); - memcpy(IMG_header.Palette,Main_palette,sizeof(T_Palette)); + memcpy(IMG_header.Palette,context->Palette,sizeof(T_Palette)); if (Write_bytes(file,IMG_header.Filler1,sizeof(IMG_header.Filler1)) && Write_word_le(file,IMG_header.Width) @@ -175,9 +175,9 @@ void Save_IMG(void) { Init_write_buffer(); - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) + for (x_pos=0; x_posWidth; x_pos++) + Write_one_byte(file,Get_pixel(context, x_pos,y_pos)); End_write(file); fclose(file); @@ -226,14 +226,14 @@ FILE *LBM_file; // -- Tester si un fichier est au format LBM -------------------------------- -void Test_LBM(void) +void Test_LBM(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; char format[4]; char section[4]; dword dummy; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -270,7 +270,7 @@ void Test_LBM(void) byte Image_HAM; // ---------------- Adapter la palette pour les images HAM ---------------- - void Adapt_palette_HAM(void) + void Adapt_palette_HAM(T_IO_Context * context) { short i,j,temp; byte color; @@ -280,7 +280,7 @@ void Test_LBM(void) for (i=1; i<=14; i++) { // On recopie a palette de base - memcpy(Main_palette+(i<<4),Main_palette,48); + memcpy(context->Palette+(i<<4),context->Palette,48); // On modifie les teintes de cette palette for (j=0; j<16; j++) { @@ -289,36 +289,36 @@ void Test_LBM(void) { if (i&1) { - temp=Main_palette[j].R+16; - Main_palette[color].R=(temp<63)?temp:63; + temp=context->Palette[j].R+16; + context->Palette[color].R=(temp<63)?temp:63; } if (i&2) { - temp=Main_palette[j].G+16; - Main_palette[color].G=(temp<63)?temp:63; + temp=context->Palette[j].G+16; + context->Palette[color].G=(temp<63)?temp:63; } if (i&4) { - temp=Main_palette[j].B+16; - Main_palette[color].B=(temp<63)?temp:63; + temp=context->Palette[j].B+16; + context->Palette[color].B=(temp<63)?temp:63; } } else { if ((i-7)&1) { - temp=Main_palette[j].R-16; - Main_palette[color].R=(temp>=0)?temp:0; + temp=context->Palette[j].R-16; + context->Palette[color].R=(temp>=0)?temp:0; } if ((i-7)&2) { - temp=Main_palette[j].G-16; - Main_palette[color].G=(temp>=0)?temp:0; + temp=context->Palette[j].G-16; + context->Palette[color].G=(temp>=0)?temp:0; } if ((i-7)&4) { - temp=Main_palette[j].B-16; - Main_palette[color].B=(temp>=0)?temp:0; + temp=context->Palette[j].B-16; + context->Palette[color].B=(temp>=0)?temp:0; } } } @@ -326,12 +326,12 @@ void Test_LBM(void) // Ici, il reste les 16 dernières couleurs à modifier for (i=240,j=0; j<16; i++,j++) { - temp=Main_palette[j].R+8; - Main_palette[i].R=(temp<63)?temp:63; - temp=Main_palette[j].G+8; - Main_palette[i].G=(temp<63)?temp:63; - temp=Main_palette[j].B+8; - Main_palette[i].B=(temp<63)?temp:63; + temp=context->Palette[j].R+8; + context->Palette[i].R=(temp<63)?temp:63; + temp=context->Palette[j].G+8; + context->Palette[i].G=(temp<63)?temp:63; + temp=context->Palette[j].B+8; + context->Palette[i].B=(temp<63)?temp:63; } } else if (Image_HAM==8) @@ -339,7 +339,7 @@ void Test_LBM(void) for (i=1; i<=3; i++) { // On recopie la palette de base - memcpy(Main_palette+(i<<6),Main_palette,192); + memcpy(context->Palette+(i<<6),context->Palette,192); // On modifie les teintes de cette palette for (j=0; j<64; j++) { @@ -347,16 +347,16 @@ void Test_LBM(void) switch (i) { case 1 : - temp=Main_palette[j].R+16; - Main_palette[color].R=(temp<63)?temp:63; + temp=context->Palette[j].R+16; + context->Palette[color].R=(temp<63)?temp:63; break; case 2 : - temp=Main_palette[j].G+16; - Main_palette[color].G=(temp<63)?temp:63; + temp=context->Palette[j].G+16; + context->Palette[color].G=(temp<63)?temp:63; break; default: - temp=Main_palette[j].B+16; - Main_palette[color].B=(temp<63)?temp:63; + temp=context->Palette[j].B+16; + context->Palette[color].B=(temp<63)?temp:63; } } } @@ -366,9 +366,9 @@ void Test_LBM(void) for (i=0; i<32; i++) { j=i+32; - Main_palette[j].R=Main_palette[i].R>>1; - Main_palette[j].G=Main_palette[i].G>>1; - Main_palette[j].B=Main_palette[i].B>>1; + context->Palette[j].R=context->Palette[i].R>>1; + context->Palette[j].G=context->Palette[i].G>>1; + context->Palette[j].B=context->Palette[i].B>>1; } } } @@ -422,7 +422,7 @@ byte Color_ILBM_line(word x_pos, word real_line_size, byte HBPm1) byte HBPm1; // header.BitPlanes-1 // ----------------------- Afficher une ligne ILBM ------------------------ - void Draw_ILBM_line(short y_pos, short real_line_size) + void Draw_ILBM_line(T_IO_Context *context, short y_pos, short real_line_size) { byte color; byte red,green,blue; @@ -431,19 +431,19 @@ byte HBPm1; // header.BitPlanes-1 if (Image_HAM<=1) // ILBM { - for (x_pos=0; x_posWidth; x_pos++) { - Pixel_load_function(x_pos,y_pos,Color_ILBM_line(x_pos,real_line_size, HBPm1)); + Set_pixel(context, x_pos,y_pos,Color_ILBM_line(x_pos,real_line_size, HBPm1)); } } else { color=0; - red=Main_palette[0].R; - green =Main_palette[0].G; - blue =Main_palette[0].B; + red=context->Palette[0].R; + green =context->Palette[0].G; + blue =context->Palette[0].B; if (Image_HAM==6) - for (x_pos=0; x_posWidth; x_pos++) // HAM6 { temp=Color_ILBM_line(x_pos,real_line_size, HBPm1); switch (temp & 0xF0) @@ -462,14 +462,14 @@ byte HBPm1; // header.BitPlanes-1 break; default: // Nouvelle couleur color=temp; - red=Main_palette[color].R; - green =Main_palette[color].G; - blue =Main_palette[color].B; + red=context->Palette[color].R; + green =context->Palette[color].G; + blue =context->Palette[color].B; } - Pixel_load_function(x_pos,y_pos,color); + Set_pixel(context, x_pos,y_pos,color); } else - for (x_pos=0; x_posWidth; x_pos++) // HAM8 { temp=Color_ILBM_line(x_pos,real_line_size, HBPm1); switch (temp & 0x03) @@ -488,17 +488,17 @@ byte HBPm1; // header.BitPlanes-1 break; default: // Nouvelle couleur color=temp; - red=Main_palette[color].R; - green =Main_palette[color].G; - blue =Main_palette[color].B; + red=context->Palette[color].R; + green =context->Palette[color].G; + blue =context->Palette[color].B; } - Pixel_load_function(x_pos,y_pos,color); + Set_pixel(context, x_pos,y_pos,color); } } } -void Load_LBM(void) +void Load_LBM(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; T_LBM_Header header; @@ -517,7 +517,7 @@ void Load_LBM(void) long file_size; dword dummy; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -585,18 +585,18 @@ void Load_LBM(void) // palette a moins de 256 coul, la précédente ne souffrira pas d'un // assombrissement préjudiciable. if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); else - Palette_64_to_256(Main_palette); + Palette_64_to_256(context->Palette); // On peut maintenant charger la nouvelle palette - if (Read_bytes(LBM_file,Main_palette,3*nb_colors)) + if (Read_bytes(LBM_file,context->Palette,3*nb_colors)) { - Palette_256_to_64(Main_palette); + Palette_256_to_64(context->Palette); if (Image_HAM) - Adapt_palette_HAM(); - Palette_64_to_256(Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); + Adapt_palette_HAM(context); + Palette_64_to_256(context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); // On lit l'octet de padding du CMAP si la taille est impaire if (nb_colors&1) @@ -606,40 +606,40 @@ void Load_LBM(void) if ( (Wait_for((byte *)"BODY")) && (!File_error) ) { Read_dword_be(LBM_file,&image_size); - //swab((char *)&header.Width ,(char *)&Main_image_width,2); - //swab((char *)&header.Height,(char *)&Main_image_height,2); - Main_image_width = header.Width; - Main_image_height = header.Height; + //swab((char *)&header.Width ,(char *)&context->Width,2); + //swab((char *)&header.Height,(char *)&context->Height,2); + context->Width = header.Width; + context->Height = header.Height; //swab((char *)&header.X_screen,(char *)&Original_screen_X,2); //swab((char *)&header.Y_screen,(char *)&Original_screen_Y,2); Original_screen_X = header.X_screen; Original_screen_Y = header.Y_screen; - Init_preview(Main_image_width,Main_image_height,file_size,FORMAT_LBM,PIXEL_SIMPLE); + Pre_load(context, context->Width,context->Height,file_size,FORMAT_LBM,PIXEL_SIMPLE,0); if (File_error==0) { if (!memcmp(format,"ILBM",4)) // "ILBM": InterLeaved BitMap { // Calcul de la taille d'une ligne ILBM (pour les images ayant des dimensions exotiques) - if (Main_image_width & 15) + if (context->Width & 15) { - real_line_size=( (Main_image_width+16) >> 4 ) << 4; - line_size=( (Main_image_width+16) >> 4 )*(header.BitPlanes<<1); + real_line_size=( (context->Width+16) >> 4 ) << 4; + line_size=( (context->Width+16) >> 4 )*(header.BitPlanes<<1); } else { - real_line_size=Main_image_width; - line_size=(Main_image_width>>3)*header.BitPlanes; + real_line_size=context->Width; + line_size=(context->Width>>3)*header.BitPlanes; } if (!header.Compression) { // non compressé LBM_buffer=(byte *)malloc(line_size); - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { if (Read_bytes(LBM_file,LBM_buffer,line_size)) - Draw_ILBM_line(y_pos,real_line_size); + Draw_ILBM_line(context, y_pos,real_line_size); else File_error=2; } @@ -651,7 +651,7 @@ void Load_LBM(void) LBM_buffer=(byte *)malloc(line_size); - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { for (x_pos=0; ((x_posWidth+(context->Width&1); if (!header.Compression) { // non compressé LBM_buffer=(byte *)malloc(real_line_size); - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { if (Read_bytes(LBM_file,LBM_buffer,real_line_size)) - for (x_pos=0; x_posWidth; x_pos++) + Set_pixel(context, x_pos,y_pos,LBM_buffer[x_pos]); else File_error=2; } @@ -709,7 +709,7 @@ void Load_LBM(void) else { // compressé /*Init_lecture();*/ - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { for (x_pos=0; ((x_posFile_name, context->File_directory); // Ouverture du fichier if ((LBM_file=fopen(filename,"wb"))) @@ -884,11 +884,11 @@ void Save_LBM(void) Write_dword_be(LBM_file,20); // On corrige la largeur de l'image pour qu'elle soit multiple de 2 - real_width=Main_image_width+(Main_image_width&1); + real_width=context->Width+(context->Width&1); //swab((byte *)&real_width,(byte *)&header.Width,2); - header.Width=Main_image_width; - header.Height=Main_image_height; + header.Width=context->Width; + header.Height=context->Height; header.X_org=0; header.Y_org=0; header.BitPlanes=8; @@ -918,7 +918,7 @@ void Save_LBM(void) Write_bytes(LBM_file,"CMAP",4); Write_dword_be(LBM_file,sizeof(T_Palette)); - Write_bytes(LBM_file,Main_palette,sizeof(T_Palette)); + Write_bytes(LBM_file,context->Palette,sizeof(T_Palette)); Write_bytes(LBM_file,"BODY",4); Write_dword_be(LBM_file,0); // On mettra la taille à jour à la fin @@ -927,10 +927,10 @@ void Save_LBM(void) LBM_list_size=0; - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { for (x_pos=0; ((x_posFile_name, context->File_directory); if ((file=fopen(filename, "rb"))) { @@ -1089,7 +1089,7 @@ byte Bitmap_mask(dword pixel, dword mask) } // -- Charger un fichier au format BMP -------------------------------------- -void Load_BMP(void) +void Load_BMP(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -1104,7 +1104,7 @@ void Load_BMP(void) byte a,b,c=0; long file_size; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -1146,30 +1146,30 @@ void Load_BMP(void) if (!File_error) { - Init_preview(header.Width,header.Height,file_size,FORMAT_BMP,PIXEL_SIMPLE); + Pre_load(context, header.Width,header.Height,file_size,FORMAT_BMP,PIXEL_SIMPLE,0); if (File_error==0) { if (Read_bytes(file,local_palette,nb_colors<<2)) { if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); // On peut maintenant transférer la nouvelle palette for (index=0; indexPalette[index].R=local_palette[index][2]; + context->Palette[index].G=local_palette[index][1]; + context->Palette[index].B=local_palette[index][0]; } - Set_palette(Main_palette); - Remap_fileselector(); + Set_palette(context->Palette); + Remap_fileselector(context); - Main_image_width=header.Width; - Main_image_height=header.Height; + context->Width=header.Width; + context->Height=header.Height; switch (header.Compression) { case 0 : // Pas de compression - line_size=Main_image_width; + line_size=context->Width; x_pos=(32/header.Nb_bits); // x_pos sert de variable temporaire // On arrondit line_size au premier multiple de x_pos supérieur if (line_size % x_pos) @@ -1178,26 +1178,26 @@ void Load_BMP(void) line_size=(line_size*header.Nb_bits)>>3; buffer=(byte *)malloc(line_size); - for (y_pos=Main_image_height-1; ((y_pos>=0) && (!File_error)); y_pos--) + for (y_pos=context->Height-1; ((y_pos>=0) && (!File_error)); y_pos--) { if (Read_bytes(file,buffer,line_size)) - for (x_pos=0; x_posWidth; x_pos++) switch (header.Nb_bits) { case 8 : - Pixel_load_function(x_pos,y_pos,buffer[x_pos]); + Set_pixel(context, x_pos,y_pos,buffer[x_pos]); break; case 4 : if (x_pos & 1) - Pixel_load_function(x_pos,y_pos,buffer[x_pos>>1] & 0xF); + Set_pixel(context, x_pos,y_pos,buffer[x_pos>>1] & 0xF); else - Pixel_load_function(x_pos,y_pos,buffer[x_pos>>1] >> 4 ); + Set_pixel(context, x_pos,y_pos,buffer[x_pos>>1] >> 4 ); break; case 1 : if ( buffer[x_pos>>3] & (0x80>>(x_pos&7)) ) - Pixel_load_function(x_pos,y_pos,1); + Set_pixel(context, x_pos,y_pos,1); else - Pixel_load_function(x_pos,y_pos,0); + Set_pixel(context, x_pos,y_pos,0); } else File_error=2; @@ -1207,7 +1207,7 @@ void Load_BMP(void) case 1 : // Compression RLE 8 bits x_pos=0; - y_pos=Main_image_height-1; + y_pos=context->Height-1; /*Init_lecture();*/ if(Read_byte(file, &a)!=1 || Read_byte(file, &b)!=1) @@ -1216,7 +1216,7 @@ void Load_BMP(void) { if (a) // Encoded mode for (index=1; index<=a; index++) - Pixel_load_function(x_pos++,y_pos,b); + Set_pixel(context, x_pos++,y_pos,b); else // Absolute mode switch (b) { @@ -1238,10 +1238,10 @@ void Load_BMP(void) if(Read_byte(file, &a)!=1) File_error=2; //Read_one_byte(file, &c); - Pixel_load_function(x_pos++,y_pos,a); + Set_pixel(context, x_pos++,y_pos,a); //if (--c) //{ - // Pixel_load_function(x_pos++,y_pos,c); + // Set_pixel(context, x_pos++,y_pos,c); // b--; //} b--; @@ -1260,7 +1260,7 @@ void Load_BMP(void) case 2 : // Compression RLE 4 bits x_pos=0; - y_pos=Main_image_height-1; + y_pos=context->Height-1; /*Init_lecture();*/ if(Read_byte(file, &a)!=1 || Read_byte(file, &b) != 1) @@ -1271,9 +1271,9 @@ void Load_BMP(void) for (index=1; index<=a; index++) { if (index & 1) - Pixel_load_function(x_pos,y_pos,b>>4); + Set_pixel(context, x_pos,y_pos,b>>4); else - Pixel_load_function(x_pos,y_pos,b&0xF); + Set_pixel(context, x_pos,y_pos,b&0xF); x_pos++; } else // Absolute mode @@ -1297,10 +1297,10 @@ void Load_BMP(void) if (index&1) { if(Read_byte(file, &c)!=1) File_error=2; - Pixel_load_function(x_pos,y_pos,c>>4); + Set_pixel(context, x_pos,y_pos,c>>4); } else - Pixel_load_function(x_pos,y_pos,c&0xF); + Set_pixel(context, x_pos,y_pos,c&0xF); } // On lit l'octet rendant le nombre d'octets pair, si // nécessaire. Encore un truc de crétin "made in MS". @@ -1343,9 +1343,9 @@ void Load_BMP(void) } File_error=0; - Main_image_width=header.Width; - Main_image_height=header.Height; - Init_preview_24b(header.Width,header.Height,file_size,FORMAT_BMP); + context->Width=header.Width; + context->Height=header.Height; + Pre_load(context,header.Width,header.Height,file_size,FORMAT_BMP,PIXEL_SIMPLE,1); if (File_error==0) { switch (header.Compression) @@ -1369,17 +1369,17 @@ void Load_BMP(void) // 24bit bitmap default: case 24: - line_size=Main_image_width*3; + line_size=context->Width*3; x_pos=(line_size % 4); // x_pos sert de variable temporaire if (x_pos>0) line_size+=(4-x_pos); buffer=(byte *)malloc(line_size); - for (y_pos=Main_image_height-1; ((y_pos>=0) && (!File_error)); y_pos--) + for (y_pos=context->Height-1; ((y_pos>=0) && (!File_error)); y_pos--) { if (Read_bytes(file,buffer,line_size)) - for (x_pos=0,index=0; x_posWidth; x_pos++,index+=3) + Set_pixel_24b(context, x_pos,y_pos,buffer[index+2],buffer[index+1],buffer[index+0]); else File_error=2; } @@ -1387,15 +1387,15 @@ void Load_BMP(void) // 32bit bitmap case 32: - line_size=Main_image_width*4; + line_size=context->Width*4; buffer=(byte *)malloc(line_size); - for (y_pos=Main_image_height-1; ((y_pos>=0) && (!File_error)); y_pos--) + for (y_pos=context->Height-1; ((y_pos>=0) && (!File_error)); y_pos--) { if (Read_bytes(file,buffer,line_size)) - for (x_pos=0; x_posWidth; x_pos++) { dword pixel=*(((dword *)buffer)+x_pos); - Pixel_load_24b(x_pos,y_pos,Bitmap_mask(pixel,red_mask),Bitmap_mask(pixel,green_mask),Bitmap_mask(pixel,blue_mask)); + Set_pixel_24b(context, x_pos,y_pos,Bitmap_mask(pixel,red_mask),Bitmap_mask(pixel,green_mask),Bitmap_mask(pixel,blue_mask)); } else File_error=2; @@ -1404,15 +1404,15 @@ void Load_BMP(void) // 16bit bitmap case 16: - line_size=(Main_image_width*2) + (Main_image_width&1)*2; + line_size=(context->Width*2) + (context->Width&1)*2; buffer=(byte *)malloc(line_size); - for (y_pos=Main_image_height-1; ((y_pos>=0) && (!File_error)); y_pos--) + for (y_pos=context->Height-1; ((y_pos>=0) && (!File_error)); y_pos--) { if (Read_bytes(file,buffer,line_size)) - for (x_pos=0; x_posWidth; x_pos++) { word pixel=*(((word *)buffer)+x_pos); - Pixel_load_24b(x_pos,y_pos,Bitmap_mask(pixel,red_mask),Bitmap_mask(pixel,green_mask),Bitmap_mask(pixel,blue_mask)); + Set_pixel_24b(context, x_pos,y_pos,Bitmap_mask(pixel,red_mask),Bitmap_mask(pixel,green_mask),Bitmap_mask(pixel,blue_mask)); } else File_error=2; @@ -1437,7 +1437,7 @@ void Load_BMP(void) // -- Sauvegarder un fichier au format BMP ---------------------------------- -void Save_BMP(void) +void Save_BMP(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -1450,27 +1450,26 @@ void Save_BMP(void) File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); // Ouverture du fichier if ((file=fopen(filename,"wb"))) { // Image width must be a multiple of 4 bytes - line_size = Main_image_width; - - if (line_size & 3) + line_size = context->Width; + if (line_size & 3) line_size += (4 - (line_size & 3)); - + header.Signature[0] = 'B'; header.Signature[1] = 'M'; - header.Size_1 =(line_size*Main_image_height)+1078; + header.Size_1 =(line_size*context->Height)+1078; header.Reserved_1 =0; header.Reserved_2 =0; header.Offset =1078; // Size of header data (including palette) header.Size_2 =40; // Size of header - header.Width =Main_image_width; - header.Height =Main_image_height; + header.Width =context->Width; + header.Height =context->Height; header.Planes =1; header.Nb_bits =8; header.Compression=0; @@ -1506,9 +1505,9 @@ void Save_BMP(void) // Windows 95." ... for (index=0; index<256; index++) { - local_palette[index][0]=Main_palette[index].B; - local_palette[index][1]=Main_palette[index].G; - local_palette[index][2]=Main_palette[index].R; + local_palette[index][0]=context->Palette[index].B; + local_palette[index][1]=context->Palette[index].G; + local_palette[index][2]=context->Palette[index].R; local_palette[index][3]=0; } @@ -1519,9 +1518,9 @@ void Save_BMP(void) // ... Et Bill, il a dit: "OK les gars! Mais seulement si vous rangez // les pixels dans l'ordre inverse, mais que sur les Y quand-même // parce que faut pas pousser." - for (y_pos=Main_image_height-1; ((y_pos>=0) && (!File_error)); y_pos--) + for (y_pos=context->Height-1; ((y_pos>=0) && (!File_error)); y_pos--) for (x_pos=0; x_posFile_name, context->File_directory); if ((file=fopen(filename, "rb"))) { @@ -1668,10 +1667,10 @@ word GIF_get_next_code(void) // -- Affiche un nouveau pixel -- -void GIF_new_pixel(T_GIF_IDB *idb, byte color) +void GIF_new_pixel(T_IO_Context * context, T_GIF_IDB *idb, byte color) { - if (color != Main_backups->Pages->Transparent_color) // transparent color - Pixel_load_function(idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color); + if (color != context->Transparent_color) // transparent color + Set_pixel(context, idb->Pos_X+GIF_pos_X, idb->Pos_Y+GIF_pos_Y,color); GIF_pos_X++; @@ -1712,7 +1711,7 @@ void GIF_new_pixel(T_GIF_IDB *idb, byte color) } -void Load_GIF(void) +void Load_GIF(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; char signature[6]; @@ -1740,13 +1739,14 @@ void Load_GIF(void) word value_eof; // Valeur <=> End d'image long file_size; int number_LID; // Nombre d'images trouvées dans le fichier + short current_layer = 0; /////////////////////////////////////////////////// FIN DES DECLARATIONS // number_LID=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((GIF_file=fopen(filename, "rb"))) { @@ -1773,9 +1773,9 @@ void Load_GIF(void) Original_screen_X=LSDB.Width; Original_screen_Y=LSDB.Height; - Init_preview(LSDB.Width,LSDB.Height,file_size,FORMAT_GIF,PIXEL_SIMPLE); - Main_image_width=LSDB.Width; - Main_image_height=LSDB.Height; + Pre_load(context, LSDB.Width,LSDB.Height,file_size,FORMAT_GIF,PIXEL_SIMPLE,0); + context->Width=LSDB.Width; + context->Height=LSDB.Height; // Palette globale dispo = (LSDB.Resol and $80) // Profondeur de couleur =((LSDB.Resol and $70) shr 4)+1 @@ -1790,28 +1790,28 @@ void Load_GIF(void) // Palette globale dispo: if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); // On peut maintenant charger la nouvelle palette: if (!(LSDB.Aspect & 0x80)) // Palette dans l'ordre: for(color_index=0;color_indexPalette[color_index].R)); + Read_byte(GIF_file,&(context->Palette[color_index].G)); + Read_byte(GIF_file,&(context->Palette[color_index].B)); } else { // Palette triée par composantes: for (color_index=0;color_indexPalette[color_index].R)); for (color_index=0;color_indexPalette[color_index].G)); for (color_index=0;color_indexPalette[color_index].B)); } - Set_palette(Main_palette); + Set_palette(context->Palette); } // On lit un indicateur de block @@ -1834,12 +1834,12 @@ void Load_GIF(void) case 0xFE: // Comment Block Extension // On récupère le premier commentaire non-vide, // on jette les autres. - if (Main_comment[0]=='\0') + if (context->Comment[0]=='\0') { int nb_char_to_keep=Min(size_to_read,COMMENT_SIZE); - Read_bytes(GIF_file,Main_comment,nb_char_to_keep); - Main_comment[nb_char_to_keep+1]='\0'; + Read_bytes(GIF_file,context->Comment,nb_char_to_keep); + context->Comment[nb_char_to_keep+1]='\0'; // Si le commentaire etait trop long, on fait avance-rapide // sur la suite. if (size_to_read>nb_char_to_keep) @@ -1853,9 +1853,9 @@ void Load_GIF(void) && Read_byte(GIF_file,&(GCE.Transparent_color))) { if (GCE.Packed_fields & 1) - Main_backups->Pages->Transparent_color= GCE.Transparent_color; + context->Transparent_color= GCE.Transparent_color; else - Main_backups->Pages->Transparent_color = -1; + context->Transparent_color = -1; } else @@ -1875,11 +1875,12 @@ void Load_GIF(void) case 0x2C: // Local Image Descriptor { // Si on a deja lu une image, c'est une GIF animée ou bizarroide, on sort. - if (number_LID!=0 && Pixel_load_function==Pixel_load_in_current_screen) + if (number_LID!=0) { // This a second layer/frame, or more. // Attempt to add a layer to current image - Add_layer(Main_backups, Main_current_layer+1); + current_layer++; + Set_layer(context, current_layer); } number_LID++; @@ -1909,24 +1910,24 @@ void Load_GIF(void) // Palette dans l'ordre: for(color_index=0;color_indexPalette[color_index].R)); + Read_byte(GIF_file,&(context->Palette[color_index].G)); + Read_byte(GIF_file,&(context->Palette[color_index].B)); } else { // Palette triée par composantes: for (color_index=0;color_indexPalette[color_index].R)); for (color_index=0;color_indexPalette[color_index].G)); for (color_index=0;color_indexPalette[color_index].B)); } - Set_palette(Main_palette); + Set_palette(context->Palette); } - Remap_fileselector(); + Remap_fileselector(context); value_clr =nb_colors+0; value_eof =nb_colors+1; @@ -1971,7 +1972,7 @@ void Load_GIF(void) special_case=alphabet_stack[alphabet_stack_pos++]=GIF_current_code; do - GIF_new_pixel(&IDB, alphabet_stack[--alphabet_stack_pos]); + GIF_new_pixel(context, &IDB, alphabet_stack[--alphabet_stack_pos]); while (alphabet_stack_pos!=0); alphabet_prefix[alphabet_free ]=old_code; @@ -1991,7 +1992,7 @@ void Load_GIF(void) alphabet_free =nb_colors+2; special_case =GIF_get_next_code(); old_code =GIF_current_code; - GIF_new_pixel(&IDB, GIF_current_code); + GIF_new_pixel(context, &IDB, GIF_current_code); } } else @@ -2095,11 +2096,11 @@ void Load_GIF(void) // -- Lire le pixel suivant -- - byte GIF_next_pixel(T_GIF_IDB *idb) + byte GIF_next_pixel(T_IO_Context *context, T_GIF_IDB *idb) { byte temp; - temp=Read_pixel_function(GIF_pos_X,GIF_pos_Y); + temp=Get_pixel(context, GIF_pos_X,GIF_pos_Y); if (++GIF_pos_X>=idb->Image_width) { @@ -2113,7 +2114,7 @@ void Load_GIF(void) -void Save_GIF(void) +void Save_GIF(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; @@ -2134,14 +2135,13 @@ void Save_GIF(void) word current_string; // Code de la chaîne en cours de traitement byte current_char; // Caractère à coder word index; // index de recherche de chaîne - - byte old_current_layer=Main_current_layer; + short current_layer; /////////////////////////////////////////////////// FIN DES DECLARATIONS // File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((GIF_file=fopen(filename,"wb"))) { @@ -2164,8 +2164,8 @@ void Save_GIF(void) } else { - LSDB.Width=Main_image_width; - LSDB.Height=Main_image_height; + LSDB.Width=context->Width; + LSDB.Height=context->Height; } LSDB.Resol =0x97; // Image en 256 couleurs, avec une palette LSDB.Backcol=0; @@ -2182,7 +2182,7 @@ void Save_GIF(void) // Le LSDB a été correctement écrit. // On sauve la palette - if (Write_bytes(GIF_file,Main_palette,768)) + if (Write_bytes(GIF_file,context->Palette,768)) { // La palette a été correctement écrite. @@ -2198,23 +2198,25 @@ void Save_GIF(void) // SSSS : number of loops // Ecriture du commentaire - if (Main_comment[0]) + if (context->Comment[0]) { Write_bytes(GIF_file,"\x21\xFE",2); - Write_byte(GIF_file,strlen(Main_comment)); - Write_bytes(GIF_file,Main_comment,strlen(Main_comment)+1); + Write_byte(GIF_file,strlen(context->Comment)); + Write_bytes(GIF_file,context->Comment,strlen(context->Comment)+1); } // Loop on all layers - for (Main_current_layer=0; - Main_current_layer < Main_backups->Pages->Nb_layers && !File_error; - Main_current_layer++) + for (current_layer=0; + current_layer < context->Nb_layers && !File_error; + current_layer++) { // Write a Graphic Control Extension char GCE_block[] = "\x21\xF9\x04\x05\x05\x00\x00\x00"; //if (Main_current_layer > 0) // GCE_block[3] = '\x05'; - if (Main_current_layer == Main_backups->Pages->Nb_layers -1) + Set_layer(context, current_layer); + + if (current_layer == context->Nb_layers -1) { // "Infinite" delay for last frame GCE_block[4] = 255; @@ -2227,8 +2229,8 @@ void Save_GIF(void) block_identifier=0x2C; IDB.Pos_X=0; IDB.Pos_Y=0; - IDB.Image_width=Main_image_width; - IDB.Image_height=Main_image_height; + IDB.Image_width=context->Width; + IDB.Image_height=context->Height; IDB.Indicator=0x07; // Image non entrelacée, pas de palette locale. IDB.Nb_bits_pixel=8; // Image 256 couleurs; @@ -2267,12 +2269,12 @@ void Save_GIF(void) ////////////////////////////////////////////// COMPRESSION LZW // - start=current_string=GIF_next_pixel(&IDB); + start=current_string=GIF_next_pixel(context, &IDB); descend=1; do { - current_char=GIF_next_pixel(&IDB); + current_char=GIF_next_pixel(context, &IDB); // On regarde si dans la table on aurait pas une chaîne // équivalente à current_string+Caractere @@ -2432,9 +2434,6 @@ void Save_GIF(void) } // On a pu ouvrir le fichier en écriture else File_error=1; - - // Restore original index of current layer - Main_current_layer = old_current_layer; } @@ -2469,13 +2468,13 @@ T_PCX_Header PCX_header; // -- Tester si un fichier est au format PCX -------------------------------- -void Test_PCX(void) +void Test_PCX(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((file=fopen(filename, "rb"))) { @@ -2522,7 +2521,7 @@ void Test_PCX(void) // -- Lire un fichier au format PCX ----------------------------------------- // -- Afficher une ligne PCX codée sur 1 seul plan avec moins de 256 c. -- - void Draw_PCX_line(short y_pos, byte depth) + void Draw_PCX_line(T_IO_Context *context, short y_pos, byte depth) { short x_pos; byte color; @@ -2530,14 +2529,14 @@ void Test_PCX(void) byte byte_mask=(1<Width; x_pos++) { color=(LBM_buffer[x_pos/reduction]>>((reduction_minus_one-(x_pos%reduction))*depth)) & byte_mask; - Pixel_load_function(x_pos,y_pos,color); + Set_pixel(context, x_pos,y_pos,color); } } -void Load_PCX(void) +void Load_PCX(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -2558,7 +2557,7 @@ void Load_PCX(void) long image_size; byte * buffer; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -2585,45 +2584,45 @@ void Load_PCX(void) Read_bytes(file,&(PCX_header.Filler),54) ) { - Main_image_width=PCX_header.X_max-PCX_header.X_min+1; - Main_image_height=PCX_header.Y_max-PCX_header.Y_min+1; + context->Width=PCX_header.X_max-PCX_header.X_min+1; + context->Height=PCX_header.Y_max-PCX_header.Y_min+1; Original_screen_X=PCX_header.Screen_X; Original_screen_Y=PCX_header.Screen_Y; if (PCX_header.Plane!=3) { - Init_preview(Main_image_width,Main_image_height,file_size,FORMAT_PCX,PIXEL_SIMPLE); + Pre_load(context, context->Width,context->Height,file_size,FORMAT_PCX,PIXEL_SIMPLE,0); if (File_error==0) { // On prépare la palette à accueillir les valeurs du fichier PCX if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); nb_colors=(dword)(1<4) - memcpy(Main_palette,PCX_header.Palette_16c,48); + memcpy(context->Palette,PCX_header.Palette_16c,48); else { - Main_palette[1].R=0; - Main_palette[1].G=0; - Main_palette[1].B=0; + context->Palette[1].R=0; + context->Palette[1].G=0; + context->Palette[1].B=0; byte1=PCX_header.Palette_16c[3]>>5; if (nb_colors==4) { // Pal. CGA "alakon" (du Turc Allahkoum qui signifie "à la con" :)) - memcpy(Main_palette+1,palette_CGA,9); + memcpy(context->Palette+1,palette_CGA,9); if (!(byte1&2)) { - Main_palette[1].B=84; - Main_palette[2].B=84; - Main_palette[3].B=84; + context->Palette[1].B=84; + context->Palette[2].B=84; + context->Palette[3].B=84; } } // Palette monochrome (on va dire que c'est du N&B) else { - Main_palette[1].R=252; - Main_palette[1].G=252; - Main_palette[1].B=252; + context->Palette[1].R=252; + context->Palette[1].G=252; + context->Palette[1].B=252; } } @@ -2639,9 +2638,9 @@ void Load_PCX(void) int index; // On lit la palette 256c que ces crétins ont foutue à la fin du fichier for(index=0;index<256;index++) - if ( ! Read_byte(file,&Main_palette[index].R) - || ! Read_byte(file,&Main_palette[index].G) - || ! Read_byte(file,&Main_palette[index].B) ) + if ( ! Read_byte(file,&(context->Palette[index].R)) + || ! Read_byte(file,&(context->Palette[index].G)) + || ! Read_byte(file,&(context->Palette[index].B)) ) { File_error=2; DEBUG("ERROR READING PCX PALETTE !",index); @@ -2649,8 +2648,8 @@ void Load_PCX(void) } } } - Set_palette(Main_palette); - Remap_fileselector(); + Set_palette(context->Palette); + Remap_fileselector(context); // Maintenant qu'on a lu la palette que ces crétins sont allés foutre // à la fin, on retourne juste après le header pour lire l'image. @@ -2670,7 +2669,7 @@ void Load_PCX(void) { /*Init_lecture();*/ - image_size=(long)PCX_header.Bytes_per_plane_line*Main_image_height; + image_size=(long)PCX_header.Bytes_per_plane_line*context->Height; if (PCX_header.Depth==8) // 256 couleurs (1 plan) { @@ -2688,7 +2687,7 @@ void Load_PCX(void) { for (index=0; indexHeight) && (!File_error)); y_pos++) { for (x_pos=0; ((x_posHeight) && (!File_error);y_pos++) { if ((width_read=Read_bytes(file,LBM_buffer,line_size))) { if (PCX_header.Plane==1) - for (x_pos=0; x_posWidth;x_pos++) + Set_pixel(context, x_pos,y_pos,LBM_buffer[x_pos]); else { if (PCX_header.Depth==1) - Draw_ILBM_line(y_pos,real_line_size); + Draw_ILBM_line(context, y_pos,real_line_size); else - Draw_PCX_line(y_pos,PCX_header.Depth); + Draw_PCX_line(context, y_pos,PCX_header.Depth); } } else @@ -2773,7 +2772,7 @@ void Load_PCX(void) { // Image 24 bits!!! - Init_preview_24b(Main_image_width,Main_image_height,file_size,FORMAT_PCX); + Pre_load(context,context->Width,context->Height,file_size,FORMAT_PCX,PIXEL_SIMPLE,1); if (File_error==0) { @@ -2782,12 +2781,12 @@ void Load_PCX(void) if (!PCX_header.Compression) { - for (y_pos=0;(y_posHeight) && (!File_error);y_pos++) { if (Read_bytes(file,buffer,line_size)) { - for (x_pos=0; x_posWidth; x_pos++) + Set_pixel_24b(context, x_pos,y_pos,buffer[x_pos+(PCX_header.Bytes_per_plane_line*0)],buffer[x_pos+(PCX_header.Bytes_per_plane_line*1)],buffer[x_pos+(PCX_header.Bytes_per_plane_line*2)]); } else File_error=2; @@ -2797,7 +2796,7 @@ void Load_PCX(void) { /*Init_lecture();*/ - for (y_pos=0,position=0;(y_posHeight) && (!File_error);) { // Lecture et décompression de la ligne if(Read_byte(file,&byte1)!=1) File_error=2; @@ -2814,8 +2813,8 @@ void Load_PCX(void) buffer[position++]=byte2; if (position>=line_size) { - for (x_pos=0; x_posWidth; x_pos++) + Set_pixel_24b(context, x_pos,y_pos,buffer[x_pos+(PCX_header.Bytes_per_plane_line*0)],buffer[x_pos+(PCX_header.Bytes_per_plane_line*1)],buffer[x_pos+(PCX_header.Bytes_per_plane_line*2)]); y_pos++; position=0; } @@ -2827,8 +2826,8 @@ void Load_PCX(void) buffer[position++]=byte1; if (position>=line_size) { - for (x_pos=0; x_posWidth; x_pos++) + Set_pixel_24b(context, x_pos,y_pos,buffer[x_pos+(PCX_header.Bytes_per_plane_line*0)],buffer[x_pos+(PCX_header.Bytes_per_plane_line*1)],buffer[x_pos+(PCX_header.Bytes_per_plane_line*2)]); y_pos++; position=0; } @@ -2858,7 +2857,7 @@ void Load_PCX(void) // -- Ecrire un fichier au format PCX --------------------------------------- -void Save_PCX(void) +void Save_PCX(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -2872,7 +2871,7 @@ void Save_PCX(void) - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -2885,14 +2884,14 @@ void Save_PCX(void) PCX_header.Depth=8; PCX_header.X_min=0; PCX_header.Y_min=0; - PCX_header.X_max=Main_image_width-1; - PCX_header.Y_max=Main_image_height-1; + PCX_header.X_max=context->Width-1; + PCX_header.Y_max=context->Height-1; PCX_header.X_dpi=0; PCX_header.Y_dpi=0; - memcpy(PCX_header.Palette_16c,Main_palette,48); + memcpy(PCX_header.Palette_16c,context->Palette,48); PCX_header.Reserved=0; PCX_header.Plane=1; - PCX_header.Bytes_per_plane_line=(Main_image_width&1)?Main_image_width+1:Main_image_width; + PCX_header.Bytes_per_plane_line=(context->Width&1)?context->Width+1:context->Width; PCX_header.Palette_info=1; PCX_header.Screen_X=Screen_width; PCX_header.Screen_Y=Screen_height; @@ -2921,22 +2920,22 @@ void Save_PCX(void) Init_write_buffer(); - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) { - pixel_read=Read_pixel_function(0,y_pos); + pixel_read=Get_pixel(context, 0,y_pos); // Compression et écriture de la ligne for (x_pos=0; ((x_pos1) || (last_pixel>=0xC0) ) @@ -2955,7 +2954,7 @@ void Save_PCX(void) // Ecriture de la palette if (!File_error) { - if (! Write_bytes(file,Main_palette,sizeof(T_Palette))) + if (! Write_bytes(file,context->Palette,sizeof(T_Palette))) File_error=1; } } @@ -2984,7 +2983,7 @@ typedef struct } T_SCx_Header; // -- Tester si un fichier est au format SCx -------------------------------- -void Test_SCx(void) +void Test_SCx(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -2992,7 +2991,7 @@ void Test_SCx(void) T_SCx_Header SCx_header; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -3018,7 +3017,7 @@ void Test_SCx(void) // -- Lire un fichier au format SCx ----------------------------------------- -void Load_SCx(void) +void Load_SCx(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -3028,7 +3027,7 @@ void Load_SCx(void) T_SCx_Header SCx_header; T_Palette SCx_Palette; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -3043,7 +3042,7 @@ void Load_SCx(void) && Read_byte(file, &(SCx_header.Planes)) ) { - Init_preview(SCx_header.Width,SCx_header.Height,file_size,FORMAT_SCx,PIXEL_SIMPLE); + Pre_load(context, SCx_header.Width,SCx_header.Height,file_size,FORMAT_SCx,PIXEL_SIMPLE,0); if (File_error==0) { if (!SCx_header.Planes) @@ -3054,41 +3053,41 @@ void Load_SCx(void) if (Read_bytes(file,SCx_Palette,size)) { if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); Palette_64_to_256(SCx_Palette); - memcpy(Main_palette,SCx_Palette,size); - Set_palette(Main_palette); - Remap_fileselector(); + memcpy(context->Palette,SCx_Palette,size); + Set_palette(context->Palette); + Remap_fileselector(context); - Main_image_width=SCx_header.Width; - Main_image_height=SCx_header.Height; + context->Width=SCx_header.Width; + context->Height=SCx_header.Height; if (!SCx_header.Planes) { // 256 couleurs (raw) - LBM_buffer=(byte *)malloc(Main_image_width); + LBM_buffer=(byte *)malloc(context->Width); - for (y_pos=0;(y_posHeight) && (!File_error);y_pos++) { - if (Read_bytes(file,LBM_buffer,Main_image_width)) - for (x_pos=0; x_posWidth)) + for (x_pos=0; x_posWidth;x_pos++) + Set_pixel(context, x_pos,y_pos,LBM_buffer[x_pos]); else File_error=2; } } else { // moins de 256 couleurs (planar) - size=((Main_image_width+7)>>3)*SCx_header.Planes; + size=((context->Width+7)>>3)*SCx_header.Planes; real_size=(size/SCx_header.Planes)<<3; LBM_buffer=(byte *)malloc(size); HBPm1=SCx_header.Planes-1; Image_HAM=0; - for (y_pos=0;(y_posHeight) && (!File_error);y_pos++) { if (Read_bytes(file,LBM_buffer,size)) - Draw_ILBM_line(y_pos,real_size); + Draw_ILBM_line(context, y_pos,real_size); else File_error=2; } @@ -3109,14 +3108,38 @@ void Load_SCx(void) } // -- Sauver un fichier au format SCx --------------------------------------- -void Save_SCx(void) +void Save_SCx(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; short x_pos,y_pos; T_SCx_Header SCx_header; - - Get_full_filename(filename,1); + byte last_char; + + last_char=strlen(context->File_name)-1; + if (context->File_name[last_char]=='?') + { + if (context->Width<=320) + context->File_name[last_char]='I'; + else + { + if (context->Width<=360) + context->File_name[last_char]='Q'; + else + { + if (context->Width<=640) + context->File_name[last_char]='F'; + else + { + if (context->Width<=800) + context->File_name[last_char]='N'; + else + context->File_name[last_char]='O'; + } + } + } + } + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -3124,12 +3147,12 @@ void Save_SCx(void) if ((file=fopen(filename,"wb"))) { T_Palette palette_64; - memcpy(palette_64,Main_palette,sizeof(T_Palette)); + memcpy(palette_64,context->Palette,sizeof(T_Palette)); Palette_256_to_64(palette_64); memcpy(SCx_header.Filler1,"RIX3",4); - SCx_header.Width=Main_image_width; - SCx_header.Height=Main_image_height; + SCx_header.Width=context->Width; + SCx_header.Height=context->Height; SCx_header.Filler2=0xAF; SCx_header.Planes=0x00; @@ -3143,9 +3166,9 @@ void Save_SCx(void) { Init_write_buffer(); - for (y_pos=0; ((y_posHeight) && (!File_error)); y_pos++) + for (x_pos=0; x_posWidth; x_pos++) + Write_one_byte(file,Get_pixel(context, x_pos,y_pos)); End_write(file); fclose(file); @@ -3174,13 +3197,13 @@ void Save_SCx(void) #ifndef __no_pnglib__ // -- Tester si un fichier est au format PNG -------------------------------- -void Test_PNG(void) +void Test_PNG(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier byte png_header[8]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -3199,7 +3222,7 @@ void Test_PNG(void) png_bytep * Row_pointers; // -- Lire un fichier au format PNG ----------------------------------------- -void Load_PNG(void) +void Load_PNG(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -3209,7 +3232,7 @@ void Load_PNG(void) png_structp png_ptr; png_infop info_ptr; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -3263,7 +3286,7 @@ void Load_PNG(void) png_uint_32 res_y; // Comment (tEXt) - Main_comment[0]='\0'; // Clear the previous comment + context->Comment[0]='\0'; // Clear the previous comment if ((num_text=png_get_text(png_ptr, info_ptr, &text_ptr, NULL))) { while (num_text--) @@ -3272,8 +3295,8 @@ void Load_PNG(void) { int size; size = Min(text_ptr[num_text].text_length, COMMENT_SIZE); - strncpy(Main_comment, text_ptr[num_text].text, size); - Main_comment[size]='\0'; + strncpy(context->Comment, text_ptr[num_text].text, size); + context->Comment[size]='\0'; break; // Skip all others tEXt chunks } } @@ -3287,18 +3310,18 @@ void Load_PNG(void) { if (res_y/res_x>1) { - Ratio_of_loaded_image=PIXEL_WIDE; + context->Ratio=PIXEL_WIDE; } else if (res_x/res_y>1) { - Ratio_of_loaded_image=PIXEL_TALL; + context->Ratio=PIXEL_TALL; } } } if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) - Init_preview_24b(info_ptr->width,info_ptr->height,File_length_file(file),FORMAT_PNG); + Pre_load(context,info_ptr->width,info_ptr->height,File_length_file(file),FORMAT_PNG,PIXEL_SIMPLE,1); else - Init_preview(info_ptr->width,info_ptr->height,File_length_file(file),FORMAT_PNG,Ratio_of_loaded_image); + Pre_load(context, info_ptr->width,info_ptr->height,File_length_file(file),FORMAT_PNG,context->Ratio,0); if (File_error==0) { @@ -3336,9 +3359,9 @@ void Load_PNG(void) // Create greyscale palette for (x=0;x<256;x++) { - Main_palette[x].R=x; - Main_palette[x].G=x; - Main_palette[x].B=x; + context->Palette[x].R=x; + context->Palette[x].G=x; + context->Palette[x].B=x; } } else if (color_type == PNG_COLOR_TYPE_PALETTE) // Palette images @@ -3348,33 +3371,33 @@ void Load_PNG(void) { // Clear unused colors if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); } // Load the palette png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); for (x=0;xPalette[x].R=palette[x].red; + context->Palette[x].G=palette[x].green; + context->Palette[x].B=palette[x].blue; } free(palette); } if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA) { - Set_palette(Main_palette); - Remap_fileselector(); + Set_palette(context->Palette); + Remap_fileselector(context); } - Main_image_width=info_ptr->width; - Main_image_height=info_ptr->height; + context->Width=info_ptr->width; + context->Height=info_ptr->height; png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); // Allocate row pointers - Row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * Main_image_height); + Row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * context->Height); row_pointers_allocated = 0; /* read file */ @@ -3387,42 +3410,45 @@ void Load_PNG(void) { // 8bpp - for (y=0; yHeight; y++) Row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes); row_pointers_allocated = 1; png_read_image(png_ptr, Row_pointers); - for (y=0; yHeight; y++) + for (x=0; xWidth; x++) + Set_pixel(context, x, y, Row_pointers[y][x]); } else { - // 24bpp - - if (Pixel_load_24b==Pixel_load_in_24b_preview) + switch (context->Type) { - // It's a preview - // Unfortunately we need to allocate loads of memory - for (y=0; yrowbytes); - row_pointers_allocated = 1; + case CONTEXT_PREVIEW: + // 24bpp - png_read_image(png_ptr, Row_pointers); + // It's a preview + // Unfortunately we need to allocate loads of memory + for (y=0; yHeight; y++) + Row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes); + row_pointers_allocated = 1; + + png_read_image(png_ptr, Row_pointers); + + for (y=0; yHeight; y++) + for (x=0; xWidth; x++) + Set_pixel_24b(context, x, y, Row_pointers[y][x*3],Row_pointers[y][x*3+1],Row_pointers[y][x*3+2]); + break; + case CONTEXT_MAIN_IMAGE: + case CONTEXT_BRUSH: + // It's loading an actual image + // We'll save memory and time by writing directly into + // our pre-allocated 24bit buffer + for (y=0; yHeight; y++) + Row_pointers[y] = (png_byte*) (&(context->Buffer_image_24b[y * context->Width])); + png_read_image(png_ptr, Row_pointers); + break; - for (y=0; yHeight; y++) free(Row_pointers[y]); } free(Row_pointers); @@ -3462,7 +3488,7 @@ void Load_PNG(void) File_error=1; } -void Save_PNG(void) +void Save_PNG(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -3471,7 +3497,7 @@ void Save_PNG(void) png_structp png_ptr; png_infop info_ptr; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; Row_pointers = NULL; @@ -3490,11 +3516,11 @@ void Save_PNG(void) /* en-tete */ if (!setjmp(png_jmpbuf(png_ptr))) { - png_set_IHDR(png_ptr, info_ptr, Main_image_width, Main_image_height, + png_set_IHDR(png_ptr, info_ptr, context->Width, context->Height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_set_PLTE(png_ptr, info_ptr, (png_colorp)Main_palette, 256); + png_set_PLTE(png_ptr, info_ptr, (png_colorp)context->Palette, 256); { // Commentaires texte PNG // Cette partie est optionnelle @@ -3503,10 +3529,10 @@ void Save_PNG(void) {-1, "Title", NULL, 0} }; int nb_text_chunks=1; - if (Main_comment[0]) + if (context->Comment[0]) { - text_ptr[1].text=Main_comment; - text_ptr[1].text_length=strlen(Main_comment); + text_ptr[1].text=context->Comment; + text_ptr[1].text_length=strlen(context->Comment); nb_text_chunks=2; } png_set_text(png_ptr, info_ptr, text_ptr, nb_text_chunks); @@ -3527,10 +3553,10 @@ void Save_PNG(void) png_write_info(png_ptr, info_ptr); /* ecriture des pixels de l'image */ - Row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * Main_image_height); - pixel_ptr = (Read_pixel_function==Read_pixel_from_brush)?Brush:Main_screen; - for (y=0; yHeight); + pixel_ptr = context->Target_address; + for (y=0; yHeight; y++) + Row_pointers[y] = (png_byte*)(pixel_ptr+y*context->Pitch); if (!setjmp(png_jmpbuf(png_ptr))) { diff --git a/filesel.c b/filesel.c index 1c12bb87..c1c689ca 100644 --- a/filesel.c +++ b/filesel.c @@ -70,6 +70,11 @@ 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: // // * 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); } - +// +// Print the current file name +// void Print_filename_in_fileselector(void) -// -// Affiche Main_filename dans le Fileselect -// { 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); } @@ -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); // 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 Print_filename_in_fileselector(); // 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]; - strcpy(old_filename,Main_filename); + strcpy(old_filename,Selector_filename); // On regarde si la liste a bougé if (file_scroller->Position!=Main_fileselector_position) @@ -945,8 +949,8 @@ void Scroll_fileselector(T_Scroller_button * file_scroller) Window_draw_slider(file_scroller); } // On récupére le nom du schmilblick à "accéder" - Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Main_filename,&Selected_type); - if (strcmp(old_filename,Main_filename)) + Get_selected_item(&Filelist, Main_fileselector_position,Main_fileselector_offset,Selector_filename,&Selected_type); + if (strcmp(old_filename,Selector_filename)) New_preview_is_needed=1; // On affiche le nouveau nom de fichier @@ -1022,7 +1026,7 @@ char * Find_filename_match(T_Fileselector *list, char * fname) 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=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 has_clicked_ok=0;// Indique si on a clické sur Load ou Save ou sur //un bouton enclenchant Load ou Save juste après. - T_Components * initial_palette; // | Données concernant l'image qui - 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 + byte initial_back_color; // | fout en l'air (c'te conne). 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 save_filename[MAX_PATH_CHARACTERS]; + char initial_comment[COMMENT_SIZE+1]; char * most_matching_filename; short window_shortcut; - if (image) + if (context->Type == CONTEXT_MAIN_IMAGE) window_shortcut = load?(0x100+BUTTON_LOAD):(0x100+BUTTON_SAVE); else window_shortcut = load?SPECIAL_LOAD_BRUSH:SPECIAL_SAVE_BRUSH; - initial_palette=(T_Components *)malloc(sizeof(T_Palette)); - memcpy(initial_palette,Main_palette,sizeof(T_Palette)); - - 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); + // Backup data that needs be restored on "cancel" + initial_back_color=Back_color; + strcpy(initial_comment,context->Comment); + if (load) { - if (image) + if (context->Type == CONTEXT_MAIN_IMAGE) Open_window(310,200,"Load picture"); else Open_window(310,200,"Load brush"); @@ -1072,7 +1066,7 @@ byte Button_Load_or_Save(byte load, byte image) } else { - if (image) + if (context->Type == CONTEXT_MAIN_IMAGE) Open_window(310,200,"Save picture"); else Open_window(310,200,"Save brush"); @@ -1092,7 +1086,7 @@ byte Button_Load_or_Save(byte load, byte image) } // Affichage du commentaire 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 @@ -1159,7 +1153,7 @@ byte Button_Load_or_Save(byte load, byte image) } else { - chdir(Main_file_directory); + chdir(context->File_directory); 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 // la barre de sélection - strcpy(Main_filename,initial_filename); + strcpy(Selector_filename,context->File_name); // On affiche le nouveau nom de fichier Print_filename_in_fileselector(); } - Pixel_load_function=Pixel_load_in_preview; New_preview_is_needed=1; Update_window_area(0,0,Window_width, Window_height); @@ -1195,10 +1188,10 @@ byte Button_Load_or_Save(byte load, byte image) if(load) { // Determine the type - if(File_exists(Main_filename)) + if(File_exists(Selector_filename)) { Selected_type = 0; - if(Directory_exists(Main_filename)) Selected_type = 1; + if(Directory_exists(Selector_filename)) Selected_type = 1; } else { @@ -1207,7 +1200,7 @@ byte Button_Load_or_Save(byte load, byte image) } else { - if(Directory_exists(Main_filename)) Selected_type = 1; + if(Directory_exists(Selector_filename)) Selected_type = 1; else Selected_type = 0; } has_clicked_ok=1; @@ -1217,7 +1210,7 @@ byte Button_Load_or_Save(byte load, byte image) break; case 3 : // Delete - if (Filelist.Nb_elements && (*Main_filename!='.') && Selected_type!=2) + if (Filelist.Nb_elements && (*Selector_filename!='.') && Selected_type!=2) { char * message; Hide_cursor(); @@ -1235,10 +1228,10 @@ byte Button_Load_or_Save(byte load, byte image) // Si c'est un fichier if (Main_fileselector_position+Main_fileselector_offset>=Filelist.Nb_directories) // On efface le fichier (si on peut) - temp=(!remove(Main_filename)); + temp=(!remove(Selector_filename)); else // Si c'est un repertoire // 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é { @@ -1291,7 +1284,7 @@ byte Button_Load_or_Save(byte load, byte image) Main_fileselector_offset=temp; // 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 Print_filename_in_fileselector(); // 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 // actuel au lieu de changer de répertoire. if (Main_fileselector_position+Main_fileselector_offsetComment) ) { - Readline(45,70,Main_comment,32,0); + Readline(45,70,context->Comment,32,0); Display_cursor(); } break; case 8 : // Saisie du nom de fichier // 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 // n'y a pas de '.' dans le nom du fichier. - for(temp=0,dummy=0; ((Main_filename[temp]) && (!dummy)); temp++) - if (Main_filename[temp]=='.') + for(temp=0,dummy=0; ((Selector_filename[temp]) && (!dummy)); temp++) + if (Selector_filename[temp]=='.') dummy=1; if (!dummy) { if (Get_fileformat(Main_format)->Default_extension) { - if(!Directory_exists(Main_filename)) + if(!Directory_exists(Selector_filename)) { - strcat(Main_filename, "."); - strcat(Main_filename,Get_fileformat(Main_format)->Default_extension); + strcat(Selector_filename, "."); + strcat(Selector_filename,Get_fileformat(Main_format)->Default_extension); } } else @@ -1381,19 +1374,19 @@ byte Button_Load_or_Save(byte load, byte image) // put default extension // (but maybe we should browse through all available ones until we find // something suitable ?) - if(!Directory_exists(Main_filename)) + if(!Directory_exists(Selector_filename)) { - strcat(Main_filename, ".pkm"); + strcat(Selector_filename, ".pkm"); } } } if(load) { // Determine the type - if(File_exists(Main_filename)) + if(File_exists(Selector_filename)) { Selected_type = 0; - if(Directory_exists(Main_filename)) Selected_type = 1; + if(Directory_exists(Selector_filename)) Selected_type = 1; } else { @@ -1402,7 +1395,7 @@ byte Button_Load_or_Save(byte load, byte image) } else { - if(Directory_exists(Main_filename)) Selected_type = 1; + if(Directory_exists(Selector_filename)) Selected_type = 1; else Selected_type = 0; } @@ -1412,7 +1405,7 @@ byte Button_Load_or_Save(byte load, byte image) else { // Restore the old filename - strcpy(Main_filename, save_filename); + strcpy(Selector_filename, save_filename); Print_filename_in_fileselector(); } Display_cursor(); @@ -1443,7 +1436,7 @@ byte Button_Load_or_Save(byte load, byte image) if (Config.Bookmark_directory[clicked_button-10]) { *quicksearch_filename=0; - strcpy(Main_filename,Config.Bookmark_directory[clicked_button-10]); + strcpy(Selector_filename,Config.Bookmark_directory[clicked_button-10]); Selected_type=1; has_clicked_ok=1; *quicksearch_filename=0; @@ -1567,7 +1560,7 @@ byte Button_Load_or_Save(byte load, byte image) if (!strcmp(Filelist.First->Full_name,PARENT_DIR)) { // On va dans le répertoire parent. - strcpy(Main_filename,PARENT_DIR); + strcpy(Selector_filename,PARENT_DIR); Selected_type=1; has_clicked_ok=1; } @@ -1622,7 +1615,7 @@ byte Button_Load_or_Save(byte load, byte image) has_clicked_ok=0; // 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)); else { @@ -1632,7 +1625,7 @@ byte Button_Load_or_Save(byte load, byte image) } // On doit rentrer dans le répertoire: - if (!chdir(Main_filename)) + if (!chdir(Selector_filename)) { 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 { - strcpy(Main_file_directory,Main_current_directory); + strcpy(context->File_directory,Main_current_directory); if (!load) Main_fileformat=Main_format; save_or_load_image=1; @@ -1682,7 +1675,7 @@ byte Button_Load_or_Save(byte load, byte image) // Affichage du commentaire 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(); // 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) ) { - strcpy(Main_file_directory,Main_current_directory); - + T_IO_Context preview_context; + + Init_context_preview(&preview_context, Selector_filename, Main_current_directory); 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); 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 @@ -1725,19 +1715,22 @@ byte Button_Load_or_Save(byte load, byte image) } while ( (!has_clicked_ok) && (clicked_button!=2) ); - // Si on annule, on restaure l'ancien commentaire - if (clicked_button==2) - strcpy(Main_comment,initial_comment); + if (has_clicked_ok) + { + 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 // 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); + Back_color=initial_back_color; Compute_optimal_menu_colors(Main_palette); temp=(Window_pos_Y+(Window_height*Menu_factor_Y) #include +#include "const.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) { @@ -26,35 +29,35 @@ unsigned short addrCalc(unsigned char vcc, unsigned char rcc, unsigned char hcc, 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}; - 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}; - 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; 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; } -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}; - 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 *tmpBuffer; @@ -137,7 +140,7 @@ unsigned char *raw2crtc(unsigned short width, unsigned short height, unsigned ch { x = (hcc << 1 | cclk); 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; } } diff --git a/loadsave.c b/loadsave.c index 33714c12..96b2c66d 100644 --- a/loadsave.c +++ b/loadsave.c @@ -49,90 +49,90 @@ #include "engine.h" // -- PKM ------------------------------------------------------------------- -void Test_PKM(void); -void Load_PKM(void); -void Save_PKM(void); +void Test_PKM(T_IO_Context *); +void Load_PKM(T_IO_Context *); +void Save_PKM(T_IO_Context *); // -- LBM ------------------------------------------------------------------- -void Test_LBM(void); -void Load_LBM(void); -void Save_LBM(void); +void Test_LBM(T_IO_Context *); +void Load_LBM(T_IO_Context *); +void Save_LBM(T_IO_Context *); // -- GIF ------------------------------------------------------------------- -void Test_GIF(void); -void Load_GIF(void); -void Save_GIF(void); +void Test_GIF(T_IO_Context *); +void Load_GIF(T_IO_Context *); +void Save_GIF(T_IO_Context *); // -- PCX ------------------------------------------------------------------- -void Test_PCX(void); -void Load_PCX(void); -void Save_PCX(void); +void Test_PCX(T_IO_Context *); +void Load_PCX(T_IO_Context *); +void Save_PCX(T_IO_Context *); // -- BMP ------------------------------------------------------------------- -void Test_BMP(void); -void Load_BMP(void); -void Save_BMP(void); +void Test_BMP(T_IO_Context *); +void Load_BMP(T_IO_Context *); +void Save_BMP(T_IO_Context *); // -- IMG ------------------------------------------------------------------- -void Test_IMG(void); -void Load_IMG(void); -void Save_IMG(void); +void Test_IMG(T_IO_Context *); +void Load_IMG(T_IO_Context *); +void Save_IMG(T_IO_Context *); // -- SCx ------------------------------------------------------------------- -void Test_SCx(void); -void Load_SCx(void); -void Save_SCx(void); +void Test_SCx(T_IO_Context *); +void Load_SCx(T_IO_Context *); +void Save_SCx(T_IO_Context *); // -- CEL ------------------------------------------------------------------- -void Test_CEL(void); -void Load_CEL(void); -void Save_CEL(void); +void Test_CEL(T_IO_Context *); +void Load_CEL(T_IO_Context *); +void Save_CEL(T_IO_Context *); // -- KCF ------------------------------------------------------------------- -void Test_KCF(void); -void Load_KCF(void); -void Save_KCF(void); +void Test_KCF(T_IO_Context *); +void Load_KCF(T_IO_Context *); +void Save_KCF(T_IO_Context *); // -- PAL ------------------------------------------------------------------- -void Test_PAL(void); -void Load_PAL(void); -void Save_PAL(void); +void Test_PAL(T_IO_Context *); +void Load_PAL(T_IO_Context *); +void Save_PAL(T_IO_Context *); // -- PI1 ------------------------------------------------------------------- -void Test_PI1(void); -void Load_PI1(void); -void Save_PI1(void); +void Test_PI1(T_IO_Context *); +void Load_PI1(T_IO_Context *); +void Save_PI1(T_IO_Context *); // -- PC1 ------------------------------------------------------------------- -void Test_PC1(void); -void Load_PC1(void); -void Save_PC1(void); +void Test_PC1(T_IO_Context *); +void Load_PC1(T_IO_Context *); +void Save_PC1(T_IO_Context *); // -- NEO ------------------------------------------------------------------- -void Test_NEO(void); -void Load_NEO(void); -void Save_NEO(void); +void Test_NEO(T_IO_Context *); +void Load_NEO(T_IO_Context *); +void Save_NEO(T_IO_Context *); // -- C64 ------------------------------------------------------------------- -void Test_C64(void); -void Load_C64(void); -void Save_C64(void); +void Test_C64(T_IO_Context *); +void Load_C64(T_IO_Context *); +void Save_C64(T_IO_Context *); // -- SCR (Amstrad CPC) -void Save_SCR(void); +void Save_SCR(T_IO_Context *); // -- PNG ------------------------------------------------------------------- #ifndef __no_pnglib__ -void Test_PNG(void); -void Load_PNG(void); -void Save_PNG(void); +void Test_PNG(T_IO_Context *); +void Load_PNG(T_IO_Context *); +void Save_PNG(T_IO_Context *); #endif // -- SDL_Image ------------------------------------------------------------- // (TGA, BMP, PNM, XPM, XCF, PCX, GIF, JPG, TIF, LBM, PNG, ICO) -void Load_SDL_Image(void); +void Load_SDL_Image(T_IO_Context *); -// ENUM Name TestFunc LoadFunc SaveFunc PalOnly Comment Layers Ext Exts +// ENUM Name TestFunc LoadFunc SaveFunc PalOnly Comment Layers Ext Exts T_Format File_formats[NB_KNOWN_FORMATS] = { {FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, 0, "", "gif;png;bmp;pcx;pkm;lbm;iff;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;kcf;pal;c64;koa;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"}, {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"}, @@ -157,157 +157,166 @@ T_Format File_formats[NB_KNOWN_FORMATS] = { {FORMAT_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"}, }; -// Cette variable est alimentée après chargement réussi d'une image. -// Actuellement seul le format PNG peut donner autre chose que PIXEL_SIMPLE. -enum PIXEL_RATIO Ratio_of_loaded_image=PIXEL_SIMPLE; - -// Chargement des pixels dans l'écran principal -void Pixel_load_in_current_screen(word x_pos,word y_pos,byte color) +/// Set the color of a pixel (on load) +void Set_pixel(T_IO_Context *context, short x_pos, short y_pos, byte color) { - //if ((x_pos>=0) && (y_pos>=0)) //Toujours vrai ? - if ((x_pos=0) && (y_pos>=0)) - if ((x_pos=context->Width) || (y_pos>=context->Height)) + return; + + switch (context->Type) { - Compute_optimal_menu_colors(Main_palette); + // Chargement des pixels dans l'écran principal + case CONTEXT_MAIN_IMAGE: + Pixel_in_current_screen(x_pos,y_pos,color,0); + break; + + // Chargement des pixels dans la brosse + case CONTEXT_BRUSH: + //Pixel_in_brush(x_pos,y_pos,color); + *(context->Buffer_image + y_pos * context->Pitch + x_pos)=color; + break; + + // Chargement des pixels dans la preview + case CONTEXT_PREVIEW: + if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0)) + { + if (context->Ratio == PIXEL_WIDE && + Pixel_ratio != PIXEL_WIDE && + Pixel_ratio != PIXEL_WIDE2) + { + Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X*2), + context->Preview_pos_Y+(y_pos/context->Preview_factor_Y), + color); + Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X*2)+1, + context->Preview_pos_Y+(y_pos/context->Preview_factor_Y), + color); + } + else if (context->Ratio == PIXEL_TALL && + Pixel_ratio != PIXEL_TALL && + Pixel_ratio != PIXEL_TALL2) + { + Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X), + context->Preview_pos_Y+(y_pos/context->Preview_factor_Y*2), + color); + Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X), + context->Preview_pos_Y+(y_pos/context->Preview_factor_Y*2)+1, + color); + } + else + Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X), + context->Preview_pos_Y+(y_pos/context->Preview_factor_Y), + color); + } - if( - ( - Main_palette[MC_Black].R==Main_palette[MC_Dark].R && - Main_palette[MC_Black].G==Main_palette[MC_Dark].G && - Main_palette[MC_Black].B==Main_palette[MC_Dark].B - ) || - ( - Main_palette[MC_Light].R==Main_palette[MC_Dark].R && - Main_palette[MC_Light].G==Main_palette[MC_Dark].G && - Main_palette[MC_Light].B==Main_palette[MC_Dark].B - ) || - ( - Main_palette[MC_White].R==Main_palette[MC_Light].R && - Main_palette[MC_White].G==Main_palette[MC_Light].G && - Main_palette[MC_White].B==Main_palette[MC_Light].B - ) - ) - { - // Si on charge une image monochrome, le fileselect ne sera plus visible. Dans ce cas on force quelques couleurs à des valeurs sures + break; + + } - int black = - Main_palette[MC_Black].R + - Main_palette[MC_Black].G + - Main_palette[MC_Black].B; - int white = - Main_palette[MC_White].R + - Main_palette[MC_White].G + - Main_palette[MC_White].B; +} - //Set_color(MC_Light,(2*white+black)/9,(2*white+black)/9,(2*white+black)/9); - //Set_color(MC_Dark,(2*black+white)/9,(2*black+white)/9,(2*black+white)/9); - Main_palette[MC_Dark].R=(2*black+white)/9; - Main_palette[MC_Dark].G=(2*black+white)/9; - Main_palette[MC_Dark].B=(2*black+white)/9; - Main_palette[MC_Light].R=(2*white+black)/9; - Main_palette[MC_Light].G=(2*white+black)/9; - Main_palette[MC_Light].B=(2*white+black)/9; - Set_palette(Main_palette); - } - Remap_screen_after_menu_colors_change(); +void Remap_fileselector(T_IO_Context *context) +{ + switch (context->Type) + { + case CONTEXT_PREVIEW: + + Compute_optimal_menu_colors(context->Palette); + /* + if( + ( + context->Palette[MC_Black].R==context->Palette[MC_Dark].R && + context->Palette[MC_Black].G==context->Palette[MC_Dark].G && + context->Palette[MC_Black].B==context->Palette[MC_Dark].B + ) || + ( + context->Palette[MC_Light].R==context->Palette[MC_Dark].R && + context->Palette[MC_Light].G==context->Palette[MC_Dark].G && + context->Palette[MC_Light].B==context->Palette[MC_Dark].B + ) || + ( + context->Palette[MC_White].R==context->Palette[MC_Light].R && + context->Palette[MC_White].G==context->Palette[MC_Light].G && + context->Palette[MC_White].B==context->Palette[MC_Light].B + ) + ) + + { + // Si on charge une image monochrome, le fileselect ne sera plus visible. Dans ce cas on force quelques couleurs à des valeurs sures + + int black = + Main_palette[MC_Black].R + + Main_palette[MC_Black].G + + Main_palette[MC_Black].B; + int white = + Main_palette[MC_White].R + + Main_palette[MC_White].G + + Main_palette[MC_White].B; + + //Set_color(MC_Light,(2*white+black)/9,(2*white+black)/9,(2*white+black)/9); + //Set_color(MC_Dark,(2*black+white)/9,(2*black+white)/9,(2*black+white)/9); + Main_palette[MC_Dark].R=(2*black+white)/9; + Main_palette[MC_Dark].G=(2*black+white)/9; + Main_palette[MC_Dark].B=(2*black+white)/9; + Main_palette[MC_Light].R=(2*white+black)/9; + Main_palette[MC_Light].G=(2*white+black)/9; + Main_palette[MC_Light].B=(2*white+black)/9; + + Set_palette(Main_palette); + } + */ + Remap_screen_after_menu_colors_change(); + break; + case CONTEXT_MAIN_IMAGE: + case CONTEXT_BRUSH: + break; + } } -int Image_24b; -T_Components * Buffer_image_24b; -Func_24b_display Pixel_load_24b; - - // Chargement des pixels dans le buffer 24b -void Pixel_load_in_24b_buffer(short x_pos,short y_pos,byte r,byte g,byte b) -{ - int index; - - if ((x_pos>=0) && (y_pos>=0)) - if ((x_pos=context->Width || y_pos>=context->Height) + return; + + switch(context->Type) { - color=((r >> 5) << 5) | - ((g >> 5) << 2) | - ((b >> 6)); - Pixel(Preview_pos_X+(x_pos/Preview_factor_X), - Preview_pos_Y+(y_pos/Preview_factor_Y), - color); + case CONTEXT_MAIN_IMAGE: + case CONTEXT_BRUSH: + { + int index; + + index=(y_pos*context->Width)+x_pos; + context->Buffer_image_24b[index].R=r; + context->Buffer_image_24b[index].G=g; + context->Buffer_image_24b[index].B=b; + } + break; + + case CONTEXT_PREVIEW: + { + + if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0)) + { + color=((r >> 5) << 5) | + ((g >> 5) << 2) | + ((b >> 6)); + Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X), + context->Preview_pos_Y+(y_pos/context->Preview_factor_Y), + color); + } + } + break; } } + + // Création d'une palette fake void Set_palette_fake_24b(T_Palette palette) { @@ -322,149 +331,104 @@ void Set_palette_fake_24b(T_Palette palette) } } -// Initialization for a 24bit image -void Init_preview_24b(short width,short height,long size,int format) -{ - // Call common processing - Init_preview(width,height,size,format, PIXEL_SIMPLE); - - if (File_error) - return; - - if (Pixel_load_function==Pixel_load_in_preview) - { - // Choose 24bit pixel "writer" - Pixel_load_24b=Pixel_load_in_24b_preview; - - // Load palette - Set_palette_fake_24b(Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); - } - else - { - // Choose 24bit pixel "writer" - Pixel_load_24b=Pixel_load_in_24b_buffer; - - // Allocate 24bit buffer - Buffer_image_24b= - (T_Components *)malloc(width*height*sizeof(T_Components)); - if (!Buffer_image_24b) - { - // Print an error message - - // The following is to be sure the messagfe is readable - Compute_optimal_menu_colors(Main_palette); - Message_out_of_memory(); - if (Pixel_load_function==Pixel_load_in_current_screen) - File_error=1; // 1 => On n'a pas perdu l'image courante - else - File_error=3; // 3 => Chargement de brosse échoué - } - else - Image_24b=1; // On a un buffer à traiter en fin de chargement - } -} - - - - -void Init_preview(short width,short height,long size,int format, enum PIXEL_RATIO ratio) -// -// Cette procédure doit être appelée par les routines de chargement -// d'images. -// Elle doit être appelée entre le moment où l'on connait la dimension de -// l'image (dimension réelle, pas dimension tronquée) et l'affichage du -// premier point. -// +/// +/// 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) { char str[10]; - if (Pixel_load_function==Pixel_load_in_preview) + context->Pitch = width; // default + context->Width = width; + context->Height = height; + context->Ratio = ratio; + context->Nb_layers = 1; + + switch(context->Type) { - // Préparation du chargement d'une preview: - - // Affichage des données "Image size:" - if ((width<10000) && (height<10000)) - { - Num2str(width,str,4); - Num2str(height,str+5,4); - str[4]='x'; - Print_in_window(143,59,str,MC_Black,MC_Light); - } - else - { - Print_in_window(143,59,"VERY BIG!",MC_Black,MC_Light); - } - - // Affichage de la taille du fichier - if (size<1048576) - { - // Le fichier fait moins d'un Mega, on affiche sa taille direct - Num2str(size,str,7); - Print_in_window(236,59,str,MC_Black,MC_Light); - } - else if ((size/1024)<100000) - { - // Le fichier fait plus d'un Mega, on peut afficher sa taille en Ko - Num2str(size/1024,str,5); - strcpy(str+5,"Kb"); - Print_in_window(236,59,str,MC_Black,MC_Light); - } - else - { - // Le fichier fait plus de 100 Mega octets (cas très rare :)) - Print_in_window(236,59,"LARGE!!",MC_Black,MC_Light); - } - - // Affichage du vrai format - if (format!=Main_format) - { - Print_in_window( 59,59,Get_fileformat(format)->Label,MC_Black,MC_Light); - } - - // On efface le commentaire précédent - Window_rectangle(45,70,32*8,8,MC_Light); - // Affichage du commentaire - if (Get_fileformat(format)->Comment) - Print_in_window(45,70,Main_comment,MC_Black,MC_Light); - - // Calculs des données nécessaires à l'affichage de la preview: - if (ratio == PIXEL_WIDE && - Pixel_ratio != PIXEL_WIDE && - Pixel_ratio != PIXEL_WIDE2) - width*=2; - else if (ratio == PIXEL_TALL && - Pixel_ratio != PIXEL_TALL && - Pixel_ratio != PIXEL_TALL2) - height*=2; - - Preview_factor_X=Round_div_max(width,122*Menu_factor_X); - Preview_factor_Y=Round_div_max(height, 82*Menu_factor_Y); - - if ( (!Config.Maximize_preview) && (Preview_factor_X!=Preview_factor_Y) ) - { - if (Preview_factor_X>Preview_factor_Y) - Preview_factor_Y=Preview_factor_X; + // Preview + case CONTEXT_PREVIEW: + // Préparation du chargement d'une preview: + // Affichage des données "Image size:" + if ((width<10000) && (height<10000)) + { + Num2str(width,str,4); + Num2str(height,str+5,4); + str[4]='x'; + Print_in_window(143,59,str,MC_Black,MC_Light); + } else - Preview_factor_X=Preview_factor_Y; - } - - Preview_pos_X=Window_pos_X+183*Menu_factor_X; - Preview_pos_Y=Window_pos_Y+ 95*Menu_factor_Y; - - // On nettoie la zone où va s'afficher la preview: - Window_rectangle(183,95,120,80,MC_Light); - - // Un update pour couvrir les 4 zones: 3 libellés plus le commentaire - Update_window_area(45,48,256,30); - // Zone de preview - Update_window_area(183,95,120,80); - } - else - { - if (Pixel_load_function==Pixel_load_in_current_screen) - { + { + Print_in_window(143,59,"VERY BIG!",MC_Black,MC_Light); + } + + // Affichage de la taille du fichier + if (file_size<1048576) + { + // Le fichier fait moins d'un Mega, on affiche sa taille direct + Num2str(file_size,str,7); + Print_in_window(236,59,str,MC_Black,MC_Light); + } + else if ((file_size/1024)<100000) + { + // Le fichier fait plus d'un Mega, on peut afficher sa taille en Ko + Num2str(file_size/1024,str,5); + strcpy(str+5,"Kb"); + Print_in_window(236,59,str,MC_Black,MC_Light); + } + else + { + // Le fichier fait plus de 100 Mega octets (cas très rare :)) + Print_in_window(236,59,"LARGE!!",MC_Black,MC_Light); + } + + // Affichage du vrai format + if (format!=Main_format) + { + Print_in_window( 59,59,Get_fileformat(format)->Label,MC_Black,MC_Light); + } + + // On efface le commentaire précédent + Window_rectangle(45,70,32*8,8,MC_Light); + // Affichage du commentaire + if (Get_fileformat(format)->Comment) + Print_in_window(45,70,Main_comment,MC_Black,MC_Light); + + // Calcul des données nécessaires à l'affichage de la preview: + if (ratio == PIXEL_WIDE && + Pixel_ratio != PIXEL_WIDE && + Pixel_ratio != PIXEL_WIDE2) + width*=2; + else if (ratio == PIXEL_TALL && + Pixel_ratio != PIXEL_TALL && + Pixel_ratio != PIXEL_TALL2) + height*=2; + + context->Preview_factor_X=Round_div_max(width,122*Menu_factor_X); + context->Preview_factor_Y=Round_div_max(height, 82*Menu_factor_Y); + + if ( (!Config.Maximize_preview) && (context->Preview_factor_X!=context->Preview_factor_Y) ) + { + if (context->Preview_factor_X>context->Preview_factor_Y) + context->Preview_factor_Y=context->Preview_factor_X; + else + context->Preview_factor_X=context->Preview_factor_Y; + } + + context->Preview_pos_X=Window_pos_X+183*Menu_factor_X; + context->Preview_pos_Y=Window_pos_Y+ 95*Menu_factor_Y; + + // On nettoie la zone où va s'afficher la preview: + Window_rectangle(183,95,120,80,MC_Light); + + // Un update pour couvrir les 4 zones: 3 libellés plus le commentaire + Update_window_area(45,48,256,30); + // Zone de preview + Update_window_area(183,95,120,80); + break; + + // Other loading + case CONTEXT_MAIN_IMAGE: if (Backup_with_new_dimensions(0,1,width,height)) { // La nouvelle page a pu être allouée, elle est pour l'instant pleine @@ -472,81 +436,72 @@ void Init_preview(short width,short height,long size,int format, enum PIXEL_RATI // Normalement tout va bien, tout est sous contrôle... // Load into layer 0, by default. + context->Nb_layers=1; Main_current_layer=0; + Main_layers_visible=1<<0; + Set_layer(context,0); + + // Remove previous comment, unless we load just a palette + if (! Get_fileformat(context->Format)->Palette_only) + context->Comment[0]='\0'; } else { // Afficher un message d'erreur - // Pour être sûr que ce soit lisible. - Compute_optimal_menu_colors(Main_palette); + Compute_optimal_menu_colors(context->Palette); Message_out_of_memory(); File_error=1; // 1 => On n'a pas perdu l'image courante } - } - else // chargement dans la brosse - { - free(Brush); - free(Smear_brush); - Brush=(byte *)malloc(width*height); - Brush_width=width; - Brush_height=height; - if (Brush) + break; + + case CONTEXT_BRUSH: + context->Buffer_image = (byte *)malloc(width*height); + if (! context->Buffer_image) { - Smear_brush=(byte *)malloc(width*height); - if (!Smear_brush) - File_error=3; - } - else File_error=3; - } - } -} - - -// Calcul du nom complet du fichier -void Get_full_filename(char * filename, byte is_colorix_format) -{ - byte last_char; - - strcpy(filename,Main_file_directory); - - //On va ajouter un séparateur à la fin du chemin s'il n'y est pas encore - if (filename[strlen(filename)-1]!=PATH_SEPARATOR[0]) - strcat(filename,PATH_SEPARATOR); - - // Si on est en train de sauvegarder une image Colorix, on calcule son ext. - if (is_colorix_format) - { - last_char=strlen(Main_filename)-1; - if (Main_filename[last_char]=='?') - { - if (Main_image_width<=320) - Main_filename[last_char]='I'; - else - { - if (Main_image_width<=360) - Main_filename[last_char]='Q'; - else - { - if (Main_image_width<=640) - Main_filename[last_char]='F'; - else - { - if (Main_image_width<=800) - Main_filename[last_char]='N'; - else - Main_filename[last_char]='O'; - } - } + return; } - } + context->Target_address=context->Buffer_image; + + break; } - strcat(filename,Main_filename); + if (File_error) + return; + + // Extra process for truecolor images + if (truecolor) + { + //context->Is_truecolor = 1; + + switch(context->Type) + { + case CONTEXT_MAIN_IMAGE: + case CONTEXT_BRUSH: + // Allocate 24bit buffer + context->Buffer_image_24b= + (T_Components *)malloc(width*height*sizeof(T_Components)); + if (!context->Buffer_image_24b) + { + // Print an error message + // The following is to be sure the message is readable + Compute_optimal_menu_colors(context->Palette); + Message_out_of_memory(); + File_error=1; + } + break; + + case CONTEXT_PREVIEW: + // Load palette + Set_palette_fake_24b(context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); + break; + } + } } - ///////////////////////////////////////////////////////////////////////////// // Gestion des lectures et écritures // ///////////////////////////////////////////////////////////////////////////// @@ -596,7 +551,7 @@ void Set_file_error(int value) // -- Charger n'importe connu quel type de fichier d'image (ou palette) ----- -void Load_image(byte image) +void Load_image(T_IO_Context *context) { unsigned int index; // index de balayage des formats T_Format *format = &(File_formats[2]); // Format du fichier à charger @@ -606,11 +561,11 @@ void Load_image(byte image) // charger le format du fichier: File_error=1; - if (Main_format>FORMAT_ALL_FILES) + if (context->Format>FORMAT_ALL_FILES) { - format = Get_fileformat(Main_format); + format = Get_fileformat(context->Format); if (format->Test) - format->Test(); + format->Test(context); } if (File_error) @@ -625,7 +580,7 @@ void Load_image(byte image) continue; // On appelle le testeur du format: - format->Test(); + format->Test(context); // On s'arrête si le fichier est au bon format: if (File_error==0) break; @@ -635,18 +590,15 @@ void Load_image(byte image) if (File_error) { // Last try: with SDL_image - Image_24b=0; - Ratio_of_loaded_image=PIXEL_SIMPLE; - - Load_SDL_Image(); + Load_SDL_Image(context); if (File_error) { // Sinon, l'appelant sera au courant de l'échec grace à File_error; // et si on s'apprêtait à faire un chargement définitif de l'image (pas // une preview), alors on flash l'utilisateur. - if (Pixel_load_function!=Pixel_load_in_preview) - Error(0); + //if (Pixel_load_function!=Pixel_load_in_preview) + // Error(0); return; } } @@ -654,77 +606,96 @@ void Load_image(byte image) // Si on a su déterminer avec succès le format du fichier: { // On peut charger le fichier: - Image_24b=0; - Ratio_of_loaded_image=PIXEL_SIMPLE; // Dans certains cas il est possible que le chargement plante // après avoir modifié la palette. TODO - format->Load(); + format->Load(context); } if (File_error>0) { Error(0); } + + // Post-load - if (Image_24b) + if (context->Buffer_image_24b) { // On vient de charger une image 24b if (!File_error) { - // Le chargement a réussi, on peut faire la conversion en 256 couleurs - if (Pixel_load_function==Pixel_load_in_current_screen) + switch(context->Type) { - // Cas d'un chargement dans l'image - Hide_cursor(); - Cursor_shape=CURSOR_SHAPE_HOURGLASS; - Display_cursor(); - Flush_update(); - if (Convert_24b_bitmap_to_256(Main_backups->Pages->Image[0],Buffer_image_24b,Main_image_width,Main_image_height,Main_palette)) - File_error=2; - else - { - Set_palette(Main_palette); - } - } - else - { - // Cas d'un chargement dans la brosse - Hide_cursor(); - Cursor_shape=CURSOR_SHAPE_HOURGLASS; - Display_cursor(); - Flush_update(); - if (Convert_24b_bitmap_to_256(Brush,Buffer_image_24b,Brush_width,Brush_height,Main_palette)) - File_error=2; + case CONTEXT_MAIN_IMAGE: + // Cas d'un chargement dans l'image + Hide_cursor(); + Cursor_shape=CURSOR_SHAPE_HOURGLASS; + Display_cursor(); + Flush_update(); + if (Convert_24b_bitmap_to_256(Main_backups->Pages->Image[0],context->Buffer_image_24b,context->Width,context->Height,context->Palette)) + File_error=2; + else + { + Set_palette(context->Palette); + } + break; + + case CONTEXT_BRUSH: + // Cas d'un chargement dans la brosse + Hide_cursor(); + Cursor_shape=CURSOR_SHAPE_HOURGLASS; + Display_cursor(); + Flush_update(); + if (Convert_24b_bitmap_to_256(Brush,context->Buffer_image_24b,context->Width,context->Height,context->Palette)) + File_error=2; + break; + + case CONTEXT_PREVIEW: + // nothing to do + break; + } } - - free(Buffer_image_24b); + free(context->Buffer_image_24b); } - if (image) + if (context->Type == CONTEXT_MAIN_IMAGE) { if ( (File_error!=1) && (!format->Palette_only) ) { + /* Shouldn't happen ??? if (Pixel_load_function==Pixel_load_in_preview) { dword color_usage[256]; - Count_used_colors_screen_area(color_usage,Preview_pos_X,Preview_pos_Y,Main_image_width/Preview_factor_X,Main_image_height/Preview_factor_Y); + Count_used_colors_screen_area(color_usage,context->Preview_pos_X,context->Preview_pos_Y,context->Width/context->Preview_factor_X,context->Height/context->Preview_factor_Y); //Count_used_colors(color_usage); Display_cursor(); Set_nice_menu_colors(color_usage,1); Hide_cursor(); } - + */ + strcpy(Main_backups->Pages->Filename,context->File_name); + strcpy(Main_backups->Pages->File_directory,context->File_directory); + // On considère que l'image chargée n'est plus modifiée Main_image_is_modified=0; // Et on documente la variable Main_fileformat avec la valeur: Main_fileformat=format->Identifier; + // already done initially on Backup_with_new_dimensions + //Main_image_width= context->Width; + //Main_image_height= context->Height; + memcpy(Main_palette, context->Palette, sizeof(T_Palette)); + memcpy(Main_backups->Pages->Palette, context->Palette, sizeof(T_Palette)); + + Main_current_layer = context->Nb_layers - 1; + Main_layers_visible = (2<Pages); } } + else if (context->Type == CONTEXT_BRUSH && File_error==0) + { + free(Brush); + Brush=context->Buffer_image; + context->Buffer_image = NULL; + + Brush_width=context->Width; + Brush_height=context->Height; + + free(Smear_brush); + 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; + Smear_brush=(byte *)malloc(Smear_brush_width*Smear_brush_height); + if (!Smear_brush) + File_error=3; + } } // -- Sauver n'importe quel type connu de fichier d'image (ou palette) ------ -void Save_image(byte image) +void Save_image(T_IO_Context *context) { T_Format *format; @@ -752,45 +739,43 @@ void Save_image(byte image) // sauver le format du fichier: (Est-ce vraiment utile??? Je ne crois pas!) File_error=1; - if (image) + switch (context->Type) { - if (!File_formats[Main_fileformat-1].Supports_layers - && Main_backups->Pages->Nb_layers > 1) - { - if (! Confirmation_box("This format doesn't support layers\nand will save a flattened copy of\nyour image. Proceed?")) + case CONTEXT_MAIN_IMAGE: + if (!File_formats[context->Format-1].Supports_layers + && Main_backups->Pages->Nb_layers > 1) { - // File_error is already set to 1. - return; + if (! Confirmation_box("This format doesn't support layers\nand will save a flattened copy of\nyour image. Proceed?")) + { + // File_error is already set to 1. + return; + } } - Read_pixel_function=Read_pixel_from_current_screen; - } - else - { - Read_pixel_function=Read_pixel_from_current_layer; - } + break; + + case CONTEXT_BRUSH: + break; + + case CONTEXT_PREVIEW: + break; } - else - { - Read_pixel_function=Read_pixel_from_brush; - } - - format = Get_fileformat(Main_fileformat); + format = Get_fileformat(context->Format); if (format->Save) - format->Save(); + format->Save(context); if (File_error) Error(0); - else - { - if ((image) && !(Get_fileformat(Main_fileformat)->Palette_only)) - Main_image_is_modified=0; - } -} - - -void Load_SDL_Image(void) -{ + //else + //{ + // if ((image) && !(Get_fileformat(Main_fileformat)->Palette_only)) + // Main_image_is_modified=0; + //} +} + + +void Load_SDL_Image(T_IO_Context *context) +{ char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier word x_pos,y_pos; // long file_size; @@ -799,7 +784,7 @@ void Load_SDL_Image(void) SDL_Surface * surface; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; surface = IMG_Load(filename); @@ -816,22 +801,21 @@ void Load_SDL_Image(void) { // 8bpp image - Init_preview(surface->w, surface->h, file_size ,FORMAT_MISC, PIXEL_SIMPLE); + Pre_load(context, surface->w, surface->h, file_size ,FORMAT_MISC, PIXEL_SIMPLE, 0); + // Read palette if (surface->format->palette) { - Get_SDL_Palette(surface->format->palette, Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); + Get_SDL_Palette(surface->format->palette, context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); } - Main_image_width=surface->w; - Main_image_height=surface->h; - for (y_pos=0; y_posHeight; y_pos++) { - for (x_pos=0; x_posWidth; x_pos++) { - Pixel_load_function(x_pos,y_pos,Get_SDL_pixel_8(surface, x_pos, y_pos)); + Set_pixel(context, x_pos, y_pos, Get_SDL_pixel_8(surface, x_pos, y_pos)); } } @@ -839,16 +823,15 @@ void Load_SDL_Image(void) else { // Hi/Trucolor - Init_preview_24b(surface->w, surface->h, file_size ,FORMAT_ALL_IMAGES); - Main_image_width=surface->w; - Main_image_height=surface->h; + Pre_load(context, surface->w, surface->h, file_size ,FORMAT_ALL_IMAGES, PIXEL_SIMPLE, 1); - for (y_pos=0; y_posHeight; y_pos++) { - for (x_pos=0; x_posWidth; x_pos++) { pixel = Get_SDL_pixel_hicolor(surface, x_pos, y_pos); - Pixel_load_24b( + Set_pixel_24b( + context, x_pos, y_pos, ((pixel & surface->format->Rmask) >> surface->format->Rshift) << surface->format->Rloss, @@ -874,6 +857,9 @@ void Emergency_backup(const char *fname, byte *source, int width, int height, T_ short x_pos,y_pos; T_IMG_Header IMG_header; + if (width == 0 || height == 0 || source == NULL) + return; + strcpy(filename,Config_directory); strcat(filename,fname); @@ -913,8 +899,8 @@ void Emergency_backup(const char *fname, byte *source, int width, int height, T_ void Image_emergency_backup() { - Emergency_backup("phoenix.img",Main_screen, Main_image_width, Main_image_height, &Main_palette); - Emergency_backup("phoenix2.img",Spare_screen, Spare_image_width, Spare_image_height, &Spare_palette); + Emergency_backup("a999999.bkp",Main_screen, Main_image_width, Main_image_height, &Main_palette); + Emergency_backup("b999999.bkp",Spare_screen, Spare_image_width, Spare_image_height, &Spare_palette); } T_Format * Get_fileformat(byte format) @@ -934,3 +920,357 @@ T_Format * Get_fileformat(byte format) // enum.... return safe_default; } + +/// Query the color of a pixel (to save) +byte Get_pixel(T_IO_Context *context, short x, short y) +{ + return *(context->Target_address + y*context->Pitch + x); +} + +/// Cleans up resources (currently: the 24bit buffer) +void Destroy_context(T_IO_Context *context) +{ + if (context->Buffer_image_24b) + { + free(context->Buffer_image_24b); + } + if (context->Buffer_image) + { + free(context->Buffer_image); + } + memset(context, 0, sizeof(T_IO_Context)); +} + +/// Setup for loading a preview in fileselector +void Init_context_preview(T_IO_Context * context, char *file_name, char *file_directory) +{ + memset(context, 0, sizeof(T_IO_Context)); + + context->Type = CONTEXT_PREVIEW; + context->File_name = file_name; + context->File_directory = file_directory; + context->Format = Main_fileformat; // FIXME ? + +} + +/// Setup for loading/saving the current main image +void Init_context_layered_image(T_IO_Context * context, char *file_name, char *file_directory) +{ + memset(context, 0, sizeof(T_IO_Context)); + + context->Type = CONTEXT_MAIN_IMAGE; + context->File_name = file_name; + context->File_directory = file_directory; + context->Format = Main_fileformat; + memcpy(context->Palette, Main_palette, sizeof(T_Palette)); + context->Width = Main_image_width; + context->Height = Main_image_height; + context->Nb_layers = Main_backups->Pages->Nb_layers; + strcpy(context->Comment, Main_comment); + context->Transparent_color=Main_backups->Pages->Transparent_color; + if (Pixel_ratio == PIXEL_WIDE || Pixel_ratio == PIXEL_WIDE2) + context->Ratio=PIXEL_WIDE; + else if (Pixel_ratio == PIXEL_TALL || Pixel_ratio == PIXEL_TALL2) + context->Ratio=PIXEL_TALL; + else + context->Ratio=PIXEL_SIMPLE; + context->Target_address=Main_backups->Pages->Image[0]; + context->Pitch=Main_image_width; + +} + +/// 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) +{ + memset(context, 0, sizeof(T_IO_Context)); + + context->Type = CONTEXT_BRUSH; + context->File_name = file_name; + context->File_directory = file_directory; + context->Format = Brush_fileformat; + // Use main screen's palette + memcpy(context->Palette, Main_palette, sizeof(T_Palette)); + context->Width = Brush_width; + context->Height = Brush_height; + context->Nb_layers = 1; + // Solid save... could use BG color maybe + context->Transparent_color=-1; + context->Ratio=PIXEL_SIMPLE; + context->Target_address=Brush; + context->Pitch=Brush_width; + +} + +/// Function to call when need to switch layers. +void Set_layer(T_IO_Context *context, byte layer) +{ + if (context->Type == CONTEXT_MAIN_IMAGE) + { + // This awful thing is the part that happens on load + while (layer > (context->Nb_layers-1)) + { + if (Add_layer(Main_backups, layer)) + { + // Failure to add a layer on load: + // Position on last layer + layer = context->Nb_layers-1; + break; + } + context->Nb_layers = Main_backups->Pages->Nb_layers; + Main_current_layer = layer; + Main_layers_visible = (2<Target_address=Main_backups->Pages->Image[layer]; + } +} + +// ============================================ +// Safety backups +// ============================================ + + +typedef struct T_String_list +{ + char * String; + struct T_String_list * Next; +} T_String_list; + +/// A list of files, used for scanning a directory +T_String_list *Backups_main = NULL; +/// A list of files, used for scanning a directory +T_String_list *Backups_spare = NULL; + +/// +/// Adds a file to Backups_main or Backups_spare lists, if it's a backup. +/// +void Add_backup_file(const char *name) +{ + T_String_list ** list; + T_String_list * elem; + int i; + char file_name[MAX_PATH_CHARACTERS]; + + // Only files names of the form a0000000.* and b0000000.* are expected + + Extract_filename(file_name, name); + + // Check first character + if (file_name[0]=='a') + { + list = &Backups_main; + } + else if (file_name[0]=='b') + { + list = &Backups_spare; + } + else + // Not a good file + return; + + // Check next characters till file extension + i = 1; + while (file_name[i]!='\0' && file_name[i]!='.') + { + if (file_name[i]< '0' || file_name[i] > '9') + { + // Not a good file + return; + } + i++; + } + + // Add to list (top insertion) + elem = (T_String_list *)malloc(sizeof(T_String_list)); + elem->String=strdup(file_name); + elem->Next=*list; + *list=elem; +} + + +/// String comparer for sorting +int String_compare (const void * a, const void * b) +{ + return strcmp(*(char**)a,*(char**)b); +} + +/// +/// Reload safety backups, by loading several files in the right order. +/// +byte Process_backups(T_String_list **list) +{ + int nb_files; + int i; + char ** files_vector; + T_String_list *element; + + if (*list == NULL) + return 0; + + // Count files + nb_files=0; + element=*list; + while (element != NULL) + { + nb_files++; + element = element->Next; + } + // Allocate a vector + files_vector = (char **)malloc(sizeof(char *) * nb_files); + // Copy from list to vector + for (i=0;iString; + next = (*list)->Next; + free(*list); + *list = next; + } + + // Sort the vector + qsort (files_vector, nb_files , sizeof(char **), String_compare); + + for (i=0; i < nb_files; i++) + { + // Load this file + T_IO_Context context; + Init_context_layered_image(&context, files_vector[i], Config_directory); + Load_image(&context); + Destroy_context(&context); + Redraw_layered_image(); + Display_all_screen(); + } + + // Done with the vector + for (i=0; i < nb_files; i++) + { + free(files_vector[i]); + } + free(files_vector); + + return nb_files; +} + + +/// +/// Checks if there are any pending safety backups, and then opens them. +/// +int Check_recovery(void) +{ + int restored_spare; + int restored_main; + + Backups_main = NULL; + Backups_spare = NULL; + For_each_file(Config_directory, Add_backup_file); + + // Do the processing twice: once for possible backups of the main page, + // once for possible backups of the spare. + + restored_spare = Process_backups(&Backups_spare); + if (restored_spare) + { + Main_offset_X=0; + Main_offset_Y=0; + Compute_limits(); + Compute_paintbrush_coordinates(); + Redraw_layered_image(); + if (Backups_main) + Button_Page(); + } + restored_main = Process_backups(&Backups_main); + + if (restored_main) + { + Main_offset_X=0; + Main_offset_Y=0; + Compute_limits(); + Compute_paintbrush_coordinates(); + Redraw_layered_image(); + } + /* + if (restored_main||restored_spare) + { + Display_all_screen(); + return 1; + }*/ + return 0; +} + +const int Rotation_safety_backup = 8; + +const int Min_interval_for_safety_backup = 30000; +const int Min_edits_for_safety_backup = 10; + +const int Max_interval_for_safety_backup = 60000; +const int Max_edits_for_safety_backup = 30; + +void Rotate_safety_backups(void) +{ + Uint32 now; + T_IO_Context context; + char file_name[12+1]; + char deleted_file[MAX_PATH_CHARACTERS]; + + now = SDL_GetTicks(); + // It's time to save if either: + // - Many edits have taken place + // - A minimum number of edits have taken place AND a minimum time has passed + // - At least one edit was done, and a maximum time has passed + if ((Main_edits_since_safety_backup > Max_edits_for_safety_backup) || + (Main_edits_since_safety_backup > Min_edits_for_safety_backup && + now > Main_time_of_safety_backup + Min_interval_for_safety_backup) || + (Main_edits_since_safety_backup > 1 && + now > Main_time_of_safety_backup + Max_interval_for_safety_backup)) + { + + // Clear a previous save (rotating saves) + sprintf(deleted_file, "%s%c%6.6d.bkp", + Config_directory, + Main_safety_backup_prefix, + (Main_safety_number + 1000000l - Rotation_safety_backup) % 1000000l); + remove(deleted_file); // no matter if fail + + // Reset counters + Main_edits_since_safety_backup=0; + Main_time_of_safety_backup=now; + + // Create a new file name and save + sprintf(file_name, "%c%6.6d.bkp", + Main_safety_backup_prefix, + Main_safety_number); + Init_context_layered_image(&context, file_name, Config_directory); + context.Format=FORMAT_GIF; + Save_image(&context); + Destroy_context(&context); + + Main_safety_number++; + } +} + +/// Remove safety backups. Need to call on normal program exit. +void Delete_safety_backups(void) +{ + T_String_list *element; + + Backups_main = NULL; + Backups_spare = NULL; + + For_each_file(Config_directory, Add_backup_file); + + for (element=Backups_main; element!=NULL; element=element->Next) + { + remove(element->String); + } + for (element=Backups_spare; element!=NULL; element=element->Next) + { + remove(element->String); + } + +} diff --git a/loadsave.h b/loadsave.h index 79f96234..7052e166 100644 --- a/loadsave.h +++ b/loadsave.h @@ -24,30 +24,108 @@ /// Also handles showing the preview in fileselectors. ////////////////////////////////////////////////////////////////////////////// +#ifndef __LOADSAVE_H__ +#define __LOADSAVE_H__ + +#include + +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_preview (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. -/// Handles loading an image or a brush, or previewing only. -/// @param image true if the fileselector is the one for loading images (not brush) -void Load_image(byte image); +void Load_image(T_IO_Context *context); /// /// High-level picture saving function. -/// @param image true if the image should be saved (instead of the brush) -void Save_image(byte image); +void Save_image(T_IO_Context *context); + +/// +/// 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. typedef struct { byte Identifier; ///< Identifier for this format in enum :FILE_FORMATS char *Label; ///< Five-letter label - Func_action Test; ///< Function which tests if the file is of this format - Func_action Load; ///< Function which loads an image of this format - Func_action Save; ///< Function which saves an image of this format + Func_IO Test; ///< Function which tests if the file is of this format + Func_IO Load; ///< Function which loads 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 Comment; ///< This file format allows a text comment 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. void Image_emergency_backup(void); +/* /// Pixel ratio of last loaded image: one of :PIXEL_SIMPLE, :PIXEL_WIDE or :PIXEL_TALL extern enum PIXEL_RATIO Ratio_of_loaded_image; +*/ 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. #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 // useful for fileformats.c, miscfileformats.c etc. @@ -96,6 +195,7 @@ typedef struct // Data for 24bit loading +/* typedef void (* Func_24b_display) (short,short,byte,byte,byte); 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 Pixel_load_in_24b_preview(short x_pos,short y_pos,byte r,byte g,byte b); - +*/ // 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 Write_one_byte(FILE *file, byte b); void End_write(FILE *file); -void Remap_fileselector(void); +#endif \ No newline at end of file diff --git a/main.c b/main.c index 8c6f0717..bce31af7 100644 --- a/main.c +++ b/main.c @@ -212,12 +212,13 @@ struct { #define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof(x[0])) // --------------------- 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 ; int index; + int file_in_command_line; - File_in_command_line = 0; + file_in_command_line = 0; Resolution_in_command_line = 0; Current_resolution = Config.Default_resolution; @@ -347,7 +348,7 @@ void Analyze_command_line(int argc, char * argv[]) break; default: // 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 Error(ERROR_COMMAND_LINE); @@ -356,22 +357,22 @@ void Analyze_command_line(int argc, char * argv[]) } else if (File_exists(argv[index])) { - File_in_command_line ++; + file_in_command_line ++; buffer = Realpath(argv[index], NULL); - if (File_in_command_line == 1) + if (file_in_command_line == 1) { // Separate path from filename - Extract_path(Main_file_directory, buffer); - Extract_filename(Main_filename, buffer); - free(buffer); + Extract_path(main_directory, buffer); + Extract_filename(main_filename, buffer); } else { - Extract_path(Spare_file_directory, buffer); - Extract_filename(Spare_filename, buffer); - free(buffer); + // Separate path from filename + Extract_path(spare_directory, buffer); + Extract_filename(spare_filename, buffer); } + free(buffer); } else { @@ -382,6 +383,7 @@ void Analyze_command_line(int argc, char * argv[]) break; } } + return file_in_command_line; } // ------------------------ Initialiser le programme ------------------------- @@ -390,8 +392,15 @@ int Init_program(int argc,char * argv[]) { int temp; int starting_videomode; - char program_directory[MAX_PATH_CHARACTERS]; + static char program_directory[MAX_PATH_CHARACTERS]; 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 // 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: 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: 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; + strcpy(Brush_current_directory,Main_current_directory); - strcpy(Brush_file_directory,Main_file_directory); - strcpy(Brush_filename ,Main_filename); + strcpy(Brush_file_directory,Main_current_directory); + strcpy(Brush_filename ,"NO_NAME.GIF"); Brush_fileformat =Main_fileformat; // 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 Main_comment[0]='\0'; - Spare_comment[0]='\0'; Brush_comment[0]='\0'; // On initialise d'ot' trucs @@ -480,6 +484,12 @@ int Init_program(int argc,char * argv[]) Spare_magnifier_offset_X=0; Spare_magnifier_offset_Y=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 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); } } + // Texte Init_text(); @@ -539,8 +550,6 @@ int Init_program(int argc,char * argv[]) Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND; Paintbrush_hidden=0; - Pixel_load_function=Pixel_load_in_current_screen; - // On initialise tout ce qui concerne les opérations et les effets Operation_stack_size=0; Selected_freehand_mode=OPERATION_CONTINUOUS_DRAW; @@ -618,7 +627,7 @@ int Init_program(int argc,char * argv[]) if (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; 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) if (Init_all_backup_lists(Screen_width,Screen_height)==0) 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) memset(Main_screen,0,Main_image_width*Main_image_height); @@ -745,6 +742,51 @@ int Init_program(int argc,char * argv[]) Brush_height=1; Capture_brush(0,0,0,0,0); *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); } @@ -772,6 +814,9 @@ void Program_shutdown(void) Config.Window_pos_y = 9999; #endif + // Remove the safety backups, this is normal exit + Delete_safety_backups(); + // On libère le buffer de gestion de lignes if(Horizontal_line_buffer) free(Horizontal_line_buffer); @@ -815,72 +860,12 @@ void Program_shutdown(void) // -------------------------- Procédure principale --------------------------- 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)) { Program_shutdown(); 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(); diff --git a/miscfileformats.c b/miscfileformats.c index dbb5917f..eafeeaae 100644 --- a/miscfileformats.c +++ b/miscfileformats.c @@ -39,11 +39,11 @@ //////////////////////////////////// PAL //////////////////////////////////// // -void Draw_palette_preview(void) +void Draw_palette_preview(T_IO_Context * context) { short index; - if (Pixel_load_function==Pixel_load_in_preview) + if (context->Type == CONTEXT_PREVIEW) for (index=0; index<256; index++) Window_rectangle(183+(index/16)*7,95+(index&15)*5,5,5,index); @@ -53,13 +53,13 @@ void Draw_palette_preview(void) // -- Tester si un fichier est au format PAL -------------------------------- -void Test_PAL(void) +void Test_PAL(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier long file_size; // Taille du fichier - Get_full_filename(filename, 0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error = 1; @@ -85,14 +85,14 @@ void Test_PAL(void) // -- Lire un fichier au format PAL ----------------------------------------- -void Load_PAL(void) +void Load_PAL(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier //long file_size; // Taille du fichier - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; // Ouverture du fichier @@ -103,18 +103,18 @@ void Load_PAL(void) if (file_size == sizeof(T_Palette)) { T_Palette palette_64; - // Init_preview(?); // Pas possible... pas d'image... + // Pre_load(context, ?); // Pas possible... pas d'image... - // Lecture du fichier dans Main_palette + // Lecture du fichier dans context->Palette if (Read_bytes(file, palette_64, sizeof(T_Palette))) { Palette_64_to_256(palette_64); - memcpy(Main_palette, palette_64, sizeof(T_Palette)); - Set_palette(Main_palette); - Remap_fileselector(); + memcpy(context->Palette, palette_64, sizeof(T_Palette)); + Set_palette(context->Palette); + Remap_fileselector(context); // On dessine une preview de la palette (si chargement = preview) - Draw_palette_preview(); + Draw_palette_preview(context); } else File_error = 2; @@ -135,15 +135,15 @@ void Load_PAL(void) for (i = 0; i < n; i++) { fscanf(file, "%d %d %d",&r, &g, &b); - Main_palette[i].R = r; - Main_palette[i].G = g; - Main_palette[i].B = b; + context->Palette[i].R = r; + context->Palette[i].G = g; + context->Palette[i].B = b; - Set_palette(Main_palette); - Remap_fileselector(); + Set_palette(context->Palette); + Remap_fileselector(context); // On dessine une preview de la palette (si chargement = preview) - Draw_palette_preview(); + Draw_palette_preview(context); } } else File_error = 2; @@ -159,13 +159,13 @@ void Load_PAL(void) // -- Sauver un fichier au format PAL --------------------------------------- -void Save_PAL(void) +void Save_PAL(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier //long file_size; // Taille du fichier - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -175,7 +175,7 @@ void Save_PAL(void) int i; fputs("JASC-PAL\n0100\n256\n", file); for (i = 0; i < 256; i++) - fprintf(file,"%d %d %d\n",Main_palette[i].R, Main_palette[i].G, Main_palette[i].B); + fprintf(file,"%d %d %d\n",context->Palette[i].R, context->Palette[i].G, context->Palette[i].B); } else // Si on n'a pas réussi à ouvrir le fichier, alors il y a eu une erreur { @@ -207,14 +207,14 @@ typedef struct } T_PKM_Header; // -- Tester si un fichier est au format PKM -------------------------------- -void Test_PKM(void) +void Test_PKM(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier T_PKM_Header header; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -243,7 +243,7 @@ void Test_PKM(void) // -- Lire un fichier au format PKM ----------------------------------------- -void Load_PKM(void) +void Load_PKM(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -258,7 +258,7 @@ void Load_PKM(void) dword Taille_pack; long file_size; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -275,7 +275,7 @@ void Load_PKM(void) Read_bytes(file,&header.Palette,sizeof(T_Palette)) && Read_word_le(file,&header.Jump)) { - Main_comment[0]='\0'; // On efface le commentaire + context->Comment[0]='\0'; // On efface le commentaire if (header.Jump) { index=0; @@ -298,10 +298,10 @@ void Load_PKM(void) else color=0; - if (Read_bytes(file,Main_comment,temp_byte)) + if (Read_bytes(file,context->Comment,temp_byte)) { index+=temp_byte; - Main_comment[temp_byte]='\0'; + context->Comment[temp_byte]='\0'; if (color) if (fseek(file,color,SEEK_CUR)) File_error=2; @@ -368,18 +368,18 @@ void Load_PKM(void) if (!File_error) { - Init_preview(header.Width,header.Height,file_size,FORMAT_PKM,PIXEL_SIMPLE); + Pre_load(context, header.Width,header.Height,file_size,FORMAT_PKM,PIXEL_SIMPLE,0); if (File_error==0) { - Main_image_width=header.Width; - Main_image_height=header.Height; - image_size=(dword)(Main_image_width*Main_image_height); + context->Width=header.Width; + context->Height=header.Height; + image_size=(dword)(context->Width*context->Height); // Palette lue en 64 - memcpy(Main_palette,header.Palette,sizeof(T_Palette)); - Palette_64_to_256(Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); + memcpy(context->Palette,header.Palette,sizeof(T_Palette)); + Palette_64_to_256(context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); Compteur_de_donnees_packees=0; Compteur_de_pixels=0; @@ -397,8 +397,8 @@ void Load_PKM(void) // Si ce n'est pas un octet de reconnaissance, c'est un pixel brut if ( (temp_byte!=header.Recog1) && (temp_byte!=header.Recog2) ) { - Pixel_load_function(Compteur_de_pixels % Main_image_width, - Compteur_de_pixels / Main_image_width, + Set_pixel(context, Compteur_de_pixels % context->Width, + Compteur_de_pixels / context->Width, temp_byte); Compteur_de_donnees_packees++; Compteur_de_pixels++; @@ -418,8 +418,8 @@ void Load_PKM(void) break; } for (index=0; indexWidth, + (Compteur_de_pixels+index) / context->Width, color); Compteur_de_pixels+=temp_byte; Compteur_de_donnees_packees+=3; @@ -433,8 +433,8 @@ void Load_PKM(void) } Read_word_be(file, &len); for (index=0; indexWidth, + (Compteur_de_pixels+index) / context->Width, color); Compteur_de_pixels+=len; Compteur_de_donnees_packees+=4; @@ -495,7 +495,7 @@ void Load_PKM(void) } -void Save_PKM(void) +void Save_PKM(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -513,19 +513,19 @@ void Save_PKM(void) memcpy(header.Ident,"PKM",3); header.Method=0; Find_recog(&header.Recog1,&header.Recog2); - header.Width=Main_image_width; - header.Height=Main_image_height; - memcpy(header.Palette,Main_palette,sizeof(T_Palette)); + header.Width=context->Width; + header.Height=context->Height; + memcpy(header.Palette,context->Palette,sizeof(T_Palette)); Palette_256_to_64(header.Palette); // Calcul de la taille du Post-header header.Jump=9; // 6 pour les dimensions de l'ecran + 3 pour la back-color - comment_size=strlen(Main_comment); + comment_size=strlen(context->Comment); if (comment_size) header.Jump+=comment_size+2; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; @@ -551,7 +551,7 @@ void Save_PKM(void) Write_one_byte(file,0); Write_one_byte(file,comment_size); for (Compteur_de_pixels=0; Compteur_de_pixelsComment[Compteur_de_pixels]); } // Ecriture des dimensions de l'écran Write_one_byte(file,1); @@ -566,9 +566,9 @@ void Save_PKM(void) Write_one_byte(file,Back_color); // Routine de compression PKM de l'image - image_size=(dword)(Main_image_width*Main_image_height); + image_size=(dword)(context->Width*context->Height); Compteur_de_pixels=0; - pixel_value=Read_pixel_function(0,0); + pixel_value=Get_pixel(context, 0,0); while ( (Compteur_de_pixelsWidth,Compteur_de_pixels / context->Width); } while ( (pixel_value==last_color) && (Compteur_de_pixels=image_size) break; - pixel_value=Read_pixel_function(Compteur_de_pixels % Main_image_width,Compteur_de_pixels / Main_image_width); + pixel_value=Get_pixel(context, Compteur_de_pixels % context->Width,Compteur_de_pixels / context->Width); } if ( (last_color!=header.Recog1) && (last_color!=header.Recog2) ) @@ -675,7 +675,7 @@ typedef struct // -- Tester si un fichier est au format CEL -------------------------------- -void Test_CEL(void) +void Test_CEL(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; int size; @@ -685,7 +685,7 @@ void Test_CEL(void) int file_size; File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); file_size=File_length(filename); if (file_size==0) { @@ -740,7 +740,7 @@ void Test_CEL(void) // -- Lire un fichier au format CEL ----------------------------------------- -void Load_CEL(void) +void Load_CEL(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -753,7 +753,7 @@ void Load_CEL(void) const long int header_size = (long int)(sizeof(header1.Width)+sizeof(header1.Height)); File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((file=fopen(filename, "rb"))) { if (Read_word_le(file,&(header1.Width)) @@ -764,24 +764,24 @@ void Load_CEL(void) && ( (((header1.Width+1)>>1)*header1.Height)==(file_size-header_size) ) ) { // Chargement d'un fichier CEL sans signature (vieux fichiers) - Main_image_width=header1.Width; - Main_image_height=header1.Height; - Original_screen_X=Main_image_width; - Original_screen_Y=Main_image_height; - Init_preview(Main_image_width,Main_image_height,file_size,FORMAT_CEL,PIXEL_SIMPLE); + context->Width=header1.Width; + context->Height=header1.Height; + Original_screen_X=context->Width; + Original_screen_Y=context->Height; + Pre_load(context, context->Width,context->Height,file_size,FORMAT_CEL,PIXEL_SIMPLE,0); if (File_error==0) { // Chargement de l'image /*Init_lecture();*/ - for (y_pos=0;((y_posHeight) && (!File_error));y_pos++) + for (x_pos=0;((x_posWidth) && (!File_error));x_pos++) if ((x_pos & 1)==0) { if(Read_byte(file,&last_byte)!=1) File_error = 2; - Pixel_load_function(x_pos,y_pos,(last_byte >> 4)); + Set_pixel(context, x_pos,y_pos,(last_byte >> 4)); } else - Pixel_load_function(x_pos,y_pos,(last_byte & 15)); + Set_pixel(context, x_pos,y_pos,(last_byte & 15)); /*Close_lecture();*/ } } @@ -803,11 +803,11 @@ void Load_CEL(void) { // Chargement d'un fichier CEL avec signature (nouveaux fichiers) - Main_image_width=header2.Width+header2.X_offset; - Main_image_height=header2.Height+header2.Y_offset; - Original_screen_X=Main_image_width; - Original_screen_Y=Main_image_height; - Init_preview(Main_image_width,Main_image_height,file_size,FORMAT_CEL,PIXEL_SIMPLE); + context->Width=header2.Width+header2.X_offset; + context->Height=header2.Height+header2.Y_offset; + Original_screen_X=context->Width; + Original_screen_Y=context->Height; + Pre_load(context, context->Width,context->Height,file_size,FORMAT_CEL,PIXEL_SIMPLE,0); if (File_error==0) { // Chargement de l'image @@ -817,11 +817,11 @@ void Load_CEL(void) { // Effacement du décalage for (y_pos=0;y_posWidth;x_pos++) + Set_pixel(context, x_pos,y_pos,0); + for (y_pos=header2.Y_offset;y_posHeight;y_pos++) for (x_pos=0;x_pos> 4)); + Set_pixel(context, x_pos+header2.X_offset,y_pos+header2.Y_offset,(last_byte >> 4)); } else - Pixel_load_function(x_pos+header2.X_offset,y_pos+header2.Y_offset,(last_byte & 15)); + Set_pixel(context, x_pos+header2.X_offset,y_pos+header2.Y_offset,(last_byte & 15)); break; case 8: @@ -843,7 +843,7 @@ void Load_CEL(void) { byte byte_read; if(Read_byte(file,&byte_read)!=1) File_error = 2; - Pixel_load_function(x_pos+header2.X_offset,y_pos+header2.Y_offset,byte_read); + Set_pixel(context, x_pos+header2.X_offset,y_pos+header2.Y_offset,byte_read); } break; @@ -869,7 +869,7 @@ void Load_CEL(void) // -- Ecrire un fichier au format CEL --------------------------------------- -void Save_CEL(void) +void Save_CEL(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -885,7 +885,7 @@ void Save_CEL(void) Count_used_colors(Utilisation); File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((file=fopen(filename,"wb"))) { // On regarde si des couleurs >16 sont utilisées dans l'image @@ -895,8 +895,8 @@ void Save_CEL(void) { // Cas d'une image 16 couleurs (écriture à l'ancien format) - header1.Width =Main_image_width; - header1.Height=Main_image_height; + header1.Width =context->Width; + header1.Height=context->Height; if (Write_word_le(file,header1.Width) && Write_word_le(file,header1.Height) @@ -904,14 +904,14 @@ void Save_CEL(void) { // Sauvegarde de l'image Init_write_buffer(); - for (y_pos=0;((y_posHeight) && (!File_error));y_pos++) { - for (x_pos=0;((x_posWidth) && (!File_error));x_pos++) if ((x_pos & 1)==0) - last_byte=(Read_pixel_function(x_pos,y_pos) << 4); + last_byte=(Get_pixel(context, x_pos,y_pos) << 4); else { - last_byte=last_byte | (Read_pixel_function(x_pos,y_pos) & 15); + last_byte=last_byte | (Get_pixel(context, x_pos,y_pos) & 15); Write_one_byte(file,last_byte); } @@ -929,21 +929,21 @@ void Save_CEL(void) // Cas d'une image 256 couleurs (écriture au nouveau format) // Recherche du décalage - for (y_pos=0;y_posHeight;y_pos++) { - for (x_pos=0;x_posWidth;x_pos++) + if (Get_pixel(context, x_pos,y_pos)!=0) break; - if (Read_pixel_function(x_pos,y_pos)!=0) + if (Get_pixel(context, x_pos,y_pos)!=0) break; } header2.Y_offset=y_pos; - for (x_pos=0;x_posWidth;x_pos++) { - for (y_pos=0;y_posHeight;y_pos++) + if (Get_pixel(context, x_pos,y_pos)!=0) break; - if (Read_pixel_function(x_pos,y_pos)!=0) + if (Get_pixel(context, x_pos,y_pos)!=0) break; } header2.X_offset=x_pos; @@ -952,8 +952,8 @@ void Save_CEL(void) header2.Kind=0x20; // Initialisation du type (BitMaP) header2.Nb_bits=8; // Initialisation du nombre de bits header2.Filler1=0; // Initialisation du filler 1 (?) - header2.Width=Main_image_width-header2.X_offset; // Initialisation de la largeur - header2.Height=Main_image_height-header2.Y_offset; // Initialisation de la hauteur + header2.Width=context->Width-header2.X_offset; // Initialisation de la largeur + header2.Height=context->Height-header2.Y_offset; // Initialisation de la hauteur for (x_pos=0;x_pos<16;x_pos++) // Initialisation du filler 2 (?) header2.Filler2[x_pos]=0; @@ -972,7 +972,7 @@ void Save_CEL(void) Init_write_buffer(); for (y_pos=0;((y_posFile_name, context->File_directory); if ((file=fopen(filename, "rb"))) { if (File_length_file(file)==sizeof(T_KCF_Header)) @@ -1060,7 +1060,7 @@ void Test_KCF(void) // -- Lire un fichier au format KCF ----------------------------------------- -void Load_KCF(void) +void Load_KCF(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -1074,7 +1074,7 @@ void Load_KCF(void) File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((file=fopen(filename, "rb"))) { file_size=File_length_file(file); @@ -1084,30 +1084,30 @@ void Load_KCF(void) if (Read_bytes(file,&buffer,sizeof(T_KCF_Header))) { - // Init_preview(?); // Pas possible... pas d'image... + // Pre_load(context, ?); // Pas possible... pas d'image... if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); // Chargement de la palette for (pal_index=0;pal_index<10;pal_index++) for (color_index=0;color_index<16;color_index++) { index=16+(pal_index*16)+color_index; - Main_palette[index].R=((buffer.Palette[pal_index].color[color_index].Byte1 >> 4) << 4); - Main_palette[index].B=((buffer.Palette[pal_index].color[color_index].Byte1 & 15) << 4); - Main_palette[index].G=((buffer.Palette[pal_index].color[color_index].Byte2 & 15) << 4); + context->Palette[index].R=((buffer.Palette[pal_index].color[color_index].Byte1 >> 4) << 4); + context->Palette[index].B=((buffer.Palette[pal_index].color[color_index].Byte1 & 15) << 4); + context->Palette[index].G=((buffer.Palette[pal_index].color[color_index].Byte2 & 15) << 4); } for (index=0;index<16;index++) { - Main_palette[index].R=Main_palette[index+16].R; - Main_palette[index].G=Main_palette[index+16].G; - Main_palette[index].B=Main_palette[index+16].B; + context->Palette[index].R=context->Palette[index+16].R; + context->Palette[index].G=context->Palette[index+16].G; + context->Palette[index].B=context->Palette[index+16].B; } - Set_palette(Main_palette); - Remap_fileselector(); + Set_palette(context->Palette); + Remap_fileselector(context); } else File_error=1; @@ -1127,7 +1127,7 @@ void Load_KCF(void) && Read_bytes(file,header2.Filler2,sizeof(header2.Filler2)) ) { - // Init_preview(?); // Pas possible... pas d'image... + // Pre_load(context, ?); // Pas possible... pas d'image... index=(header2.Nb_bits==12)?16:0; for (pal_index=0;pal_index> 4) << 4; - Main_palette[index].B=(bytes[0] & 15) << 4; - Main_palette[index].G=(bytes[1] & 15) << 4; + context->Palette[index].R=(bytes[0] >> 4) << 4; + context->Palette[index].B=(bytes[0] & 15) << 4; + context->Palette[index].G=(bytes[1] & 15) << 4; break; case 24: // RRRR RRRR | VVVV VVVV | BBBB BBBB Read_bytes(file,bytes,3); - Main_palette[index].R=bytes[0]; - Main_palette[index].G=bytes[1]; - Main_palette[index].B=bytes[2]; + context->Palette[index].R=bytes[0]; + context->Palette[index].G=bytes[1]; + context->Palette[index].B=bytes[2]; } index++; @@ -1161,13 +1161,13 @@ void Load_KCF(void) if (header2.Nb_bits==12) for (index=0;index<16;index++) { - Main_palette[index].R=Main_palette[index+16].R; - Main_palette[index].G=Main_palette[index+16].G; - Main_palette[index].B=Main_palette[index+16].B; + context->Palette[index].R=context->Palette[index+16].R; + context->Palette[index].G=context->Palette[index+16].G; + context->Palette[index].B=context->Palette[index+16].B; } - Set_palette(Main_palette); - Remap_fileselector(); + Set_palette(context->Palette); + Remap_fileselector(context); } else File_error=1; @@ -1177,13 +1177,13 @@ void Load_KCF(void) else File_error=1; - if (!File_error) Draw_palette_preview(); + if (!File_error) Draw_palette_preview(context); } // -- Ecrire un fichier au format KCF --------------------------------------- -void Save_KCF(void) +void Save_KCF(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; FILE *file; @@ -1199,7 +1199,7 @@ void Save_KCF(void) Count_used_colors(Utilisation); File_error=0; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if ((file=fopen(filename,"wb"))) { // Sauvegarde de la palette @@ -1215,8 +1215,8 @@ void Save_KCF(void) for (color_index=0;color_index<16;color_index++) { index=16+(pal_index*16)+color_index; - buffer.Palette[pal_index].color[color_index].Byte1=((Main_palette[index].R>>4)<<4) | (Main_palette[index].B>>4); - buffer.Palette[pal_index].color[color_index].Byte2=Main_palette[index].G>>4; + buffer.Palette[pal_index].color[color_index].Byte1=((context->Palette[index].R>>4)<<4) | (context->Palette[index].B>>4); + buffer.Palette[pal_index].color[color_index].Byte2=context->Palette[index].G>>4; } if (! Write_bytes(file,&buffer,sizeof(T_KCF_Header))) @@ -1251,9 +1251,9 @@ void Save_KCF(void) for (index=0;(index<256) && (!File_error);index++) { - bytes[0]=Main_palette[index].R; - bytes[1]=Main_palette[index].G; - bytes[2]=Main_palette[index].B; + bytes[0]=context->Palette[index].R; + bytes[1]=context->Palette[index].G; + bytes[2]=context->Palette[index].B; if (! Write_bytes(file,bytes,3)) File_error=1; } @@ -1383,7 +1383,7 @@ void PI1_code_palette(byte * palette,byte * dest) // -- Tester si un fichier est au format PI1 -------------------------------- -void Test_PI1(void) +void Test_PI1(T_IO_Context * context) { FILE * file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -1391,7 +1391,7 @@ void Test_PI1(void) word resolution; // Résolution de l'image - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -1416,7 +1416,7 @@ void Test_PI1(void) // -- Lire un fichier au format PI1 ----------------------------------------- -void Load_PI1(void) +void Load_PI1(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -1425,7 +1425,7 @@ void Load_PI1(void) byte * ptr; byte pixels[320]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; if ((file=fopen(filename, "rb"))) @@ -1438,18 +1438,18 @@ void Load_PI1(void) if (Read_bytes(file,buffer,32034)) { // Initialisation de la preview - Init_preview(320,200,File_length_file(file),FORMAT_PI1,PIXEL_SIMPLE); + Pre_load(context, 320,200,File_length_file(file),FORMAT_PI1,PIXEL_SIMPLE,0); if (File_error==0) { // Initialisation de la palette if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); - PI1_decode_palette(buffer+2,(byte *)Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); + memset(context->Palette,0,sizeof(T_Palette)); + PI1_decode_palette(buffer+2,(byte *)context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); - Main_image_width=320; - Main_image_height=200; + context->Width=320; + context->Height=200; // Chargement/décompression de l'image ptr=buffer+34; @@ -1461,7 +1461,7 @@ void Load_PI1(void) ptr+=8; } for (x_pos=0;x_pos<320;x_pos++) - Pixel_load_function(x_pos,y_pos,pixels[x_pos]); + Set_pixel(context, x_pos,y_pos,pixels[x_pos]); } } } @@ -1479,7 +1479,7 @@ void Load_PI1(void) // -- Sauver un fichier au format PI1 --------------------------------------- -void Save_PI1(void) +void Save_PI1(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -1488,7 +1488,7 @@ void Save_PI1(void) byte * ptr; byte pixels[320]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; // Ouverture du fichier @@ -1500,17 +1500,17 @@ void Save_PI1(void) buffer[0]=0x00; buffer[1]=0x00; // Codage de la palette - PI1_code_palette((byte *)Main_palette,buffer+2); + PI1_code_palette((byte *)context->Palette,buffer+2); // Codage de l'image ptr=buffer+34; for (y_pos=0;y_pos<200;y_pos++) { // Codage de la ligne memset(pixels,0,320); - if (y_posHeight) { - for (x_pos=0;(x_pos<320) && (x_posWidth);x_pos++) + pixels[x_pos]=Get_pixel(context, x_pos,y_pos); } for (x_pos=0;x_pos<(320>>4);x_pos++) @@ -1705,7 +1705,7 @@ void PC1_1line_to_4bp(byte * src,byte * dst0,byte * dst1,byte * dst2,byte * dst3 // -- Tester si un fichier est au format PC1 -------------------------------- -void Test_PC1(void) +void Test_PC1(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -1713,7 +1713,7 @@ void Test_PC1(void) word resolution; // Résolution de l'image - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -1738,7 +1738,7 @@ void Test_PC1(void) // -- Lire un fichier au format PC1 ----------------------------------------- -void Load_PC1(void) +void Load_PC1(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -1749,7 +1749,7 @@ void Load_PC1(void) byte * ptr; byte pixels[320]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; if ((file=fopen(filename, "rb"))) @@ -1764,18 +1764,18 @@ void Load_PC1(void) if (Read_bytes(file,buffercomp,size)) { // Initialisation de la preview - Init_preview(320,200,File_length_file(file),FORMAT_PC1,PIXEL_SIMPLE); + Pre_load(context, 320,200,File_length_file(file),FORMAT_PC1,PIXEL_SIMPLE,0); if (File_error==0) { // Initialisation de la palette if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); - PI1_decode_palette(buffercomp+2,(byte *)Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); + memset(context->Palette,0,sizeof(T_Palette)); + PI1_decode_palette(buffercomp+2,(byte *)context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); - Main_image_width=320; - Main_image_height=200; + context->Width=320; + context->Height=200; // Décompression du buffer PC1_uncompress_packbits(buffercomp+34,bufferdecomp); @@ -1789,7 +1789,7 @@ void Load_PC1(void) ptr+=160; // Chargement de la ligne for (x_pos=0;x_pos<320;x_pos++) - Pixel_load_function(x_pos,y_pos,pixels[x_pos]); + Set_pixel(context, x_pos,y_pos,pixels[x_pos]); } } } @@ -1812,7 +1812,7 @@ void Load_PC1(void) // -- Sauver un fichier au format PC1 --------------------------------------- -void Save_PC1(void) +void Save_PC1(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -1823,7 +1823,7 @@ void Save_PC1(void) byte * ptr; byte pixels[320]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; // Ouverture du fichier @@ -1836,17 +1836,17 @@ void Save_PC1(void) buffercomp[0]=0x80; buffercomp[1]=0x00; // Codage de la palette - PI1_code_palette((byte *)Main_palette,buffercomp+2); + PI1_code_palette((byte *)context->Palette,buffercomp+2); // Codage de l'image ptr=bufferdecomp; for (y_pos=0;y_pos<200;y_pos++) { // Codage de la ligne memset(pixels,0,320); - if (y_posHeight) { - for (x_pos=0;(x_pos<320) && (x_posWidth);x_pos++) + pixels[x_pos]=Get_pixel(context, x_pos,y_pos); } // Encodage de la scanline @@ -1885,7 +1885,7 @@ void Save_PC1(void) //////////////////////////////////// NEO //////////////////////////////////// -void Test_NEO(void) +void Test_NEO(T_IO_Context * context) { FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier @@ -1893,7 +1893,7 @@ void Test_NEO(void) word resolution; // Résolution de l'image - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=1; @@ -1924,7 +1924,7 @@ void Test_NEO(void) } -void Load_NEO(void) +void Load_NEO(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -1933,7 +1933,7 @@ void Load_NEO(void) byte * ptr; byte pixels[320]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; if ((file=fopen(filename, "rb"))) @@ -1946,19 +1946,19 @@ void Load_NEO(void) if (Read_bytes(file,buffer,32128)) { // Initialisation de la preview - Init_preview(320,200,File_length_file(file),FORMAT_NEO,PIXEL_SIMPLE); + Pre_load(context, 320,200,File_length_file(file),FORMAT_NEO,PIXEL_SIMPLE,0); if (File_error==0) { // Initialisation de la palette if (Config.Clear_palette) - memset(Main_palette,0,sizeof(T_Palette)); + memset(context->Palette,0,sizeof(T_Palette)); // on saute la résolution et le flag, chacun 2 bits - PI1_decode_palette(buffer+4,(byte *)Main_palette); - Set_palette(Main_palette); - Remap_fileselector(); + PI1_decode_palette(buffer+4,(byte *)context->Palette); + Set_palette(context->Palette); + Remap_fileselector(context); - Main_image_width=320; - Main_image_height=200; + context->Width=320; + context->Height=200; // Chargement/décompression de l'image ptr=buffer+128; @@ -1970,7 +1970,7 @@ void Load_NEO(void) ptr+=8; } for (x_pos=0;x_pos<320;x_pos++) - Pixel_load_function(x_pos,y_pos,pixels[x_pos]); + Set_pixel(context, x_pos,y_pos,pixels[x_pos]); } } } @@ -1986,7 +1986,7 @@ void Load_NEO(void) File_error=1; } -void Save_NEO(void) +void Save_NEO(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier FILE *file; @@ -1995,7 +1995,7 @@ void Save_NEO(void) byte * ptr; byte pixels[320]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); File_error=0; // Ouverture du fichier @@ -2009,17 +2009,17 @@ void Save_NEO(void) buffer[2]=0x00; buffer[3]=0x00; // Codage de la palette - PI1_code_palette((byte *)Main_palette,buffer+4); + PI1_code_palette((byte *)context->Palette,buffer+4); // Codage de l'image ptr=buffer+128; for (y_pos=0;y_pos<200;y_pos++) { // Codage de la ligne memset(pixels,0,320); - if (y_posHeight) { - for (x_pos=0;(x_pos<320) && (x_posWidth);x_pos++) + pixels[x_pos]=Get_pixel(context, x_pos,y_pos); } for (x_pos=0;x_pos<(320>>4);x_pos++) @@ -2051,13 +2051,13 @@ void Save_NEO(void) } //////////////////////////////////// C64 //////////////////////////////////// -void Test_C64(void) +void Test_C64(T_IO_Context * context) { FILE* file; char filename[MAX_PATH_CHARACTERS]; long file_size; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); file = fopen(filename,"rb"); @@ -2087,7 +2087,7 @@ void Test_C64(void) } } -void Load_C64_hires(byte *bitmap, byte *colors) +void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors) { int cx,cy,x,y,c[4],pixel,color; @@ -2103,14 +2103,14 @@ void Load_C64_hires(byte *bitmap, byte *colors) for(x=0; x<8; x++) { color=c[pixel&(1<<(7-x))?1:0]; - Pixel_load_function(cx*8+x,cy*8+y,color); + Set_pixel(context, cx*8+x,cy*8+y,color); } } } } } -void Load_C64_multi(byte *bitmap, byte *colors, byte *nybble, byte background) +void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nybble, byte background) { int cx,cy,x,y,c[4],pixel,color; c[0]=background; @@ -2129,14 +2129,14 @@ void Load_C64_multi(byte *bitmap, byte *colors, byte *nybble, byte background) { color=c[(pixel&3)]; pixel>>=2; - Pixel_load_function(cx*4+(3-x),cy*8+y,color); + Set_pixel(context, cx*4+(3-x),cy*8+y,color); } } } } } -void Load_C64(void) +void Load_C64(T_IO_Context * context) { FILE* file; char filename[MAX_PATH_CHARACTERS]; @@ -2169,7 +2169,7 @@ void Load_C64(void) byte bitmap[8000],colors[1000],nybble[1000]; word width=320, height=200; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); file = fopen(filename,"rb"); if (file) @@ -2223,9 +2223,9 @@ void Load_C64(void) } - memcpy(Main_palette,pal,48); // this set the software palette for grafx2 - Set_palette(Main_palette); // this set the hardware palette for SDL - Remap_fileselector(); // Always call it if you change the palette + memcpy(context->Palette,pal,48); // this set the software palette for grafx2 + Set_palette(context->Palette); // this set the hardware palette for SDL + Remap_fileselector(context); // Always call it if you change the palette if (file_size>9002) width=160; @@ -2244,14 +2244,14 @@ void Load_C64(void) if(file_size>9002) { - Ratio_of_loaded_image = PIXEL_WIDE; + context->Ratio = PIXEL_WIDE; } - sprintf(Main_comment,"C64 %s, %s", + sprintf(context->Comment,"C64 %s, %s", c64_format_names[loadFormat],filename); - Init_preview(width, height, file_size, FORMAT_C64, Ratio_of_loaded_image); // Do this as soon as you can + Pre_load(context, width, height, file_size, FORMAT_C64, context->Ratio,0); // Do this as soon as you can - Main_image_width = width ; - Main_image_height = height; + context->Width = width ; + context->Height = height; Read_bytes(file,bitmap,8000); @@ -2269,11 +2269,11 @@ void Load_C64(void) { Read_bytes(file,nybble,1000); Read_byte(file,&background); - Load_C64_multi(bitmap,colors,nybble,background); + Load_C64_multi(context,bitmap,colors,nybble,background); } else { - Load_C64_hires(bitmap,colors); + Load_C64_hires(context,bitmap,colors); } File_error = 0; @@ -2348,7 +2348,7 @@ int Save_C64_window(byte *saveWhat, byte *loadAddr) return button==1; } -int Save_C64_hires(char *filename, byte saveWhat, byte loadAddr) +int Save_C64_hires(T_IO_Context *context, char *filename, byte saveWhat, byte loadAddr) { int cx,cy,x,y,c1,c2=0,i,pixel,bits,pos=0; word numcolors; @@ -2396,7 +2396,7 @@ int Save_C64_hires(char *filename, byte saveWhat, byte loadAddr) bits=0; for(x=0; x<8; x++) { - pixel=Read_pixel_function(x+cx*8,y+cy*8); + pixel=Get_pixel(context, x+cx*8,y+cy*8); if(pixel>15) { Warning_message("Color above 15 used"); @@ -2437,7 +2437,7 @@ int Save_C64_hires(char *filename, byte saveWhat, byte loadAddr) return 0; } -int Save_C64_multi(char *filename, byte saveWhat, byte loadAddr) +int Save_C64_multi(T_IO_Context *context, char *filename, byte saveWhat, byte loadAddr) { /* BITS COLOR INFORMATION COMES FROM @@ -2507,7 +2507,7 @@ int Save_C64_multi(char *filename, byte saveWhat, byte loadAddr) bits=0; for(x=0;x<4;x++) { - pixel=Read_pixel_function(cx*4+x,cy*8+y); + pixel=Get_pixel(context, cx*4+x,cy*8+y); if(pixel>15) { Warning_message("Color above 15 used"); @@ -2557,14 +2557,14 @@ int Save_C64_multi(char *filename, byte saveWhat, byte loadAddr) return 0; } -void Save_C64(void) +void Save_C64(T_IO_Context * context) { char filename[MAX_PATH_CHARACTERS]; static byte saveWhat=0, loadAddr=0; dword numcolors,cusage[256]; numcolors=Count_used_colors(cusage); - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); if (numcolors>16) { @@ -2572,7 +2572,7 @@ void Save_C64(void) File_error = 1; return; } - if (((Main_image_width!=320) && (Main_image_width!=160)) || Main_image_height!=200) + if (((context->Width!=320) && (context->Width!=160)) || context->Height!=200) { Warning_message("must be 320x200 or 160x200"); File_error = 1; @@ -2586,16 +2586,16 @@ void Save_C64(void) } //printf("saveWhat=%d, loadAddr=%d\n",saveWhat,loadAddr); - if (Main_image_width==320) - File_error = Save_C64_hires(filename,saveWhat,loadAddr); + if (context->Width==320) + File_error = Save_C64_hires(context,filename,saveWhat,loadAddr); else - File_error = Save_C64_multi(filename,saveWhat,loadAddr); + File_error = Save_C64_multi(context,filename,saveWhat,loadAddr); } // SCR (Amstrad CPC) -void Test_SCR(void) +void Test_SCR(__attribute__((unused)) T_IO_Context * context) { // Mmh... not sure what we could test. Any idea ? // The palette file can be tested, if it exists and have the right size it's @@ -2606,7 +2606,7 @@ void Test_SCR(void) // be there } -void Load_SCR(void) +void Load_SCR(__attribute__((unused)) T_IO_Context * context) { // The Amstrad CPC screen memory is mapped in a weird mode, somewhere // between bitmap and textmode. Basically the only way to decode this is to @@ -2637,7 +2637,7 @@ void Load_SCR(void) // 8) Close the file } -void Save_SCR(void) +void Save_SCR(T_IO_Context * context) { // TODO : Add possibility to set R9, R12, R13 values // TODO : Add OCP packing support @@ -2651,7 +2651,7 @@ void Save_SCR(void) FILE* file; char filename[MAX_PATH_CHARACTERS]; - Get_full_filename(filename,0); + Get_full_filename(filename, context->File_name, context->File_directory); switch(Pixel_ratio) @@ -2669,7 +2669,7 @@ void Save_SCR(void) break; } - output = raw2crtc(Main_image_width,Main_image_height,cpc_mode,7,&outsize,&r1,0,0); + output = raw2crtc(context->Width,context->Height,cpc_mode,7,&outsize,&r1,0,0); file = fopen(filename,"wb"); Write_bytes(file, output, outsize); diff --git a/pages.c b/pages.c index e22d7232..a55e77fb 100644 --- a/pages.c +++ b/pages.c @@ -153,8 +153,6 @@ void Download_infos_page_main(T_Page * page) Main_image_height=page->Height; memcpy(Main_palette,page->Palette,sizeof(T_Palette)); strcpy(Main_comment,page->Comment); - strcpy(Main_file_directory,page->File_directory); - strcpy(Main_filename,page->Filename); Main_fileformat=page->File_format; if (size_is_modified) @@ -302,8 +300,6 @@ void Upload_infos_page_main(T_Page * page) page->Height=Main_image_height; memcpy(page->Palette,Main_palette,sizeof(T_Palette)); strcpy(page->Comment,Main_comment); - strcpy(page->File_directory,Main_file_directory); - strcpy(page->Filename,Main_filename); page->File_format=Main_fileformat; } } @@ -316,9 +312,6 @@ void Download_infos_page_spare(T_Page * page) Spare_image_width=page->Width; Spare_image_height=page->Height; 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; } } @@ -331,9 +324,6 @@ void Upload_infos_page_spare(T_Page * page) page->Width=Spare_image_width; page->Height=Spare_image_height; 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; } } @@ -659,6 +649,10 @@ int Init_all_backup_lists(int width,int height) // On y met les infos sur la dimension de démarrage Main_backups->Pages->Width=width; 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; iPages->Nb_layers; i++) { 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; memcpy(Spare_backups->Pages->Palette,Main_palette,sizeof(T_Palette)); strcpy(Spare_backups->Pages->Comment,""); - strcpy(Spare_backups->Pages->File_directory,Spare_current_directory); - strcpy(Spare_backups->Pages->Filename,"NO_NAME.GIF"); + strcpy(Spare_backups->Pages->File_directory,Main_current_directory); + strcpy(Spare_backups->Pages->Filename,"NO_NAME2.GIF"); Spare_backups->Pages->File_format=DEFAULT_FILEFORMAT; // Copy this informations in the global Spare_ variables 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); new_page->Width=width; 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)) { for (i=0; iPages); - 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; } @@ -1001,6 +1007,11 @@ void End_of_modification(void) Last_backed_up_layers = 0; 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. diff --git a/windows.c b/windows.c index ed5b1804..850e91ce 100644 --- a/windows.c +++ b/windows.c @@ -741,10 +741,10 @@ void Print_filename(void) // Determine maximum size, in characters 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 - strncpy(display_string, Main_filename, max_size); + strncpy(display_string, Main_backups->Pages->Filename, max_size); display_string[max_size]='\0'; if (string_size > max_size)