From 4e60f5ad7470bbb7ffc718a84845d4d66a87c4b8 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Sun, 13 Feb 2011 21:20:45 +0000 Subject: [PATCH] Import the WIP CPC-Mode5 code from the sourcearchive git-svn-id: svn://pulkomandy.tk/GrafX2/branches/cpcmode5@1718 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/Makefile | 9 +- src/brush.c | 109 ++++++++++- src/buttons_effects.c | 2 +- src/const.h | 4 +- src/engine.c | 4 + src/graph.c | 68 ++++++- src/graph.h | 1 + src/help.c | 6 +- src/helpfile.h | 6 + src/hotkeys.c | 10 + src/loadsave.c | 7 +- src/misc.c | 22 +++ src/misc.h | 3 + src/miscfileformats.c | 435 ++++++++++++++++++++++++++++++++---------- src/oldies.c | 411 +++++++++++++++++++++++++++++++++++++++ src/oldies.h | 24 +++ src/pages.c | 54 ++++-- src/struct.h | 10 +- 18 files changed, 1031 insertions(+), 154 deletions(-) create mode 100644 src/oldies.c create mode 100644 src/oldies.h diff --git a/src/Makefile b/src/Makefile index ee8fe8a0..fb0c92d5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -152,9 +152,8 @@ else RMDIR = rmdir CP = cp BIN = ../bin/grafx2 - PLATFORMOBJ = $(OBJDIR)/haiku.o COPT = -W -Wall -c -g `sdl-config --cflags` $(TTFCOPT) -I/boot/common/include - LOPT = `sdl-config --libs` -lSDL_image -lpng -ljpeg -lz $(TTFLOPT) -lfreetype -lbe + LOPT = `sdl-config --libs` -lSDL_image -lpng -ljpeg -lz $(TTFLOPT) CC = gcc OBJDIR = ../obj/haiku ZIP = zip @@ -303,7 +302,7 @@ endif .PHONY : all debug release clean depend zip version force install uninstall # This is the list of the objects we want to build. Dependancies are built by "make depend" automatically. -OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o +OBJ = $(OBJDIR)/main.o $(OBJDIR)/init.o $(OBJDIR)/graph.o $(OBJDIR)/sdlscreen.o $(OBJDIR)/misc.o $(OBJDIR)/special.o $(OBJDIR)/buttons.o $(OBJDIR)/palette.o $(OBJDIR)/help.o $(OBJDIR)/operatio.o $(OBJDIR)/pages.o $(OBJDIR)/loadsave.o $(OBJDIR)/readline.o $(OBJDIR)/engine.o $(OBJDIR)/filesel.o $(OBJDIR)/op_c.o $(OBJDIR)/readini.o $(OBJDIR)/saveini.o $(OBJDIR)/shade.o $(OBJDIR)/keyboard.o $(OBJDIR)/io.o $(OBJDIR)/version.o $(OBJDIR)/text.o $(OBJDIR)/SFont.o $(OBJDIR)/setup.o $(OBJDIR)/pxsimple.o $(OBJDIR)/pxtall.o $(OBJDIR)/pxwide.o $(OBJDIR)/pxdouble.o $(OBJDIR)/pxtriple.o $(OBJDIR)/pxtall2.o $(OBJDIR)/pxwide2.o $(OBJDIR)/pxquad.o $(OBJDIR)/windows.o $(OBJDIR)/brush.o $(OBJDIR)/realpath.o $(OBJDIR)/mountlist.o $(OBJDIR)/input.o $(OBJDIR)/hotkeys.o $(OBJDIR)/transform.o $(OBJDIR)/pversion.o $(OBJDIR)/factory.o $(PLATFORMOBJ) $(OBJDIR)/fileformats.o $(OBJDIR)/miscfileformats.o $(OBJDIR)/libraw2crtc.o $(OBJDIR)/brush_ops.o $(OBJDIR)/buttons_effects.o $(OBJDIR)/layers.o $(OBJDIR)/oldies.o SKIN_FILES = ../share/grafx2/skins/skin_classic.png ../share/grafx2/skins/skin_modern.png ../share/grafx2/skins/skin_DPaint.png ../share/grafx2/skins/font_Classic.png ../share/grafx2/skins/font_Fun.png ../share/grafx2/skins/font_Fairlight.png ../share/grafx2/skins/font_Melon.png ../share/grafx2/skins/font_DPaint.png ../share/grafx2/skins/skin_scenish.png ../share/grafx2/skins/font_Seen.png @@ -388,10 +387,6 @@ depend : $(OBJDIR)/winres.o : gfx2.ico echo "1 ICON \"gfx2.ico\"" | $(WINDRES) -o $(OBJDIR)/winres.o -# Compile the C++ file needed in Haiku to use the API -$(OBJDIR)/haiku.o : haiku.cpp - g++ -c haiku.cpp -o $(OBJDIR)/haiku.o - clean : $(DELCOMMAND) $(OBJ) $(DELCOMMAND) $(BIN) diff --git a/src/brush.c b/src/brush.c index 63014847..de28b7fd 100644 --- a/src/brush.c +++ b/src/brush.c @@ -125,14 +125,119 @@ void Display_paintbrush(short x,short y,byte color,byte is_preview) byte temp_color; // color de la brosse en cours d'affichage int position; byte * temp; + byte old_color; - if (is_preview==0 || Mouse_K==0) // pas de curseur si on est en preview et - // en train de cliquer + if (is_preview && Mouse_K) // pas de curseur si on est en preview et + return; // en train de cliquer + + if (Main_current_layer < 4) + { + if (is_preview) + goto single_pixel; + else + { + // Flood-fill the enclosing area + if (x= 0 && y >= 0 + && (color=Effect_function(x,y,color)) != (old_color=Read_pixel_from_current_layer(x,y)) + && (!((Stencil_mode) && (Stencil[old_color]))) + && (!((Mask_mode) && (Mask_table[Read_pixel_from_spare_screen(x,y)]))) + ) + { + short min_x,width,min_y,height; + short xx,yy; + + // determine area + switch(Main_current_layer) + { + case 0: + default: + // Full layer + min_x=0; + min_y=0; + width=Main_image_width; + height=Main_image_height; + break; + case 1: + case 2: + // Line + min_x=0; + min_y=y; + width=Main_image_width; + height=1; + break; + case 3: + // Segment + min_x=x / 48 * 48; + min_y=y; + width=48; + height=1; + break; + //case 4: + // // 8x8 + // min_x=x / 8 * 8; + // min_y=y / 8 * 8; + // width=8; + // height=8; + // break; + } + // Clip the bottom edge. + // (Necessary if image height is not a multiple) + if (min_y+height>=Main_image_height) + height=Main_image_height-min_y; + // Clip the right edge. + // (Necessary if image width is not a multiple) + if (min_x+width>=Main_image_width) + width=Main_image_width-min_x; + + for (yy=min_y; yy0) && (height>0) ) + Clear_brush(min_x-Main_offset_X, + min_y-Main_offset_Y, + 0,0, + width,height,0, + Main_image_width); + + if (Main_magnifier_mode != 0) + { + Compute_clipped_dimensions_zoom(&min_x,&min_y,&width,&height); + xx=min_x; + yy=min_y; + + if ( (width>0) && (height>0) ) + { + // Corrections dues au Zoom: + min_x=(min_x-Main_magnifier_offset_X)*Main_magnifier_factor; + min_y=(min_y-Main_magnifier_offset_Y)*Main_magnifier_factor; + height=min_y+(height*Main_magnifier_factor); + if (height>Menu_Y) + height=Menu_Y; + + Clear_brush_scaled(Main_X_zoom+min_x,min_y, + xx,yy, + width,height,0, + Main_image_width, + Horizontal_line_buffer); + } + } + // End of graphic feedback + } + } + return; + } switch (Paintbrush_shape) { case PAINTBRUSH_SHAPE_NONE : // No paintbrush. for colorpicker for example break; case PAINTBRUSH_SHAPE_POINT : // !!! TOUJOURS EN PREVIEW !!! + single_pixel: if ( (Paintbrush_X>=Limit_left) && (Paintbrush_X<=Limit_right) && (Paintbrush_Y>=Limit_top) diff --git a/src/buttons_effects.c b/src/buttons_effects.c index eb62b93d..c76d1190 100644 --- a/src/buttons_effects.c +++ b/src/buttons_effects.c @@ -546,7 +546,7 @@ void Button_Colorize_mode(void) switch(Colorize_current_mode) { case 0 : - Effect_function=Effect_interpolated_colorize; + Effect_function=Effect_layer_copy; break; case 1 : Effect_function=Effect_additive_colorize; diff --git a/src/const.h b/src/const.h index 5b146183..e4c60590 100644 --- a/src/const.h +++ b/src/const.h @@ -37,7 +37,7 @@ #define BETA1 98 ///< Version number for gfx2.cfg (3/4) #define BETA2 0 ///< Version number for gfx2.cfg (4/4) #define MAX_VIDEO_MODES 100 ///< Maximum number of video modes Grafx2 can propose. -#define NB_SHORTCUTS 181 ///< Number of actions that can have a key combination associated to it. +#define NB_SHORTCUTS 183 ///< Number of actions that can have a key combination associated to it. #define NB_ZOOM_FACTORS 15 ///< Number of zoom levels available in the magnifier. #define MENU_WIDTH 254 ///< Width of the menu (not counting the palette) #define MENU_HEIGHT 44 ///< Height of the menu. @@ -435,6 +435,8 @@ enum SPECIAL_ACTIONS SPECIAL_LAYER7_TOGGLE, SPECIAL_LAYER8_SELECT, SPECIAL_LAYER8_TOGGLE, + SPECIAL_FORMAT_CHECKER, + SPECIAL_FORMAT_CHECKER_MENU, NB_SPECIAL_SHORTCUTS ///< Number of special shortcuts }; diff --git a/src/engine.c b/src/engine.c index 7a4dcea7..514d4ea8 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1084,6 +1084,10 @@ void Main_handler(void) Layer_activate((key_index-SPECIAL_LAYER1_TOGGLE)/2, RIGHT_SIDE); action++; break; + case SPECIAL_FORMAT_CHECKER: + C64_FLI_enforcer(); + action++; + break; } } } // End of special keys diff --git a/src/graph.c b/src/graph.c index 06c78114..c393ebc0 100644 --- a/src/graph.c +++ b/src/graph.c @@ -2853,6 +2853,15 @@ byte Effect_smooth(word x,word y,__attribute__((unused)) byte color) // l'écran feedback car il s'agit de ne } // pas modifier l'écran courant. +byte Effect_layer_copy(word x,word y,byte color) +{ + if (colorPages->Nb_layers) + { + return *((y)*Main_image_width+(x)+Main_backups->Pages->Image[color]); + } + return Read_pixel_from_feedback_screen(x,y); +} + void Horizontal_grid_line(word x_pos,word y_pos,word width) { int x; @@ -2896,6 +2905,10 @@ byte Read_pixel_from_current_screen (word x,word y) #ifndef NOLAYERS byte depth; byte color; + + if (Main_current_layer==4) + return *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width); + color = *(Main_screen+y*Main_image_width+x); if (color != Main_backups->Pages->Transparent_color) // transparent color return color; @@ -2909,9 +2922,48 @@ byte Read_pixel_from_current_screen (word x,word y) void Pixel_in_current_screen (word x,word y,byte color,int with_preview) { - #ifndef NOLAYERS - byte depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); + #ifndef NOLAYERS + if ( Main_current_layer == 4) + { + if (color<4) + { + // Paste in layer + *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color; + // Paste in depth buffer + *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width)=color; + // Fetch pixel color from the target raster layer + color=*(Main_backups->Pages->Image[color] + x+y*Main_image_width); + // Draw that color on the visible image buffer + *(x+y*Main_image_width+Main_screen)=color; + + if (with_preview) + Pixel_preview(x,y,color); + } + } + else if (Main_current_layer<4 && (Main_layers_visible & (1<<4))) + { + byte depth; + + // Paste in layer *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color; + // Search depth + depth = *(Main_backups->Pages->Image[4] + x+y*Main_image_width); + + if ( depth == Main_current_layer) + { + // Draw that color on the visible image buffer + *(x+y*Main_image_width+Main_screen)=color; + + if (with_preview) + Pixel_preview(x,y,color); + } + } + else + { + byte depth; + + *(Main_backups->Pages->Image[Main_current_layer] + x+y*Main_image_width)=color; + depth = *(Main_visible_image_depth_buffer.Image+x+y*Main_image_width); if ( depth <= Main_current_layer) { if (color == Main_backups->Pages->Transparent_color) // transparent color @@ -2923,13 +2975,15 @@ void Pixel_in_current_screen (word x,word y,byte color,int with_preview) if (with_preview) Pixel_preview(x,y,color); } - #else - *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color; - if (with_preview) - Pixel_preview(x,y,color); - #endif + } + #else + *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color; + if (with_preview) + Pixel_preview(x,y,color); + #endif } + void Pixel_in_current_layer(word x,word y, byte color) { *((y)*Main_image_width+(x)+Main_backups->Pages->Image[Main_current_layer])=color; diff --git a/src/graph.h b/src/graph.h index 34a6f634..27724c5f 100644 --- a/src/graph.h +++ b/src/graph.h @@ -38,6 +38,7 @@ byte Effect_shade(word x,word y,byte color); byte Effect_quick_shade(word x,word y,byte color); byte Effect_tiling(word x,word y,byte color); byte Effect_smooth(word x,word y,byte color); +byte Effect_layer_copy(word x,word y,byte color); void Display_foreback(void); diff --git a/src/help.c b/src/help.c index 1fee8884..9fcf976e 100644 --- a/src/help.c +++ b/src/help.c @@ -31,8 +31,6 @@ #include #elif defined (__linux__) #include -#elif defined(__HAIKU__) - #include "haiku.h" #endif #include "const.h" @@ -64,7 +62,7 @@ word * Shortcut(word shortcut_number) return &(Config_Key[shortcut_number & 0xFF][0]); } -// Nom de la touche actuallement assignée à un raccourci d'après son numéro +// Nom de la touche actuallement assignée à un raccourci d'après son numéro // de type 0x100+BOUTON_* ou SPECIAL_* const char * Keyboard_shortcut_value(word shortcut_number) { @@ -672,8 +670,6 @@ void Button_Stats(void) statfs(Main_current_directory,&disk_info); mem_size=(qword) disk_info.f_bfree * (qword) disk_info.f_bsize; } -#elif defined(__HAIKU__) - mem_size = haiku_get_free_space(Main_current_directory); #else // Free disk space is only for shows. Other platforms can display 0. #warning "Missing code for your platform !!! Check and correct please :)" diff --git a/src/helpfile.h b/src/helpfile.h index 0351dc6d..5e246059 100644 --- a/src/helpfile.h +++ b/src/helpfile.h @@ -312,6 +312,12 @@ static const T_Help_table helptable_help[] = HELP_LINK (" 6 : %s", SPECIAL_LAYER6_TOGGLE) HELP_LINK (" 7 : %s", SPECIAL_LAYER7_TOGGLE) HELP_LINK (" 8 : %s", SPECIAL_LAYER8_TOGGLE) + HELP_TEXT ("") + HELP_LINK (" Format check : %s", SPECIAL_FORMAT_CHECKER) + HELP_LINK (" Format check menu: %s", SPECIAL_FORMAT_CHECKER_MENU) + HELP_TEXT ("") + HELP_TEXT ("") + HELP_TEXT ("") }; static const T_Help_table helptable_credits[] = { diff --git a/src/hotkeys.c b/src/hotkeys.c index 764275bb..46150eb7 100644 --- a/src/hotkeys.c +++ b/src/hotkeys.c @@ -1477,6 +1477,14 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = { true, SDLK_HOME|MOD_ALT, // Alt + Home 0}, + {181, + "Format checker", + "Performs a format check on the", + "current image.", + "", + true, + 0, + 0}, }; word Ordering[NB_SHORTCUTS]= @@ -1662,4 +1670,6 @@ word Ordering[NB_SHORTCUTS]= 0x100+BUTTON_LAYER_UP, 0x100+BUTTON_LAYER_DOWN, 0x100+BUTTON_LAYER_MENU, + SPECIAL_FORMAT_CHECKER, + SPECIAL_FORMAT_CHECKER_MENU, }; diff --git a/src/loadsave.c b/src/loadsave.c index 3aacd162..b8f1075e 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -134,7 +134,7 @@ void Load_SDL_Image(T_IO_Context *); // 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_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;koala;fli;bml;cdu;prg;tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"}, {FORMAT_ALL_FILES, "(*.*)", NULL, NULL, NULL, 0, 0, 0, "", "*"}, {FORMAT_GIF, " gif", Test_GIF, Load_GIF, Save_GIF, 0, 1, 1, "gif", "gif"}, #ifndef __no_pnglib__ @@ -152,7 +152,7 @@ T_Format File_formats[NB_KNOWN_FORMATS] = { {FORMAT_NEO, " neo", Test_NEO, Load_NEO, Save_NEO, 0, 0, 0, "neo", "neo"}, {FORMAT_KCF, " kcf", Test_KCF, Load_KCF, Save_KCF, 1, 0, 0, "kcf", "kcf"}, {FORMAT_PAL, " pal", Test_PAL, Load_PAL, Save_PAL, 1, 0, 0, "pal", "pal"}, - {FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 0, "c64", "c64;koa"}, + {FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 0, "c64", "c64;koa;koala;fli;bml;cdu;prg"}, {FORMAT_SCR, " cpc", NULL, NULL, Save_SCR, 0, 0, 0, "cpc", "cpc;scr"}, {FORMAT_MISC,"misc.",NULL, NULL, NULL, 0, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"}, }; @@ -430,8 +430,7 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size, // 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); + Print_in_window(45,70,context->Comment,MC_Black,MC_Light); // Calcul des données nécessaires à l'affichage de la preview: if (ratio == PIXEL_WIDE && diff --git a/src/misc.c b/src/misc.c index bc750078..de374850 100644 --- a/src/misc.c +++ b/src/misc.c @@ -826,6 +826,28 @@ double Fround(double n, unsigned d) return floor(n * exp + 0.5) / exp; } +/// Count number of bits in a word (16bit). +/// Based on Wikipedia article for Hamming_weight, it's optimized +/// for cases when zeroes are more frequent. +int Popcount_word(word x) +{ + word count; + for (count=0; x; count++) + x &= x-1; + return count; +} + +/// Count number of bits in a dword (32bit). +/// Based on Wikipedia article for Hamming_weight, it's optimized +/// for cases when zeroes are more frequent. +int Popcount_dword(dword x) +{ + dword count; + for (count=0; x; count++) + x &= x-1; + return count; +} + // Fonction retournant le libellé d'une mode (ex: " 320x200") char * Mode_label(int mode) diff --git a/src/misc.h b/src/misc.h index 523f143d..bd365211 100644 --- a/src/misc.h +++ b/src/misc.h @@ -165,3 +165,6 @@ int Max(int a,int b); char* Mode_label(int mode); int Convert_videomode_arg(const char *argument); + +int Popcount_word(word x); +int Popcount_dword(dword x); diff --git a/src/miscfileformats.c b/src/miscfileformats.c index 6c032a7b..28453236 100644 --- a/src/miscfileformats.c +++ b/src/miscfileformats.c @@ -39,6 +39,7 @@ #include "sdlscreen.h" #include "struct.h" #include "windows.h" +#include "oldies.h" //////////////////////////////////// PAL //////////////////////////////////// // @@ -444,24 +445,24 @@ void Load_PKM(T_IO_Context * context) // Trouver quels sont les octets de reconnaissance void Find_recog(byte * recog1, byte * recog2) { - dword Find_recon[256]; // Table d'utilisation de couleurs + dword color_usage[256]; // Table d'utilisation de couleurs byte best; // Meilleure couleur pour recon (recon1 puis recon2) dword NBest; // Nombre d'occurences de cette couleur word index; // On commence par compter l'utilisation de chaque couleurs - Count_used_colors(Find_recon); + Count_used_colors(color_usage); // Ensuite recog1 devient celle la moins utilisée de celles-ci *recog1=0; best=1; NBest=INT_MAX; // Une même couleur ne pourra jamais être utilisée 1M de fois. for (index=1;index<=255;index++) - if (Find_recon[index]File_name, context->File_directory); if ((file=fopen(filename,"wb"))) { // On regarde si des couleurs >16 sont utilisées dans l'image - for (x_pos=16;((x_pos<256) && (!Utilisation[x_pos]));x_pos++); + for (x_pos=16;((x_pos<256) && (!color_usage[x_pos]));x_pos++); if (x_pos==256) { @@ -1173,10 +1174,10 @@ void Save_KCF(T_IO_Context * context) int pal_index; int color_index; int index; - dword Utilisation[256]; // Table d'utilisation de couleurs + dword color_usage[256]; // Table d'utilisation de couleurs // On commence par compter l'utilisation de chaque couleurs - Count_used_colors(Utilisation); + Count_used_colors(color_usage); File_error=0; Get_full_filename(filename, context->File_name, context->File_directory); @@ -1185,7 +1186,7 @@ void Save_KCF(T_IO_Context * context) // Sauvegarde de la palette // On regarde si des couleurs >16 sont utilisées dans l'image - for (index=16;((index<256) && (!Utilisation[index]));index++); + for (index=16;((index<256) && (!color_usage[index]));index++); if (index==256) { @@ -2035,6 +2036,7 @@ void Save_NEO(T_IO_Context * context) } //////////////////////////////////// C64 //////////////////////////////////// + void Test_C64(T_IO_Context * context) { FILE* file; @@ -2050,14 +2052,15 @@ void Test_C64(T_IO_Context * context) file_size = File_length_file(file); switch (file_size) { - case 1000: // screen or color - case 1002: // (screen or color) + loadaddr case 8000: // raw bitmap case 8002: // raw bitmap with loadaddr - case 9000: // bitmap + screen - case 9002: // bitmap + screen + loadaddr + case 9000: // bitmap + ScreenRAM + case 9002: // bitmap + ScreenRAM + loadaddr case 10001: // multicolor case 10003: // multicolor + loadaddr + case 17472: // FLI (BlackMail) + case 17474: // FLI (BlackMail) + loadaddr + case 10277: // multicolor CDU-Paint + loadaddr File_error = 0; break; default: // then we don't know for now. @@ -2071,7 +2074,7 @@ void Test_C64(T_IO_Context * context) } } -void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors) +void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *screen_ram) { int cx,cy,x,y,c[4],pixel,color; @@ -2079,8 +2082,8 @@ void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors) { for(cx=0; cx<40; cx++) { - c[0]=colors[cy*40+cx]&15; - c[1]=colors[cy*40+cx]>>4; + c[0]=screen_ram[cy*40+cx]&15; + c[1]=screen_ram[cy*40+cx]>>4; for(y=0; y<8; y++) { pixel=bitmap[cy*320+cx*8+y]; @@ -2094,7 +2097,7 @@ void Load_C64_hires(T_IO_Context *context, byte *bitmap, byte *colors) } } -void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nybble, byte background) +void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *screen_ram, byte *color_ram, byte background) { int cx,cy,x,y,c[4],pixel,color; c[0]=background&15; @@ -2102,9 +2105,9 @@ void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nyb { for(cx=0; cx<40; cx++) { - c[1]=colors[cy*40+cx]>>4; - c[2]=colors[cy*40+cx]&15; - c[3]=nybble[cy*40+cx]&15; + c[1]=screen_ram[cy*40+cx]>>4; + c[2]=screen_ram[cy*40+cx]&15; + c[3]=color_ram[cy*40+cx]&15; for(y=0; y<8; y++) { @@ -2120,16 +2123,113 @@ void Load_C64_multi(T_IO_Context *context, byte *bitmap, byte *colors, byte *nyb } } +void Load_C64_fli(T_IO_Context *context, byte *bitmap, byte *screen_ram, byte *color_ram, byte *background) +{ + // Thanks to MagerValp for complement of specifications. + // + // background : length: 200 (+ padding 56) + // These are the BG colors for lines 0-199 (top to bottom) + // Low nybble: the color. + // High nybble: garbage. ignore it. + // color_ram : length: 1000 (+ padding 24) + // Color RAM. Contains one color per 4x8 block. + // There are 40x25 such blocks, arranged from top left to bottom + // right, starting in right direction. For each block there is one byte. + // Low nybble: the color. + // High nybble: garbage. ignore it. + // screen_ram : length: 8192 + // Screen RAMs. The s is important. + // This is actually 8 blocks of 1000 bytes, each separated by a filler of + // 24 bytes. Each byte contains data for a 4x1 pixel group, and a complete + // block will contain 40x25 of them. 40 is from left to right, and 25 is from + // top to bottom, spacing them 8 lines apart. + // The second block start at y=1, the third block starts at y=2, etc... + // Each byte contains 2 colors that *can* be used by the 4x1 pixel group: + // Low nybble: Color 1 + // High nybble: Color 2 + // + // bitmap : length: 8000 + // This is the final structure that refers to all others. It describes + // 160x200 pixels linearly, from top left to bottom right, starting in + // right direction. For each pixel, two bits say which color is displayed + // (So 4 pixels are described by the same byte) + // 00 Use the BG color of the current line (background[y]) + // 01 Use the Color 2 from the current 4x8 block of Screen RAM + // ((screen_ram[y/8][x/4] & 0xF0) >> 8) + // 10 Use the Color 1 from the current 4x8 block of Screen RAM + // (screen_ram[y/8][x/4] & 0x0F) + // 11 Use the color from Color RAM + // (color_ram[y/8][x/4] & 0x0F) + // + + int cx,cy,x,y,c[4]; + + for(y=0; y<200; y++) + { + for(x=0; x<160; x++) + { + Set_pixel(context, x,y,background[y]); + } + } + + Set_layer(context, 1); + for(cy=0; cy<25; cy++) + { + for(cx=0; cx<40; cx++) + { + c[3]=color_ram[cy*40+cx]&15; + for(y=0; y<8; y++) + { + for(x=0; x<4; x++) + { + Set_pixel(context, cx*4+(3-x),cy*8+y,c[3]); + } + } + } + } + + Set_layer(context, 2); + for(cy=0; cy<25; cy++) + { + for(cx=0; cx<40; cx++) + { + c[3]=color_ram[cy*40+cx]&15; + for(y=0; y<8; y++) + { + int pixel=bitmap[cy*320+cx*8+y]; + + c[0]=background[cy*8+y]&15; + c[1]=screen_ram[y*1024+cy*40+cx]>>4; + c[2]=screen_ram[y*1024+cy*40+cx]&15; + for(x=0; x<4; x++) + { + int color=c[(pixel&3)]; + pixel>>=2; + Set_pixel(context, cx*4+(3-x),cy*8+y,color); + } + } + } + } + Set_layer(context, 3); + for(y=0; y<200; y++) + { + for(x=0; x<160; x++) + { + Set_pixel(context, x,y,16); + } + } +} + void Load_C64(T_IO_Context * context) { FILE* file; char filename[MAX_PATH_CHARACTERS]; long file_size; - int i; - byte background,hasLoadAddr=0; + byte hasLoadAddr=0; int loadFormat=0; - enum c64_format {F_hires,F_multi,F_bitmap,F_screen,F_color}; - const char *c64_format_names[]={"hires","multicolor","bitmap","screen","color"}; + enum c64_format {F_hires,F_multi,F_bitmap,F_fli}; + const char *c64_format_names[]={"Hires","Multicolor","Bitmap","FLI"}; + // Palette from http://www.pepto.de/projects/colorvic/ byte pal[48]={ @@ -2150,118 +2250,194 @@ void Load_C64(T_IO_Context * context) 0x6C, 0x5E, 0xB5, 0x95, 0x95, 0x95}; - byte bitmap[8000],colors[1000],nybble[1000]; + byte *file_buffer; + byte *bitmap, *screen_ram, *color_ram=NULL, *background=NULL; // Only pointers to existing data word width=320, height=200; + static byte dummy_screen[1000]; Get_full_filename(filename, context->File_name, context->File_directory); file = fopen(filename,"rb"); if (file) { - File_error=0; - file_size = File_length_file(file); + File_error=0; + file_size = File_length_file(file); - switch (file_size) + // Check for known file sizes + switch (file_size) + { + case 8000: // raw bitmap + case 8002: // raw bitmap with loadaddr + case 9000: // bitmap + ScreenRAM + case 9002: // bitmap + ScreenRAM + loadaddr + case 10001: // multicolor + case 10003: // multicolor + loadaddr + case 10277: // multicolor CDU-Paint + loadaddr + case 17472: // FLI (BlackMail) + case 17474: // FLI (BlackMail) + loadaddr + break; + + default: + File_error = 1; + fclose(file); + return; + } + // Load entire file in memory + file_buffer=(byte *)malloc(file_size); + if (!file_buffer) + { + File_error = 1; + fclose(file); + return; + } + if (!Read_bytes(file,file_buffer,file_size)) + { + File_error = 1; + free(file_buffer); + fclose(file); + return; + } + fclose(file); + + memset(dummy_screen,1,1000); + + switch (file_size) { - case 1000: // screen or color - hasLoadAddr=0; - loadFormat=F_screen; - break; - - case 1002: // (screen or color) + loadaddr - hasLoadAddr=1; - loadFormat=F_screen; - break; - case 8000: // raw bitmap hasLoadAddr=0; loadFormat=F_bitmap; + bitmap=file_buffer+0; // length: 8000 + screen_ram=dummy_screen; break; - + case 8002: // raw bitmap with loadaddr hasLoadAddr=1; loadFormat=F_bitmap; + bitmap=file_buffer+2; // length: 8000 + screen_ram=dummy_screen; break; - case 9000: // bitmap + screen + case 9000: // bitmap + ScreenRAM hasLoadAddr=0; loadFormat=F_hires; + bitmap=file_buffer+0; // length: 8000 + screen_ram=file_buffer+8000; // length: 1000 break; - case 9002: // bitmap + screen + loadaddr + case 9002: // bitmap + ScreenRAM + loadaddr hasLoadAddr=1; loadFormat=F_hires; + bitmap=file_buffer+2; // length: 8000 + screen_ram=file_buffer+8002; // length: 1000 break; case 10001: // multicolor hasLoadAddr=0; loadFormat=F_multi; + context->Ratio = PIXEL_WIDE; + bitmap=file_buffer+0; // length: 8000 + screen_ram=file_buffer+8000; // length: 1000 + color_ram=file_buffer+9000; // length: 1000 + background=file_buffer+10000; // only 1 break; case 10003: // multicolor + loadaddr hasLoadAddr=1; loadFormat=F_multi; + context->Ratio = PIXEL_WIDE; + bitmap=file_buffer+2; // length: 8000 + screen_ram=file_buffer+8002; // length: 1000 + color_ram=file_buffer+9002; // length: 1000 + background=file_buffer+10002; // only 1 break; - - default: // then we don't know what it is. - File_error = 1; + case 10277: // multicolor CDU-Paint + loadaddr + hasLoadAddr=1; + loadFormat=F_multi; + context->Ratio = PIXEL_WIDE; + // 273 bytes of display routine + bitmap=file_buffer+275; // length: 8000 + screen_ram=file_buffer+8275; // length: 1000 + color_ram=file_buffer+9275; // length: 1000 + background=file_buffer+10275; // only 1 + break; + + case 17472: // FLI (BlackMail) + hasLoadAddr=0; + loadFormat=F_fli; + context->Ratio = PIXEL_WIDE; + background=file_buffer+0; // length: 200 (+ padding 56) + color_ram=file_buffer+256; // length: 1000 (+ padding 24) + screen_ram=file_buffer+1280; // length: 8192 + bitmap=file_buffer+9472; // length: 8000 + break; + + case 17474: // FLI (BlackMail) + loadaddr + hasLoadAddr=1; + loadFormat=F_fli; + context->Ratio = PIXEL_WIDE; + background=file_buffer+2; // length: 200 (+ padding 56) + color_ram=file_buffer+258; // length: 1000 (+ padding 24) + screen_ram=file_buffer+1282; // length: 8192 + bitmap=file_buffer+9474; // length: 8000 + break; + + default: + File_error = 1; + free(file_buffer); + return; } + if (context->Ratio == PIXEL_WIDE) + width=160; + + // Write detailed format in comment + strcpy(context->Comment, c64_format_names[loadFormat]); + if (hasLoadAddr) + { + // get load address + word load_addr; + load_addr = file_buffer[0] | (file_buffer[1] << 8); + sprintf(context->Comment+strlen(context->Comment),", load at $%04.4X",load_addr); + } + else + { + sprintf(context->Comment+strlen(context->Comment),", no addr"); + } + + Pre_load(context, width, height, file_size, FORMAT_C64, context->Ratio,0); // Do this as soon as you can + memcpy(context->Palette,pal,48); // this set the software palette for grafx2 + // Transparent color "16" is a dark grey that is distinguishable + // from black, but darker than normal colors. + context->Palette[16].R=20; + context->Palette[16].G=20; + context->Palette[16].B=20; + Palette_loaded(context); // Always call it if you change the palette - if (file_size>9002) - width=160; - - if (hasLoadAddr) - { - // get load address - Read_byte(file,&background); - Read_byte(file,&background); - sprintf(filename,"load at $%02x00",background); - } - else - { - sprintf(filename,"no addr"); - } - - if(file_size>9002) - { - context->Ratio = PIXEL_WIDE; - } - sprintf(context->Comment,"C64 %s, %s", - c64_format_names[loadFormat],filename); - Pre_load(context, width, height, file_size, FORMAT_C64, context->Ratio,0); // Do this as soon as you can - context->Width = width ; context->Height = height; + context->Transparent_color=16; - Read_bytes(file,bitmap,8000); - - if (file_size>8002) - Read_bytes(file,colors,1000); - else + if(loadFormat==F_fli) { - for(i=0;i<1000;i++) - { - colors[i]=1; - } + Load_C64_fli(context,bitmap,screen_ram,color_ram,background); } - - if(width==160) + else + if(loadFormat==F_multi) { - Read_bytes(file,nybble,1000); - Read_byte(file,&background); - Load_C64_multi(context,bitmap,colors,nybble,background); + Load_C64_multi(context,bitmap,screen_ram,color_ram,*background); } else { - Load_C64_hires(context,bitmap,colors); + Load_C64_hires(context,bitmap,screen_ram); } File_error = 0; - fclose(file); + + free(file_buffer); + } else File_error = 1; @@ -2290,17 +2466,17 @@ int Save_C64_window(byte *saveWhat, byte *loadAddr) }; Open_window(200,120,"c64 settings"); - Window_set_normal_button(110,100,80,15,"Save",1,1,SDLK_RETURN); - Window_set_normal_button(10,100,80,15,"Cancel",1,1,SDLK_ESCAPE); + Window_set_normal_button(110,100,80,15,"Save",1,1,SDLK_RETURN); // 1 + Window_set_normal_button(10,100,80,15,"Cancel",1,1,SDLK_ESCAPE); // 2 Print_in_window(13,18,"Data:",MC_Dark,MC_Light); - what=Window_set_dropdown_button(10,28,90,15,70,what_label[*saveWhat],1, 0, 1, LEFT_SIDE,0); + what=Window_set_dropdown_button(10,28,90,15,70,what_label[*saveWhat],1, 0, 1, LEFT_SIDE,0); // 3 Window_dropdown_clear_items(what); for (i=0; iFile_name, context->File_directory); + /* if (numcolors>16) { Warning_message("Error: Max 16 colors"); File_error = 1; return; } + */ if (((context->Width!=320) && (context->Width!=160)) || context->Height!=200) { Warning_message("must be 320x200 or 160x200"); @@ -2574,7 +2801,7 @@ void Save_C64(T_IO_Context * context) if (context->Width==320) File_error = Save_C64_hires(context,filename,saveWhat,loadAddr); else - File_error = Save_C64_multi(context,filename,saveWhat,loadAddr); + File_error = Save_C64_fli(filename,saveWhat,loadAddr); } diff --git a/src/oldies.c b/src/oldies.c new file mode 100644 index 00000000..9be48122 --- /dev/null +++ b/src/oldies.c @@ -0,0 +1,411 @@ +/* vim:expandtab:ts=2 sw=2: +*/ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Yves Rizoud + Copyright 2008 Franck Charlet + Copyright 2007 Adrien Destugues + Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see +*/ +#include +#include +#include +#include +#include +#include "struct.h" +#include "global.h" +#include "errors.h" +#include "misc.h" +#include "palette.h" + +void Pixel_in_layer(word x,word y, byte layer, byte color) +{ + *((y)*Main_image_width+(x)+Main_backups->Pages->Image[layer])=color; +} + +byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background) +{ + word used_colors[200][40]; + word block_used_colors[25][40]; + word line_used_colors[200]; + byte used_colors_count[200][40]; + dword usage[16]; + word x,y,row,col; + int i; + byte line_color[200]; + byte block_color[25][40]; + word best_color_count; + byte best_color; + const byte no_color=16; + + // Prerequisites + if (Main_backups->Pages->Nb_layers < 3) + return 1; + if (Main_image_width != 160 || Main_image_height != 200) + return 2; + + memset(used_colors,0,200*40*sizeof(word)); + memset(block_used_colors,0,25*40*sizeof(word)); + memset(line_used_colors,0,200*sizeof(word)); + memset(used_colors_count,0,200*40*sizeof(byte)); + + // Initialize these as "unset" + memset(line_color,no_color,200*sizeof(byte)); + memset(block_color,no_color,25*40*sizeof(byte)); + + // Examine all 4-pixel blocks to fill used_colors[][] + for (row=0;row<200;row++) + { + for (col=0;col<40;col++) + { + for (x=0;x<4;x++) + { + byte c=*((row)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2]); + used_colors[row][col] |= 1<Pages->Image[0]); + if (c<16) + { + line_color[row]=c; + for (col=0;col<40;col++) + { + // Remove that color from the sets + used_colors[row][col] &= ~(1<Pages->Image[1]); + if (c<16) + { + block_color[row/8][col]=c; + // Remove that color from the sets + for (y=0; y<8;y++) + used_colors[row+y][col] &= ~(1<best_color_count) + { + best_color_count=usage[i]; + best_color=i; + } + } + line_color[row]=best_color; + + // Remove that color from the sets + for (col=0;col<40;col++) + { + if (used_colors[row][col] & (1<2) + { + filter &= used_colors[row+y][col]; + + for (i=0; i<16; i++) + { + if (used_colors[row+y][col] & (1<best_color_count) + { + best_color_count=usage[i]; + best_color=i; + } + } + } + } + block_color[row/8][col]=best_color; + + // Remove that color from the sets + for (y=0;y<8;y++) + { + if (used_colors[row+y][col] & (1<15) + c1=16; + if (c2>15) + c2=16; + + // Output Screen RAMs + if (screen_ram!=NULL) + screen_ram[y*1024+row*40+col] = (c1&15) | ((c2&15)<<4); + + // Output bitmap + if (bitmap!=NULL) + { + for(x=0; x<4; x++) + { + byte bits; + byte c=*((row*8+y)*Main_image_width+(col*4+x)+Main_backups->Pages->Image[2]); + + if (c==line_color[row*8+y]) + // BG color + bits=0; + else if (c==block_color[row][col]) + // block color + bits=3; + else if (c==c1) + // Color 1 + bits=2; + else if (c==c2) + // Color 2 + bits=1; + else // problem + bits=0; + // clear target bits + //bitmap[row*320+col*8+y] &= ~(3<<((3-x)*2)); + // set them + bitmap[row*320+col*8+y] |= bits<<((3-x)*2); + } + } + } + } + } + //memset(background,3,200); + //memset(color_ram,5,8000); + //memset(screen_ram,(9<<4) | 7,8192); + + return 0; + +} + +byte C64_FLI_enforcer(void) +{ + byte background[200]; + byte bitmap[8000]; + byte screen_ram[8192]; + byte color_ram[1000]; + + int row, col, x, y; + byte c[4]; + + // Checks + if (Main_image_width != 160) + return 1; + if (Main_image_height != 200) + return 1; + if (Main_backups->Pages->Nb_layers != 4) + return 2; + + Backup_layers(1<<3); + + memset(bitmap,0,8000); + memset(background,0,200); + memset(color_ram,0,1000); + memset(screen_ram,0,8192); + C64_FLI(bitmap, screen_ram, color_ram, background); + + for(row=0; row<25; row++) + { + for(col=0; col<40; col++) + { + c[3]=color_ram[row*40+col]&15; + for(y=0; y<8; y++) + { + int pixel=bitmap[row*320+col*8+y]; + + c[0]=background[row*8+y]&15; + c[1]=screen_ram[y*1024+row*40+col]>>4; + c[2]=screen_ram[y*1024+row*40+col]&15; + for(x=0; x<4; x++) + { + int color=c[(pixel&3)]; + pixel>>=2; + Pixel_in_layer(col*4+(3-x),row*8+y,3,color); + } + } + } + } + End_of_modification(); + + // Visible feedback: + + // If the "check" layer was visible, manually update the whole thing + if (Main_layers_visible & (1<<3)) + { + Hide_cursor(); + Redraw_layered_image(); + Display_all_screen(); + Display_layerbar(); + Display_cursor(); + } + else + // Otherwise, simply toggle the layer visiblity + Layer_activate(3,RIGHT_SIDE); + + + return 0; +} \ No newline at end of file diff --git a/src/oldies.h b/src/oldies.h new file mode 100644 index 00000000..8476775f --- /dev/null +++ b/src/oldies.h @@ -0,0 +1,24 @@ +/* vim:expandtab:ts=2 sw=2: +*/ +/* Grafx2 - The Ultimate 256-color bitmap paint program + + Copyright 2008 Adrien Destugues + + Grafx2 is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 + of the License. + + Grafx2 is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Grafx2; if not, see +*/ + +byte C64_FLI(byte *bitmap, byte *screen_ram, byte *color_ram, byte *background); + +byte C64_FLI_enforcer(void); + diff --git a/src/pages.c b/src/pages.c index de7fccec..4b3c5ee0 100644 --- a/src/pages.c +++ b/src/pages.c @@ -178,25 +178,47 @@ void Redraw_layered_image(void) { #ifndef NOLAYERS // Re-construct the image with the visible layers - byte layer; + byte layer=0; // First layer - for (layer=0; layerPages->Nb_layers; layer++) + if (Main_layers_visible & (1<<4)) { - if ((1<Pages->Image[layer], - Main_image_width*Main_image_height); - - // Initialize the depth buffer - memset(Main_visible_image_depth_buffer.Image, - layer, - Main_image_width*Main_image_height); - - // skip all other layers - layer++; - break; + layer = *(Main_backups->Pages->Image[4]+i); + Main_visible_image.Image[i]=*(Main_backups->Pages->Image[layer]+i); + } + + // Copy it to the depth buffer + memcpy(Main_visible_image_depth_buffer.Image, + Main_backups->Pages->Image[4], + Main_image_width*Main_image_height); + + // Next + layer= (1<<4)+1; + } + else + { + for (layer=0; layerPages->Nb_layers; layer++) + { + if ((1<Pages->Image[layer], + Main_image_width*Main_image_height); + + // Initialize the depth buffer + memset(Main_visible_image_depth_buffer.Image, + layer, + Main_image_width*Main_image_height); + + // skip all other layers + layer++; + break; + } } } // subsequent layer(s) diff --git a/src/struct.h b/src/struct.h index 3e8fbde2..f46c2560 100644 --- a/src/struct.h +++ b/src/struct.h @@ -323,11 +323,11 @@ typedef struct byte Grid_XOR_color; ///< XOR value to apply for grid color. } T_Config; -// Structures utilisées pour les descriptions de pages et de liste de pages. -// Lorsqu'on gérera les animations, il faudra aussi des listes de listes de +// Structures utilisées pour les descriptions de pages et de liste de pages. +// Lorsqu'on gèrera les animations, il faudra aussi des listes de listes de // pages. -// Ces structures sont manipulées à travers des fonctions de gestion du +// Ces structures sont manipulées à travers des fonctions de gestion du // backup dans "graph.c". /// This is the data for one step of Undo/Redo, for one image. @@ -350,11 +350,7 @@ typedef struct T_Page byte Background_transparent; ///< Boolean, true if Layer 0 should have transparent pixels byte Transparent_color; ///< Index of transparent color. 0 to 255. byte Nb_layers; ///< Number of layers -#if __GNUC__ < 3 - byte * Image[0]; -#else byte * Image[]; ///< Pixel data for the (first layer of) image. -#endif // Define as Image[0] if you have an old gcc which is not C99. // No field after Image[] ! Dynamic layer allocation for Image[1], [2] etc. } T_Page;