diff --git a/buttons.c b/buttons.c index 10882e5b..82854e33 100644 --- a/buttons.c +++ b/buttons.c @@ -2764,7 +2764,7 @@ void Load_picture(byte image) { // Si c'est une image qu'on charge, on efface l'ancien commentaire // C'est loin d'être indispensable, m'enfin bon... - if (File_formats[Main_fileformat-1].Backup_done) + if (Get_fileformat(Main_fileformat)->Backup_done) Main_comment[0]='\0'; Original_screen_X=0; @@ -2828,7 +2828,7 @@ void Load_picture(byte image) Cursor_shape=old_cursor_shape; } - if ( (File_error==1) || (!File_formats[Main_fileformat-1].Backup_done) ) + if ( (File_error==1) || (!Get_fileformat(Main_fileformat)->Backup_done) ) { do_not_restore=0; if (File_error!=1) @@ -3097,7 +3097,7 @@ void Save_picture(byte image) Hide_cursor(); Cursor_shape=old_cursor_shape; - if ((File_error==1) || (!File_formats[Main_fileformat-1].Backup_done)) + if ((File_error==1) || (!Get_fileformat(Main_fileformat)->Backup_done)) do_not_restore=0; Display_cursor(); diff --git a/const.h b/const.h index 9d8afc2d..d61583f9 100644 --- a/const.h +++ b/const.h @@ -92,38 +92,26 @@ #define PARENT_DIR ".." #endif -// -- File formats - -#ifndef __no_pnglib__ -#define NB_KNOWN_FORMATS 15 ///< Total number of known file formats. -#define NB_FORMATS_LOAD 15 ///< Number of file formats that grafx2 can load. -#define NB_FORMATS_SAVE 15 ///< Number of file formats that grafx2 can save. -#else -// Without pnglib -#define NB_KNOWN_FORMATS 14 ///< Total number of known file formats. -#define NB_FORMATS_LOAD 14 ///< Number of file formats that grafx2 can load. -#define NB_FORMATS_SAVE 14 ///< Number of file formats that grafx2 can save. -#endif - /// List of file formats recognized by grafx2 enum FILE_FORMATS { - FORMAT_ANY=0, ///< This is not really a file format, it's reserverd for the "*.*" filter option. - FORMAT_PKM=1, - FORMAT_LBM, + FORMAT_ALL_IMAGES=0, ///< This is not really a file format, it's reserverd for a compilation of all file extensions + FORMAT_ALL_FILES=1, ///< This is not really a file format, it's reserverd for the "*.*" filter option. + FORMAT_PNG, FORMAT_GIF, FORMAT_BMP, FORMAT_PCX, + FORMAT_PKM, + FORMAT_LBM, FORMAT_IMG, FORMAT_SCx, FORMAT_PI1, FORMAT_PC1, FORMAT_CEL, FORMAT_NEO, + FORMAT_C64, FORMAT_KCF, FORMAT_PAL, - FORMAT_C64, - FORMAT_PNG }; /// Default format for 'save as' diff --git a/filesel.c b/filesel.c index 4f2ed269..74dd7d33 100644 --- a/filesel.c +++ b/filesel.c @@ -210,13 +210,15 @@ void Add_element_to_list(T_Fileselector *list, const char * fname, int type) list->First=temp_item; } -// -- Vérification si un fichier a l'extension demandée. -// Autorise les '?', et '*' si c'est le seul caractère. -int Check_extension(const char *filename, char * filter) +/// +/// Checks if a file has the requested file extension. +/// The extension string can end with a ';' (remainder is ignored) +/// This function allows wildcard '?', and '*' if it's the only character. +int Check_extension(const char *filename, const char * filter) { int pos_last_dot = -1; int c = 0; - + if (filter[0] == '*') return 1; // On recherche la position du dernier . dans le nom @@ -225,20 +227,21 @@ int Check_extension(const char *filename, char * filter) pos_last_dot = c; // Fichier sans extension (ca arrive) if (pos_last_dot == -1) - return (filter[0] == '\0'); + return (filter[0] == '\0' || filter[0] == ';'); // Vérification caractère par caractère, case-insensitive. c = 0; - do + while (1) { + if (filter[c] == '\0' || filter[c] == ';') + return filename[pos_last_dot + 1 + c] == '\0'; + if (filter[c] != '?' && tolower(filter[c]) != tolower(filename[pos_last_dot + 1 + c])) return 0; c++; - } while (filter[c++] != '\0'); - - return 1; + } } @@ -254,8 +257,7 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format) char * current_path; // Tout d'abord, on déduit du format demandé un filtre à utiliser: - if (selected_format) // Format (extension) spécifique - filter = File_formats[selected_format-1].Extension; + filter = Get_fileformat(selected_format)->Extensions; // Ensuite, on vide la liste actuelle: Free_fileselector_list(list); @@ -288,11 +290,23 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format) (Config.Show_hidden_files || //Il n'est pas caché !isHidden(entry))) { - if (Check_extension(entry->d_name, filter)) - { - // On rajoute le fichier à la liste - Add_element_to_list(list, entry->d_name, 0); - list->Nb_files++; + const char * ext = filter; + while (ext!=NULL) + { + if (Check_extension(entry->d_name, ext)) + { + // On rajoute le fichier à la liste + Add_element_to_list(list, entry->d_name, 0); + list->Nb_files++; + // Stop searching + ext=NULL; + } + else + { + ext = strchr(ext, ';'); + if (ext) + ext++; + } } } } @@ -1061,21 +1075,21 @@ byte Button_Load_or_Save(byte load, byte image) else Open_window(310,200,"Save brush"); Window_set_normal_button(198,180,51,14,"Save",0,1,SDLK_RETURN); // 1 - if (Main_format==FORMAT_ANY) // Correction du *.* + if (Main_format<=FORMAT_ALL_FILES) // Correction du *.* { Main_format=Main_fileformat; Main_fileselector_position=0; Main_fileselector_offset=0; } - if (Main_format>NB_FORMATS_SAVE) // Correction d'un format insauvable + if (Get_fileformat(Main_format)->Save == NULL) // Correction d'un format insauvable { Main_format=DEFAULT_FILEFORMAT; Main_fileselector_position=0; Main_fileselector_offset=0; } // Affichage du commentaire - if (File_formats[Main_format-1].Comment) + if (Get_fileformat(Main_format)->Comment) Print_in_window(47,70,Main_comment,MC_Black,MC_Light); } @@ -1097,16 +1111,15 @@ byte Button_Load_or_Save(byte load, byte image) // Dropdown pour les formats de fichier formats_dropdown= - Window_set_dropdown_button(69,28,49,11,0, - (Main_format==FORMAT_ANY)?"*.*":File_formats[Main_format-1].Extension, + Window_set_dropdown_button(68,28,52,11,0, + Get_fileformat(Main_format)->Label, 1,0,1,RIGHT_SIDE|LEFT_SIDE); // 6 - if (load) - Window_dropdown_add_item(formats_dropdown,0,"*.*"); - for (temp=0;tempComment) ) { Readline(45,70,Main_comment,32,0); Display_cursor(); @@ -1353,12 +1366,12 @@ byte Button_Load_or_Save(byte load, byte image) dummy=1; if (!dummy) { - if (Main_format != FORMAT_ANY) + if (Get_fileformat(Main_format)->Default_extension) { if(!Directory_exists(Main_filename)) { - strcat(Main_filename,"."); - strcat(Main_filename,File_formats[Main_format-1].Extension); + strcat(Main_filename, "."); + strcat(Main_filename,Get_fileformat(Main_format)->Default_extension); } } else @@ -1658,9 +1671,9 @@ byte Button_Load_or_Save(byte load, byte image) // On efface la taille du fichier Window_rectangle(236,59,56,8,MC_Light); // On efface le format du fichier - Window_rectangle(59,59,3*8,8,MC_Light); + Window_rectangle(59,59,5*8,8,MC_Light); // Affichage du commentaire - if ( (!load) && (File_formats[Main_format-1].Comment) ) + if ( (!load) && (Get_fileformat(Main_format)->Comment) ) { Print_in_window(45,70,Main_comment,MC_Black,MC_Light); } diff --git a/loadsave.c b/loadsave.c index 81083f5f..96aaa279 100644 --- a/loadsave.c +++ b/loadsave.c @@ -126,23 +126,25 @@ void Save_PNG(void); void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio); T_Format File_formats[NB_KNOWN_FORMATS] = { - {"pkm", Test_PKM, Load_PKM, Save_PKM, 1, 1}, - {"lbm", Test_LBM, Load_LBM, Save_LBM, 1, 0}, - {"gif", Test_GIF, Load_GIF, Save_GIF, 1, 1}, - {"bmp", Test_BMP, Load_BMP, Save_BMP, 1, 0}, - {"pcx", Test_PCX, Load_PCX, Save_PCX, 1, 0}, - {"img", Test_IMG, Load_IMG, Save_IMG, 1, 0}, - {"sc?", Test_SCx, Load_SCx, Save_SCx, 1, 0}, - {"pi1", Test_PI1, Load_PI1, Save_PI1, 1, 0}, - {"pc1", Test_PC1, Load_PC1, Save_PC1, 1, 0}, - {"cel", Test_CEL, Load_CEL, Save_CEL, 1, 0}, - {"neo", Test_NEO, Load_NEO, Save_NEO, 1, 0}, - {"kcf", Test_KCF, Load_KCF, Save_KCF, 0, 0}, - {"pal", Test_PAL, Load_PAL, Save_PAL, 0, 0}, - {"c64", Test_C64, Load_C64, Save_C64, 1, 1}, + {FORMAT_ALL_IMAGES, "(all)", NULL, NULL, NULL, 0, 0, "", "gif;png;bmp;pcx;pkm;lbm;iff;img;sci;scq;scf;scn;sco;pi1;pc1;cel;neo;kcf;pal;c64;koa"}, + {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, "", "*"}, + {FORMAT_GIF, " gif", Test_GIF, Load_GIF, Save_GIF, 1, 1, "gif", "gif"}, #ifndef __no_pnglib__ - {"png", Test_PNG, Load_PNG, Save_PNG, 1, 1} + {FORMAT_PNG, " png", Test_PNG, Load_PNG, Save_PNG, 1, 1, "png", "png"}, #endif + {FORMAT_BMP, " bmp", Test_BMP, Load_BMP, Save_BMP, 1, 0, "bmp", "bmp"}, + {FORMAT_PCX, " pcx", Test_PCX, Load_PCX, Save_PCX, 1, 0, "pcx", "pcx"}, + {FORMAT_PKM, " pkm", Test_PKM, Load_PKM, Save_PKM, 1, 1, "pkm", "pkm"}, + {FORMAT_LBM, " lbm", Test_LBM, Load_LBM, Save_LBM, 1, 0, "lbm", "lbm;iff"}, + {FORMAT_IMG, " img", Test_IMG, Load_IMG, Save_IMG, 1, 0, "img", "img"}, + {FORMAT_SCx, " sc?", Test_SCx, Load_SCx, Save_SCx, 1, 0, "sc?", "sci;scq;scf;scn;sco"}, + {FORMAT_PI1, " pi1", Test_PI1, Load_PI1, Save_PI1, 1, 0, "pi1", "pi1"}, + {FORMAT_PC1, " pc1", Test_PC1, Load_PC1, Save_PC1, 1, 0, "pc1", "pc1"}, + {FORMAT_CEL, " cel", Test_CEL, Load_CEL, Save_CEL, 1, 0, "cel", "cel"}, + {FORMAT_NEO, " neo", Test_NEO, Load_NEO, Save_NEO, 1, 0, "neo", "neo"}, + {FORMAT_KCF, " kcf", Test_KCF, Load_KCF, Save_KCF, 0, 0, "kcf", "kcf"}, + {FORMAT_PAL, " pal", Test_PAL, Load_PAL, Save_PAL, 0, 0, "pal", "pal"}, + {FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 1, 1, "c64", "c64;koa"}, }; // Cette variable est alimentée après chargement réussi d'une image. @@ -415,13 +417,13 @@ void Init_preview(short width,short height,long size,int format, enum PIXEL_RATI // Affichage du vrai format if (format!=Main_format) { - Print_in_window( 59,59,File_formats[format-1].Extension,MC_Black,MC_Light); + 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 (File_formats[format-1].Comment) + 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: @@ -604,36 +606,36 @@ void Set_file_error(int value) // -- Charger n'importe connu quel type de fichier d'image (ou palette) ----- void Load_image(byte image) { - int index; // index de balayage des formats - int format=0; // Format du fichier à charger + unsigned int index; // index de balayage des formats + T_Format *format = &(File_formats[2]); // Format du fichier à charger // On place par défaut File_error à vrai au cas où on ne sache pas // charger le format du fichier: File_error=1; - if (Main_format!=0) + if (Main_format>FORMAT_ALL_FILES) { - File_formats[Main_format-1].Test(); - if (!File_error) - // Si dans le sélecteur il y a un format valide on le prend tout de suite - format=Main_format-1; + format = Get_fileformat(Main_format); + format->Test(); } if (File_error) { // Sinon, on va devoir scanner les différents formats qu'on connait pour // savoir à quel format est le fichier: - for (index=0;indexLoad == NULL) + continue; + // On appelle le testeur du format: - File_formats[index].Test(); + format->Test(); // On s'arrête si le fichier est au bon format: if (File_error==0) - { - format=index; break; - } } } @@ -645,7 +647,7 @@ void Load_image(byte image) Ratio_of_loaded_image=PIXEL_SIMPLE; // Dans certains cas il est possible que le chargement plante // après avoir modifié la palette. TODO - File_formats[format].Load(); + format->Load(); if (File_error>0) { @@ -685,7 +687,7 @@ void Load_image(byte image) if (image) { - if ( (File_error!=1) && (File_formats[format].Backup_done) ) + if ( (File_error!=1) && (format->Backup_done) ) { if (Pixel_load_function==Pixel_load_in_preview) { @@ -700,7 +702,7 @@ void Load_image(byte image) // 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+1; + Main_fileformat=format->Identifier; // Correction des dimensions if (Main_image_width<1) @@ -713,7 +715,7 @@ void Load_image(byte image) // On considère que l'image chargée est encore modifiée Main_image_is_modified=1; // Et on documente la variable Main_fileformat avec la valeur: - Main_fileformat=format+1; + Main_fileformat=format->Identifier; } else { @@ -741,13 +743,13 @@ void Save_image(byte image) Read_pixel_function=(image)?Read_pixel_from_current_screen:Read_pixel_from_brush; - File_formats[Main_fileformat-1].Save(); + Get_fileformat(Main_fileformat)->Save(); if (File_error) Error(0); else { - if ((image) && (File_formats[Main_fileformat-1].Backup_done)) + if ((image) && (Get_fileformat(Main_fileformat)->Backup_done)) Main_image_is_modified=0; } } @@ -6899,3 +6901,21 @@ 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); } + +T_Format * Get_fileformat(byte format) +{ + unsigned int i; + T_Format * safe_default = File_formats; + + for (i=0; i < NB_KNOWN_FORMATS; i++) + { + if (File_formats[i].Identifier == format) + return &(File_formats[i]); + + if (File_formats[i].Identifier == FORMAT_GIF) + safe_default=&(File_formats[i]); + } + // Normally impossible to reach this point, unless called with an invalid + // enum.... + return safe_default; +} diff --git a/loadsave.h b/loadsave.h index 93025ae8..df761483 100644 --- a/loadsave.h +++ b/loadsave.h @@ -40,16 +40,19 @@ void Save_image(byte image); /// Data for an image file format. typedef struct { - char *Extension; ///< Three-letter file extension - 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 - byte Backup_done; ///< Boolean, true if this format saves all the image, and considers it backed up. Set false for formats which only save the palette. - byte Comment; ///< This file format allows a text comment + 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 + byte Backup_done; ///< Boolean, true if this format saves all the image, and considers it backed up. Set false for formats which only save the palette. + byte Comment; ///< This file format allows a text comment + char *Default_extension; ///< Default file extension + char *Extensions; ///< List of semicolon-separated file extensions } T_Format; /// Array of the known file formats -extern T_Format File_formats[NB_KNOWN_FORMATS]; +extern T_Format File_formats[]; /// /// Function which attempts to save backups of the images (main and spare), @@ -58,3 +61,15 @@ 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); + +// -- File formats + +#ifndef __no_pnglib__ +#define NB_KNOWN_FORMATS 17 ///< Total number of known file formats. +#else +// Without pnglib +#define NB_KNOWN_FORMATS 16 ///< Total number of known file formats. +#endif + diff --git a/main.c b/main.c index 818cc650..ecb63bb8 100644 --- a/main.c +++ b/main.c @@ -368,13 +368,13 @@ int Init_program(int argc,char * argv[]) Main_fileselector_position=0; // Au début, le fileselect est en haut de la liste des fichiers Main_fileselector_offset=0; // Au début, le fileselect est en haut de la liste des fichiers - Main_format=0; + Main_format=FORMAT_ALL_IMAGES; Spare_fileselector_position=0; Spare_fileselector_offset=0; - Spare_format=0; + Spare_format=FORMAT_ALL_IMAGES; Brush_fileselector_position=0; Brush_fileselector_offset=0; - Brush_format=0; + Brush_format=FORMAT_ALL_IMAGES; // On initialise les commentaires des images à des chaînes vides Main_comment[0]='\0';