diff --git a/Makefile b/Makefile index 8beba9db..f8830ffe 100644 --- a/Makefile +++ b/Makefile @@ -229,7 +229,7 @@ else # Compiles a regular linux exectutable for the native platform BIN = grafx2 COPT = -W -Wall -Wdeclaration-after-statement -std=c99 -c -g `sdl-config --cflags` $(TTFCOPT) $(LUACOPT) - LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng $(LUALOPT) + LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng $(LUALOPT) -lm # Use gcc for compiling. Use ncc to build a callgraph and analyze the code. CC = gcc #CC = nccgen -ncgcc -ncld -ncfabs @@ -287,7 +287,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 +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 SKIN_FILES = skins/skin_classic.png skins/skin_modern.png skins/font_Classic.png skins/font_Fun.png diff --git a/Makefile.dep b/Makefile.dep index aaa84ec2..b95a0802 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -30,16 +30,17 @@ $(OBJDIR)/input.o: input.c global.h struct.h const.h keyboard.h sdlscreen.h \ windows.h errors.h misc.h input.h $(OBJDIR)/io.o: io.c struct.h const.h io.h realpath.h $(OBJDIR)/keyboard.o: keyboard.c global.h struct.h const.h keyboard.h +$(OBJDIR)/libraw2crtc.o: libraw2crtc.c global.h struct.h const.h $(OBJDIR)/loadsave.o: loadsave.c buttons.h struct.h const.h errors.h global.h io.h \ - loadsave.h misc.h op_c.h pages.h palette.h sdlscreen.h windows.h \ - engine.h + loadsave.h misc.h graph.h op_c.h pages.h palette.h sdlscreen.h \ + windows.h engine.h $(OBJDIR)/main.o: main.c const.h struct.h global.h graph.h misc.h init.h buttons.h \ engine.h pages.h loadsave.h sdlscreen.h errors.h readini.h saveini.h \ io.h text.h setup.h windows.h brush.h palette.h realpath.h $(OBJDIR)/misc.o: misc.c struct.h const.h sdlscreen.h global.h errors.h buttons.h \ - engine.h misc.h keyboard.h windows.h palette.h input.h -$(OBJDIR)/miscfileformats.o: miscfileformats.c global.h struct.h const.h loadsave.h \ - windows.h + engine.h misc.h keyboard.h windows.h palette.h input.h graph.h +$(OBJDIR)/miscfileformats.o: miscfileformats.c engine.h struct.h const.h errors.h \ + global.h io.h libraw2crtc.h loadsave.h misc.h sdlscreen.h windows.h $(OBJDIR)/mountlist.o: mountlist.c $(OBJDIR)/op_c.o: op_c.c op_c.h struct.h const.h errors.h $(OBJDIR)/operatio.o: operatio.c const.h struct.h global.h misc.h engine.h graph.h \ diff --git a/SFont.c b/SFont.c index 6b23f027..0e9a8c95 100644 --- a/SFont.c +++ b/SFont.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* SFont: a simple font-library that uses special .pngs as fonts Copyright (C) 2003 Karl Bartel diff --git a/SFont.h b/SFont.h index dd1c9804..bca5fae2 100644 --- a/SFont.h +++ b/SFont.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* SFont: a simple font-library that uses special bitmaps as fonts Copyright (C) 2003 Karl Bartel diff --git a/brush.c b/brush.c index c3032587..21f4dc01 100644 --- a/brush.c +++ b/brush.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Franck Charlet diff --git a/brush.h b/brush.h index f7e20080..7369cd6d 100644 --- a/brush.h +++ b/brush.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007-2008 Adrien Destugues diff --git a/buttons.c b/buttons.c index 07ae8c05..c9145d9e 100644 --- a/buttons.c +++ b/buttons.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud @@ -3453,6 +3455,11 @@ void Button_Grid_menu(void) short dx_selected=Snap_offset_X; short dy_selected=Snap_offset_Y; + char showgrid = Show_grid; + // if grid is shown check if we snap + // if not snap by default (so the window work like before we introduced the "show" option) + char snapgrid = Show_grid?Snap_mode:1; + T_Special_button * input_x_button; T_Special_button * input_y_button; T_Special_button * input_dx_button; @@ -3461,10 +3468,10 @@ void Button_Grid_menu(void) char str[3]; - Open_window(133,98,"Grid"); + Open_window(133,118,"Grid"); - Window_set_normal_button(12,72,51,14,"Cancel",0,1,KEY_ESC); // 1 - Window_set_normal_button(70,72,51,14,"OK" ,0,1,SDLK_RETURN); // 2 + Window_set_normal_button(12,92,51,14,"Cancel",0,1,KEY_ESC); // 1 + Window_set_normal_button(70,92,51,14,"OK" ,0,1,SDLK_RETURN); // 2 Print_in_window(19,26, "X:",MC_Dark,MC_Light); input_x_button = Window_set_input_button(37,24,2); // 3 @@ -3484,6 +3491,16 @@ void Button_Grid_menu(void) Print_in_window(69,47,"dY:",MC_Dark,MC_Light); input_dy_button = Window_set_input_button(95,45,2); // 6 Num2str(dy_selected,str,2); + + Window_set_normal_button(12, 62, 14, 14, " ", 0, 1, 0); // 7 + Window_set_normal_button(70, 62, 14, 14, " ", 0, 1, 0); // 8 + if (snapgrid) + Print_in_window(16, 65, "X", MC_Black, MC_Light); + if (Show_grid) + Print_in_window(74, 65, "X", MC_Black, MC_Light); + Print_in_window(32, 65,"Snap",MC_Dark,MC_Light); + Print_in_window(90, 65,"Show",MC_Dark,MC_Light); + Window_input_content(input_dy_button,str); Update_window_area(0,0,Window_width, Window_height); @@ -3568,6 +3585,20 @@ void Button_Grid_menu(void) Window_input_content(input_dy_button,str); Display_cursor(); + + case 7: + snapgrid = !snapgrid; + Hide_cursor(); + Print_in_window(16, 65, snapgrid?"X":" ", MC_Black, MC_Light); + Display_cursor(); + break; + case 8: + showgrid = !showgrid; + Hide_cursor(); + Print_in_window(74, 65, showgrid?"X":" ", MC_Black, MC_Light); + Display_cursor(); + break; + } if (Is_shortcut(Key,0x100+BUTTON_HELP)) Window_help(BUTTON_EFFECTS, "GRID"); @@ -3580,14 +3611,12 @@ void Button_Grid_menu(void) Snap_height=chosen_Y; Snap_offset_X=dx_selected; Snap_offset_Y=dy_selected; - Snap_mode=1; + Snap_mode=snapgrid; + Show_grid=showgrid; } Close_window(); - if ( (clicked_button==2) && (!Snap_mode) ) - Button_Snap_mode(); - Display_cursor(); } diff --git a/buttons.h b/buttons.h index bb2d2187..8622cabe 100644 --- a/buttons.h +++ b/buttons.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/const.h b/const.h index a18ddac7..ad83cca5 100644 --- a/const.h +++ b/const.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud @@ -112,6 +114,7 @@ enum FILE_FORMATS FORMAT_C64, FORMAT_KCF, FORMAT_PAL, + FORMAT_SCR, FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image }; diff --git a/engine.c b/engine.c index b83e91a0..4ce50d7f 100644 --- a/engine.c +++ b/engine.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/engine.h b/engine.h index 14b84244..4af90670 100644 --- a/engine.h +++ b/engine.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/errors.h b/errors.h index 4f1cab97..5fc671ce 100644 --- a/errors.h +++ b/errors.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Adrien Destugues diff --git a/factory.c b/factory.c index e14fd12a..32142429 100644 --- a/factory.c +++ b/factory.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Adrien Destugues @@ -129,7 +131,6 @@ void Draw_script_name(word x, word y, word index, byte highlighted) { T_Fileselector_item * current_item; - DEBUG("draw",index); if (Scripts_list.Nb_elements) { current_item = Get_item_by_index(&Scripts_list, index); diff --git a/factory.h b/factory.h index cefd687c..ff12d081 100644 --- a/factory.h +++ b/factory.h @@ -1 +1,3 @@ +/* vim:expandtab:ts=2 sw=2: +*/ void Button_Brush_Factory(void); diff --git a/fileformats.c b/fileformats.c index ab7c1f51..211367c3 100644 --- a/fileformats.c +++ b/fileformats.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Petter Lindquist diff --git a/filesel.c b/filesel.c index 5759c34d..1c12bb87 100644 --- a/filesel.c +++ b/filesel.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Franck Charlet @@ -1388,7 +1390,7 @@ byte Button_Load_or_Save(byte load, byte image) if(load) { // Determine the type - if(File_exists(Main_filename)) + if(File_exists(Main_filename)) { Selected_type = 0; if(Directory_exists(Main_filename)) Selected_type = 1; @@ -1403,7 +1405,9 @@ byte Button_Load_or_Save(byte load, byte image) if(Directory_exists(Main_filename)) Selected_type = 1; else Selected_type = 0; } - has_clicked_ok=1; + + // Now load immediately, but only if the user exited readline by pressing ENTER + if (Mouse_K == 0) has_clicked_ok = 1; } else { diff --git a/filesel.h b/filesel.h index ba2cc4a5..1064b0b1 100644 --- a/filesel.h +++ b/filesel.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/global.h b/global.h index 32765b6b..2f013869 100644 --- a/global.h +++ b/global.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Franck Charlet diff --git a/graph.c b/graph.c index a7a6870a..a0231fc2 100644 --- a/graph.c +++ b/graph.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Franck Charlet diff --git a/graph.h b/graph.h index 96f12f99..34a6f634 100644 --- a/graph.h +++ b/graph.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007-2008 Adrien Destugues diff --git a/help.c b/help.c index ba4c2c63..f498ab76 100644 --- a/help.c +++ b/help.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/help.h b/help.h index 883df678..14c866d0 100644 --- a/help.h +++ b/help.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/helpfile.h b/helpfile.h index a3938903..cc7bd648 100644 --- a/helpfile.h +++ b/helpfile.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/hotkeys.c b/hotkeys.c index 4e05beb5..01d23d4c 100644 --- a/hotkeys.c +++ b/hotkeys.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/hotkeys.h b/hotkeys.h index b90e4340..380964d5 100644 --- a/hotkeys.h +++ b/hotkeys.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/init.c b/init.c index f00ef5f5..9a33e38a 100644 --- a/init.c +++ b/init.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/init.h b/init.h index 4ef9eeb4..44152a19 100644 --- a/init.h +++ b/init.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/input.c b/input.c index 3f147bb5..ac5d4db9 100644 --- a/input.c +++ b/input.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Franck Charlet diff --git a/input.h b/input.h index c6f68f23..e4564942 100644 --- a/input.h +++ b/input.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/io.c b/io.c index 507700be..e468823b 100644 --- a/io.c +++ b/io.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/io.h b/io.h index f63aa54f..38e556d6 100644 --- a/io.h +++ b/io.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/keyboard.c b/keyboard.c index 5582d931..db96567c 100644 --- a/keyboard.c +++ b/keyboard.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Franck Charlet diff --git a/keyboard.h b/keyboard.h index eca0352e..08787c0e 100644 --- a/keyboard.h +++ b/keyboard.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/libraw2crtc.c b/libraw2crtc.c new file mode 100644 index 00000000..94d502ae --- /dev/null +++ b/libraw2crtc.c @@ -0,0 +1,187 @@ +/* vim:expandtab:ts=2 sw=2: +*/ +/* GFX2CRTC - libraw2crtc.c + * CloudStrife - 20080921 + * Diffusé sous licence libre CeCILL v2 + * Voire LICENCE + */ + +#include +#include +#include + +#include "global.h" + +unsigned short addrCalc(unsigned char vcc, unsigned char rcc, unsigned char hcc, unsigned char cclk, unsigned char r1, unsigned char r12, unsigned char r13) +{ + unsigned short MA; + unsigned short addr; + + //MA = vcc*r1 + hcc + (0x0C)*256; + MA = vcc*r1 + hcc + r12*256 + r13; + addr = cclk | ((MA & 0x03FF) << 1); + addr = addr | ((rcc & 0x07) << 11); + addr = addr | ((MA & 0x3000) << 2); + + return addr; +} + +unsigned char mode0interlace(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)]; +} + +unsigned char mode1interlace(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)]; +} + +unsigned char mode2interlace(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); + return out; +} + +unsigned char mode3interlace(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; +} + +unsigned char (*ptrMode)(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 *outBuffer; + unsigned char *tmpBuffer; + unsigned char *allocationBuffer; + unsigned short minAddr = 0; + unsigned char minAddrIsDefined = 0; + unsigned short maxAddr = 0; + + unsigned char nbPixPerByte; + int y,x; + unsigned char r6; + unsigned short i; + unsigned char *ptrTmp; + unsigned char *ptrOut; + unsigned char vcc; + unsigned char rcc; + unsigned char hcc; + unsigned char cclk; + + switch(mode) + { + case 0: + { + *r1 = (width+3)/4; + nbPixPerByte = 2; + ptrMode = mode0interlace; + break; + } + case 1: + { + *r1 = (width+7)/8; + nbPixPerByte = 4; + ptrMode = mode1interlace; + break; + } + case 2: + { + *r1 = (width+15)/16; + nbPixPerByte = 8; + ptrMode = mode2interlace; + break; + } + case 3: + { + *r1 = (width+3)/4; + nbPixPerByte = 2; + ptrMode = mode3interlace; + break; + } + default: + { + exit(4); + } + } + + tmpBuffer = (unsigned char*)malloc(0xFFFF); + if (tmpBuffer == NULL) + { + printf("Allocation tmpBuffer raté\n"); + exit(4); + } + + allocationBuffer = (unsigned char*)malloc(0xFFFF); + if(allocationBuffer == NULL) + { + printf("Allocation allocationBuffer raté\n"); + exit(4); + } + memset(allocationBuffer, 0, 0xFFFF); + + r6 = height/(r9+1); + + for(vcc = 0; vcc < r6; vcc++) + { + for(rcc = 0; rcc < (r9+1); rcc++) + { + for(hcc = 0; hcc < *r1; hcc++) + { + for(cclk = 0; cclk < 2; cclk++) + { + x = (hcc << 1 | cclk); + y = vcc*(r9+1) + rcc; + *(tmpBuffer + addrCalc(vcc, rcc, hcc, cclk, *r1, r12, r13)) = (*ptrMode)(x,y); + *(allocationBuffer + addrCalc(vcc, rcc, hcc, cclk, *r1, r12, r13)) += 1; + } + } + } + } + + for(i = 0; i < 0xFFFF; i++) + { + if(*(allocationBuffer + i) > 1) + { + printf("Attention : Ecriture multiple a l'adresse mémoire %d\n",i); + } + if(*(allocationBuffer + i) > 0) + { + maxAddr = i; + } + if((*(allocationBuffer + i) == 1) && (minAddrIsDefined == 0)) + { + minAddr = i; + minAddrIsDefined = 1; + } + } + + *outSize = (maxAddr + 1) - minAddr; + + outBuffer = (unsigned char*)malloc((*outSize)); + if (outBuffer == NULL) + { + printf("Allocation outBuffer raté\n"); + exit(4); + } + + ptrTmp = tmpBuffer + minAddr; + ptrOut = outBuffer; + + for(i = minAddr; i <= maxAddr; i++) + { + *(ptrOut++) = *(ptrTmp++); + } + + free(tmpBuffer); + tmpBuffer = NULL; + free(allocationBuffer); + allocationBuffer = NULL; + + return outBuffer; +} diff --git a/libraw2crtc.h b/libraw2crtc.h new file mode 100644 index 00000000..f689043c --- /dev/null +++ b/libraw2crtc.h @@ -0,0 +1,14 @@ +/* vim:expandtab:ts=2 sw=2: +*/ +/* GFX2CRTC - libraw2crtc.h + * CloudStrife - 20080921 + * Diffusé sous licence libre CeCILL v2 + * Voire LICENCE + */ + +#ifndef LIBRAW2CRTC_H +#define LIBRAW2CRTC_H 1 + +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); + +#endif diff --git a/loadsave.c b/loadsave.c index 517f6a6b..e62d9d02 100644 --- a/loadsave.c +++ b/loadsave.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Petter Lindquist @@ -116,6 +118,9 @@ void Test_C64(void); void Load_C64(void); void Save_C64(void); +// -- SCR (Amstrad CPC) +void Save_SCR(void); + // -- PNG ------------------------------------------------------------------- #ifndef __no_pnglib__ void Test_PNG(void); @@ -130,7 +135,7 @@ void Load_SDL_Image(void); void Init_preview(short width,short height,long size,int format,enum PIXEL_RATIO ratio); -// ENUM Name TestFunc LoadFunc SaveFunc Backup Comment Ext Exts +// ENUM Name TestFunc LoadFunc SaveFunc Backup 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, "", "*"}, @@ -140,18 +145,19 @@ T_Format File_formats[NB_KNOWN_FORMATS] = { #endif {FORMAT_BMP, " bmp", Test_BMP, Load_BMP, Save_BMP, 1, 0, 0, "bmp", "bmp"}, {FORMAT_PCX, " pcx", Test_PCX, Load_PCX, Save_PCX, 1, 0, 0, "pcx", "pcx"}, - {FORMAT_PKM, " pkm", Test_PKM, Load_PKM, Save_PKM, 1, 1, 0, "pkm", "pkm"}, + {FORMAT_PKM, " pkm", Test_PKM, Load_PKM, Save_PKM, 0, 1, 0, "pkm", "pkm"}, // Not a backup since it does not save the full palette {FORMAT_LBM, " lbm", Test_LBM, Load_LBM, Save_LBM, 1, 0, 0, "lbm", "lbm;iff"}, {FORMAT_IMG, " img", Test_IMG, Load_IMG, Save_IMG, 1, 0, 0, "img", "img"}, {FORMAT_SCx, " sc?", Test_SCx, Load_SCx, Save_SCx, 1, 0, 0, "sc?", "sci;scq;scf;scn;sco"}, - {FORMAT_PI1, " pi1", Test_PI1, Load_PI1, Save_PI1, 1, 0, 0, "pi1", "pi1"}, - {FORMAT_PC1, " pc1", Test_PC1, Load_PC1, Save_PC1, 1, 0, 0, "pc1", "pc1"}, + {FORMAT_PI1, " pi1", Test_PI1, Load_PI1, Save_PI1, 0, 0, 0, "pi1", "pi1"}, + {FORMAT_PC1, " pc1", Test_PC1, Load_PC1, Save_PC1, 0, 0, 0, "pc1", "pc1"}, {FORMAT_CEL, " cel", Test_CEL, Load_CEL, Save_CEL, 1, 0, 0, "cel", "cel"}, - {FORMAT_NEO, " neo", Test_NEO, Load_NEO, Save_NEO, 1, 0, 0, "neo", "neo"}, + {FORMAT_NEO, " neo", Test_NEO, Load_NEO, Save_NEO, 0, 0, 0, "neo", "neo"}, {FORMAT_KCF, " kcf", Test_KCF, Load_KCF, Save_KCF, 0, 0, 0, "kcf", "kcf"}, {FORMAT_PAL, " pal", Test_PAL, Load_PAL, Save_PAL, 0, 0, 0, "pal", "pal"}, - {FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 1, 1, 0, "c64", "c64;koa"}, - {FORMAT_MISC,"misc.", NULL, NULL, NULL, 1, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"}, + {FORMAT_C64, " c64", Test_C64, Load_C64, Save_C64, 0, 1, 0, "c64", "c64;koa"}, + {FORMAT_SCR, " cpc", NULL, NULL, Save_SCR, 0, 0, 0, "cpc", "cpc;scr"}, + {FORMAT_MISC,"misc.",NULL, NULL, NULL, 1, 0, 0, "", "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"}, }; // Cette variable est alimentée après chargement réussi d'une image. @@ -501,20 +507,6 @@ void Init_preview(short width,short height,long size,int format, enum PIXEL_RATI } - -void Draw_palette_preview(void) -{ - short index; - - if (Pixel_load_function==Pixel_load_in_preview) - for (index=0; index<256; index++) - Window_rectangle(183+(index/16)*7,95+(index&15)*5,5,5,index); - - Update_window_area(183,95,120,80); -} - - - // Calcul du nom complet du fichier void Get_full_filename(char * filename, byte is_colorix_format) { diff --git a/loadsave.h b/loadsave.h index 639be97b..5238321f 100644 --- a/loadsave.h +++ b/loadsave.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues @@ -69,10 +71,10 @@ T_Format * Get_fileformat(byte format); // -- File formats #ifndef __no_pnglib__ -#define NB_KNOWN_FORMATS 18 ///< Total number of known file formats. +#define NB_KNOWN_FORMATS 19 ///< Total number of known file formats. #else // Without pnglib -#define NB_KNOWN_FORMATS 17 ///< Total number of known file formats. +#define NB_KNOWN_FORMATS 18 ///< Total number of known file formats. #endif // This is here and not in fileformats.c because the emergency save uses it... diff --git a/main.c b/main.c index 9b6bad14..9912847f 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/misc.c b/misc.c index a5937a58..440ee099 100644 --- a/misc.c +++ b/misc.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/misc.h b/misc.h index d91f0f74..6465b9e1 100644 --- a/misc.h +++ b/misc.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/miscfileformats.c b/miscfileformats.c index 410d143a..458d9657 100644 --- a/miscfileformats.c +++ b/miscfileformats.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Petter Lindquist @@ -23,34 +25,61 @@ ///@file miscfileformats.c /// Formats that aren't fully saving, either because of palette restrictions or other things +#include "engine.h" +#include "errors.h" #include "global.h" +#include "io.h" +#include "libraw2crtc.h" #include "limits.h" #include "loadsave.h" +#include "misc.h" +#include "sdlscreen.h" #include "struct.h" #include "windows.h" //////////////////////////////////// PAL //////////////////////////////////// +// +void Draw_palette_preview(void) +{ + short index; + + if (Pixel_load_function==Pixel_load_in_preview) + for (index=0; index<256; index++) + Window_rectangle(183+(index/16)*7,95+(index&15)*5,5,5,index); + + Update_window_area(183,95,120,80); +} + + // -- Tester si un fichier est au format PAL -------------------------------- void Test_PAL(void) { - FILE *file; // Fichier du fichier + FILE *file; // Fichier du fichier char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier - long file_size; // Taille du fichier + long file_size; // Taille du fichier - Get_full_filename(filename,0); + Get_full_filename(filename, 0); - File_error=1; + File_error = 1; // Ouverture du fichier - if ((file=fopen(filename, "rb"))) + if ((file = fopen(filename, "rb"))) { // Lecture de la taille du fichier - file_size=File_length_file(file); - fclose(file); + file_size = File_length_file(file); // Le fichier ne peut être au format PAL que si sa taille vaut 768 octets - if (file_size==sizeof(T_Palette)) - File_error=0; + if (file_size == sizeof(T_Palette)) + File_error = 0; + else { + // Sinon c'est peut être un fichier palette ASCII "Jasc" + fread(filename, 1, 8, file); + if (strncmp(filename,"JASC-PAL",8) == 0) + { + File_error = 0; + } + } + fclose(file); } } @@ -69,22 +98,56 @@ void Load_PAL(void) // Ouverture du fichier if ((file=fopen(filename, "rb"))) { - T_Palette palette_64; - // Init_preview(?); // Pas possible... pas d'image... + long file_size = File_length_file(file); + // Le fichier ne peut être au format PAL que si sa taille vaut 768 octets + if (file_size == sizeof(T_Palette)) + { + T_Palette palette_64; + // Init_preview(?); // Pas possible... pas d'image... - // Lecture du fichier dans Main_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(); + // Lecture du fichier dans Main_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(); - // On dessine une preview de la palette (si chargement=preview) - Draw_palette_preview(); - } - else - File_error=2; + // On dessine une preview de la palette (si chargement = preview) + Draw_palette_preview(); + } + else + File_error = 2; + } else { + fread(filename, 1, 8, file); + if (strncmp(filename,"JASC-PAL",8) == 0) + { + int i, n, r, g, b; + fscanf(file, "%d",&n); + if(n != 100) + { + File_error = 2; + fclose(file); + return; + } + // Read color count + fscanf(file, "%d",&n); + 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; + + Set_palette(Main_palette); + Remap_fileselector(); + + // On dessine une preview de la palette (si chargement = preview) + Draw_palette_preview(); + } + } else File_error = 2; + + } // Fermeture du fichier fclose(file); @@ -107,20 +170,12 @@ void Save_PAL(void) File_error=0; // Ouverture du fichier - if ((file=fopen(filename,"wb"))) + if ((file=fopen(filename,"w"))) { - T_Palette palette_64; - memcpy(palette_64,Main_palette,sizeof(T_Palette)); - Palette_256_to_64(palette_64); - // Enregistrement de Main_palette dans le fichier - if (! Write_bytes(file,palette_64,sizeof(T_Palette))) - { - File_error=1; - fclose(file); - remove(filename); - } - else // Ecriture correcte => Fermeture normale du fichier - fclose(file); + 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); } else // Si on n'a pas réussi à ouvrir le fichier, alors il y a eu une erreur { @@ -2483,3 +2538,90 @@ void Save_C64(void) File_error = Save_C64_multi(filename,saveWhat,loadAddr); } + +// SCR (Amstrad CPC) + +void Test_SCR(void) +{ + // 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 + // ok. But if it's not there the pixel data may still be valid. And we can't + // use the filesize as this depends on the screen format. + + // An AMSDOS header would be a good indication but in some cases it may not + // be there +} + +void Load_SCR(void) +{ + // 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 + // emulate the video chip and read the bytes as needed... + // Moreover, the hardware allows the screen to have any size from 8x1 to + // 800x273 pixels, and there is no indication of that in the file besides + // its size. It can also use any of the 3 screen modes. Fortunately this + // last bit of information is stored in the palette file. + // Oh, and BTW, the picture can be offset, and it's even usual to do it, + // because letting 128 pixels unused at the beginning of the file make it a + // lot easier to handle screens using more than 16K of VRam. + // The pixel encoding change with the video mode so we have to know that + // before attempting to load anything... + // As if this wasn't enough, Advanced OCP Art Studio, the reference tool on + // Amstrad, can use RLE packing when saving files, meaning we also have to + // handle that. + + // All this mess enforces us to load (and unpack if needed) the file to a + // temporary 32k buffer before actually decoding it. + + // 1) Seek for a palette + // 2) If palette found get screenmode from there, else ask user + // 3) ask user for screen size (or register values) + // 4) Load color data from palette (if found) + // 5) Close palette + // 6) Open the file + // 7) Run around the screen to untangle the pixeldata + // 8) Close the file +} + +void Save_SCR(void) +{ + // TODO : Add possibility to set R9, R12, R13 values + // TODO : Add OCP packing support + // TODO : Add possibility to include AMSDOS header, with proper loading + // address guessed from r12/r13 values. + + unsigned char* output; + unsigned long outsize; + unsigned char r1; + int cpc_mode; + FILE* file; + char filename[MAX_PATH_CHARACTERS]; + + Get_full_filename(filename,0); + + + switch(Pixel_ratio) + { + case PIXEL_WIDE: + case PIXEL_WIDE2: + cpc_mode = 0; + break; + case PIXEL_TALL: + case PIXEL_TALL2: + cpc_mode = 2; + break; + default: + cpc_mode = 1; + break; + } + + output = raw2crtc(Main_image_width,Main_image_height,cpc_mode,7,&outsize,&r1,0,0); + + file = fopen(filename,"wb"); + Write_bytes(file, output, outsize); + fclose(file); + + free (output); + + File_error = 0; +} diff --git a/mountlist.c b/mountlist.c index 74674df2..36171754 100644 --- a/mountlist.c +++ b/mountlist.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* mountlist.c -- return a list of mounted file systems Copyright (C) 1991, 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, diff --git a/mountlist.h b/mountlist.h index 3a5a3906..7cf87fef 100644 --- a/mountlist.h +++ b/mountlist.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* mountlist.h -- declarations for list of mounted file systems Copyright (C) 1991, 1992, 1998, 2000, 2001, 2002, 2003, 2004, 2005 diff --git a/op_c.c b/op_c.c index 1417a623..28cb68e1 100644 --- a/op_c.c +++ b/op_c.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues @@ -28,6 +30,8 @@ #include "op_c.h" #include "errors.h" +/// Convert RGB to HSL. +/// Both input and output are in the 0..255 range to use in the palette screen void RGB_to_HSL(int r,int g,int b,byte * hr,byte * sr,byte* lr) { double rd,gd,bd,h,s,l,max,min; @@ -37,9 +41,6 @@ void RGB_to_HSL(int r,int g,int b,byte * hr,byte * sr,byte* lr) gd = g / 255.0; bd = b / 255.0; - // compute L -// l=(rd*0.30)+(gd*0.59)+(bd*0.11); - // compute maximum of rd,gd,bd if (rd>=gd) { @@ -97,6 +98,8 @@ void RGB_to_HSL(int r,int g,int b,byte * hr,byte * sr,byte* lr) *sr = (s*255.0); } +/// Convert HSL back to RGB +/// Input and output are all in range 0..255 void HSL_to_RGB(byte h,byte s,byte l, byte* r, byte* g, byte* b) { float rf =0 ,gf = 0,bf = 0; @@ -162,10 +165,14 @@ void HSL_to_RGB(byte h,byte s,byte l, byte* r, byte* g, byte* b) *b = bf * (255); } -///////////////////////////////////////////////////////////////////////////// -///////////////////////////// Méthodes de gestion des tables de conversion // -///////////////////////////////////////////////////////////////////////////// +// Conversion table handlers +// The conversion table is built after a run of the median cut algorithm and is +// used to find the best color index for a given (RGB) color. GIMP avoids +// creating the whole table and only create parts of it when they are actually +// needed. This may or may not be faster +/// Creates a new conversion table +/// params: bumber of bits for R, G, B (precision) T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b) { T_Conversion_table * n; @@ -174,31 +181,34 @@ T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b) n=(T_Conversion_table *)malloc(sizeof(T_Conversion_table)); if (n!=NULL) { - // On recopie les paramŠtres demand‚s + // Copy the passed parameters n->nbb_r=nbb_r; n->nbb_g=nbb_g; n->nbb_b=nbb_b; - // On calcule les autres + // Calculate the others + + // Value ranges (max value actually) n->rng_r=(1<rng_g=(1<rng_b=(1<dec_r=nbb_g+nbb_b; n->dec_g=nbb_b; n->dec_b=0; + + // Reductions (how many bits are lost) n->red_r=8-nbb_r; n->red_g=8-nbb_g; n->red_b=8-nbb_b; - // On tente d'allouer la table + // Allocate the table size=(n->rng_r)*(n->rng_g)*(n->rng_b); - n->table=(byte *)malloc(size); - if (n->table!=NULL) - // C'est bon! - memset(n->table,0,size); // Inutile, mais plus propre - else + n->table=(byte *)calloc(size, 1); + if (n->table == NULL) { - // Table impossible … allouer + // Not enough memory free(n); n=NULL; } @@ -207,27 +217,33 @@ T_Conversion_table * CT_new(int nbb_r,int nbb_g,int nbb_b) return n; } + +/// Delete a conversion table and release its memory void CT_delete(T_Conversion_table * t) { free(t->table); free(t); } + +/// Get the best palette index for an (R, G, B) color byte CT_get(T_Conversion_table * t,int r,int g,int b) { int index; - // On réduit le nombre de bits par couleur + // Reduce the number of bits to the table precision r=(r>>t->red_r); g=(g>>t->red_g); b=(b>>t->red_b); - // On recherche la couleur la plus proche dans la table de conversion + // Find the nearest color index=(r<dec_r) | (g<dec_g) | (b<dec_b); return t->table[index]; } + +/// Set an entry of the table, index (RGB), value i void CT_set(T_Conversion_table * t,int r,int g,int b,byte i) { int index; @@ -237,19 +253,21 @@ void CT_set(T_Conversion_table * t,int r,int g,int b,byte i) } +// Handlers for the occurences tables +// This table is used to count the occurence of an (RGB) pixel value in the +// source 24bit image. These count are then used by the median cut algorithm to +// decide which cluster to split. -///////////////////////////////////////////////////////////////////////////// -/////////////////////////////// M‚thodes de gestion des tables d'occurence // -///////////////////////////////////////////////////////////////////////////// - +/// Initialize an occurence table void OT_init(T_Occurrence_table * t) { int size; size=(t->rng_r)*(t->rng_g)*(t->rng_b)*sizeof(int); - memset(t->table,0,size); // On initialise … 0 + memset(t->table,0,size); // Set it to 0 } +/// Allocate an occurence table for given number of bits T_Occurrence_table * OT_new(int nbb_r,int nbb_g,int nbb_b) { T_Occurrence_table * n; @@ -258,12 +276,12 @@ T_Occurrence_table * OT_new(int nbb_r,int nbb_g,int nbb_b) n=(T_Occurrence_table *)malloc(sizeof(T_Occurrence_table)); if (n!=0) { - // On recopie les paramŠtres demand‚s + // Copy passed parameters n->nbb_r=nbb_r; n->nbb_g=nbb_g; n->nbb_b=nbb_b; - // On calcule les autres + // Compute others n->rng_r=(1<rng_g=(1<rng_b=(1<red_g=8-nbb_g; n->red_b=8-nbb_b; - // On tente d'allouer la table + // Allocate the table size=(n->rng_r)*(n->rng_g)*(n->rng_b)*sizeof(int); - n->table=(int *)malloc(size); - if (n->table!=0) - // C'est bon! On initialise … 0 - OT_init(n); - else + n->table=(int *)calloc(size, 1); + if (n->table == NULL) { - // Table impossible … allouer + // Not enough memory ! free(n); n=0; } @@ -291,31 +306,42 @@ T_Occurrence_table * OT_new(int nbb_r,int nbb_g,int nbb_b) return n; } + +/// Delete a table and free the memory void OT_delete(T_Occurrence_table * t) { free(t->table); free(t); } -int OT_get(T_Occurrence_table * t,int r,int g,int b) + +/// Get number of occurences for a given color +int OT_get(T_Occurrence_table * t, int r, int g, int b) { int index; + // Drop bits as needed index=(r<dec_r) | (g<dec_g) | (b<dec_b); return t->table[index]; } + +/// Add 1 to the count for a color void OT_inc(T_Occurrence_table * t,int r,int g,int b) { int index; + // Drop bits as needed r=(r>>t->red_r); g=(g>>t->red_g); b=(b>>t->red_b); + // Compute the address index=(r<dec_r) | (g<dec_g) | (b<dec_b); t->table[index]++; } + +/// Count the use of each color in a 24bit picture and fill in the table void OT_count_occurrences(T_Occurrence_table* t, T_Bitmap24B image, int size) { T_Bitmap24B ptr; @@ -325,11 +351,13 @@ void OT_count_occurrences(T_Occurrence_table* t, T_Bitmap24B image, int size) OT_inc(t, ptr->R, ptr->G, ptr->B); } + +/// Count the total number of pixels in an occurence table int OT_count_colors(T_Occurrence_table * t) { - int val; // Valeur de retour - int nb; // Nombre de couleurs … tester - int i; // Compteur de couleurs test‚es + int val; // Computed return value + int nb; // Number of colors to test + int i; // Loop index val = 0; nb=(t->rng_r)*(t->rng_g)*(t->rng_b); @@ -341,25 +369,41 @@ int OT_count_colors(T_Occurrence_table * t) } +// Cluster management +// Clusters are boxes in the RGB spaces, defined by 6 corner coordinates : +// Rmax, Rmin, Vmax (or Gmax), Vmin, Rmax, Rmin +// The median cut algorithm start with a single cluster covering the whole +// colorspace then split it in two smaller clusters on the longest axis until +// there are 256 non-empty clusters (with some tricks if the original image +// actually has less than 256 colors) +// Each cluster also store the number of pixels that are inside and the +// rmin, rmax, vmin, vmax, bmin, bmax values are the first/last values that +// actually are used by a pixel in the cluster +// When you split a big cluster there may be some space between the splitting +// plane and the first pixel actually in a cluster -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////// M‚thodes de gestion des clusters // -///////////////////////////////////////////////////////////////////////////// +/// Pack a cluster, ie compute its {r,v,b}{min,max} values void Cluster_pack(T_Cluster * c,T_Occurrence_table * to) { int rmin,rmax,vmin,vmax,bmin,bmax; int r,g,b; - // On cherche les mins et les maxs de chaque composante sur la couverture + // Find min. and max. values actually used for each component in this cluster - // int nbocc; - - // On prédécale tout pour éviter de faire trop de bazar en se forçant à utiliser OT_get, plus rapide + // Pre-shift everything to avoid using OT_Get and be faster. This will only + // work if the occurence table actually has full precision, that is a + // 256^3*sizeof(int) = 64MB table. If your computer has less free ram and + // malloc fails, this will not work at all ! + // GIMP use only 6 bits for G and B components in this table. rmin=c->rmax <<16; rmax=c->rmin << 16; vmin=c->vmax << 8; vmax=c->vmin << 8; bmin=c->bmax; bmax=c->bmin; c->occurences=0; + + // Unoptimized code kept here for documentation purpose because the optimized + // one is unreadable : run over the whole cluster and find the min and max, + // and count the occurences at the same time. /* for (r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) @@ -379,9 +423,9 @@ void Cluster_pack(T_Cluster * c,T_Occurrence_table * to) } */ - // On recherche le minimum et le maximum en parcourant le cluster selon chaque composante, - // ça évite des accès mémoires inutiles, de plus chaque boucle est plus petite que la - // précédente puisqu'on connait une borne supplémentaire + // Optimized version : find the extremums one at a time, so we can reduce the + // area to seek for the next one. Start at the edges of the cluster and go to + // the center until we find a pixel. for(r=c->rmin<<16;r<=c->rmax<<16;r+=1<<16) for(g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) @@ -449,7 +493,8 @@ BMAX: } } ENDCRUSH: - // Il faut quand même parcourir la partie utile du cluster, pour savoir combien il y a d'occurences + // We still need to seek the internal part of the cluster to count pixels + // inside it for(r=rmin;r<=rmax;r+=1<<16) for(g=vmin;g<=vmax;g+=1<<8) for(b=bmin;b<=bmax;b++) @@ -457,11 +502,14 @@ ENDCRUSH: c->occurences+=to->table[r + g + b]; // OT_get } + // Unshift the values and put them in the cluster info c->rmin=rmin>>16; c->rmax=rmax>>16; c->vmin=vmin>>8; c->vmax=vmax>>8; c->bmin=bmin; c->bmax=bmax; - // On regarde la composante qui a la variation la plus grande + // Find the longest axis to know which way to split the cluster + // This multiplications are supposed to improve the result, but may or may not + // work, actually. r=(c->rmax-c->rmin)*299; g=(c->vmax-c->vmin)*587; b=(c->bmax-c->bmin)*114; @@ -496,6 +544,9 @@ ENDCRUSH: } } + +/// Split a cluster on its longest axis. +/// c = source cluster, c1, c2 = output after split void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, T_Occurrence_table * to) { @@ -503,10 +554,12 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, int cumul; int r, g, b; + // Split criterion: each of the cluster will have the same number of pixels limit = c->occurences / 2; cumul = 0; - if (hue == 0) + if (hue == 0) // split on red { + // Run over the cluster until we reach the requested number of pixels for (r = c->rmin<<16; r<=c->rmax<<16; r+=1<<16) { for (g = c->vmin<<8; g<=c->vmax<<8; g+=1<<8) @@ -527,9 +580,11 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, r>>=16; g>>=8; + // We tried to split on red, but found half of the pixels with r = rmin + // so we enforce some split to happen anyway, instead of creating an empty + // c2 and c1 == c if (r==c->rmin) r++; - // R est la valeur de d‚but du 2nd cluster c1->Rmin=c->Rmin; c1->Rmax=r-1; c1->rmin=c->rmin; c1->rmax=r-1; @@ -546,7 +601,7 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, c2->bmin=c->bmin; c2->bmax=c->bmax; } else - if (hue==1) + if (hue==1) // split on green { for (g=c->vmin<<8;g<=c->vmax<<8;g+=1<<8) @@ -570,7 +625,6 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, if (g==c->vmin) g++; - // G est la valeur de d‚but du 2nd cluster c1->Rmin=c->Rmin; c1->Rmax=c->Rmax; c1->rmin=c->rmin; c1->rmax=c->rmax; @@ -586,7 +640,7 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, c2->Bmin=c->Bmin; c2->Bmax=c->Bmax; c2->bmin=c->bmin; c2->bmax=c->bmax; } - else + else // split on blue { for (b=c->bmin;b<=c->bmax;b++) @@ -610,7 +664,6 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, if (b==c->bmin) b++; - // B est la valeur de d‚but du 2nd cluster c1->Rmin=c->Rmin; c1->Rmax=c->Rmax; c1->rmin=c->rmin; c1->rmax=c->rmax; @@ -628,6 +681,8 @@ void Cluster_split(T_Cluster * c, T_Cluster * c1, T_Cluster * c2, int hue, } } + +/// Compute the mean R, G, B (for palette generation) and H, L (for palette sorting) void Cluster_compute_hue(T_Cluster * c,T_Occurrence_table * to) { int cumul_r,cumul_g,cumul_b; @@ -657,10 +712,11 @@ void Cluster_compute_hue(T_Cluster * c,T_Occurrence_table * to) } +// Cluster set management +// A set of clusters in handled as a list, the median cut algorithm pops a +// cluster from the list, split it, and pushes back the two splitted clusters +// until the lit grows to 256 items -///////////////////////////////////////////////////////////////////////////// -//////////////////////////// M‚thodes de gestion des ensembles de clusters // -///////////////////////////////////////////////////////////////////////////// // Debug helper : check if a cluster set has the right count value /* @@ -679,6 +735,7 @@ void CS_Check(T_Cluster_set* cs) */ /// Setup the first cluster before we start the operations +/// This one covers the full palette range void CS_Init(T_Cluster_set * cs, T_Occurrence_table * to) { cs->clusters->Rmin = cs->clusters->rmin = 0; @@ -700,25 +757,23 @@ T_Cluster_set * CS_New(int nbmax, T_Occurrence_table * to) n=(T_Cluster_set *)malloc(sizeof(T_Cluster_set)); if (n != NULL) { - // On recopie les paramŠtres demand‚s + // Copy requested params n->nb_max = OT_count_colors(to); - // On vient de compter le nombre de couleurs existantes, s'il est plus grand - // que 256 on limite à 256 - // (nombre de couleurs voulu au final) + // If the number of colors asked is > 256, we ceil it because we know we + // don't want more if (n->nb_max > nbmax) { n->nb_max = nbmax; } - // On tente d'allouer le premier cluster + // Allocate the first cluster n->clusters=(T_Cluster *)malloc(sizeof(T_Cluster)); if (n->clusters != NULL) - // C'est bon! On initialise CS_Init(n, to); else { - // Table impossible … allouer + // No memory free ! Sorry ! free(n); n = NULL; } @@ -740,12 +795,18 @@ void CS_Delete(T_Cluster_set * cs) free(cs); } + +/// Pop a cluster from the cluster list void CS_Get(T_Cluster_set * cs, T_Cluster * c) { T_Cluster* current = cs->clusters; T_Cluster* prev = NULL; // Search a cluster with at least 2 distinct colors so we can split it + // Clusters are sorted by number of occurences, so a cluster may end up + // with a lot of pixelsand on top of the list, but only one color. We can't + // split it in that case. It should probably be stored on a list of unsplittable + // clusters to avoid running on it again on each iteration. do { if ( (current->rmin < current->rmax) || @@ -771,12 +832,14 @@ void CS_Get(T_Cluster_set * cs, T_Cluster * c) current = NULL; } + +/// Push a cluster in the list void CS_Set(T_Cluster_set * cs,T_Cluster * c) { T_Cluster* current = cs->clusters; T_Cluster* prev = NULL; - // Search the first cluster that is smaller than ours + // Search the first cluster that is smaller than ours (less pixels) while (current && current->occurences > c->occurences) { prev = current; @@ -795,41 +858,44 @@ void CS_Set(T_Cluster_set * cs,T_Cluster * c) cs->nb++; } -// Détermination de la meilleure palette en utilisant l'algo Median Cut : -// 1) On considère l'espace (R,G,B) comme 1 boîte -// 2) On cherche les extrêmes de la boîte en (R,G,B) -// 3) On trie les pixels de l'image selon l'axe le plus long parmi (R,G,B) -// 4) On coupe la boîte en deux au milieu, et on compacte pour que chaque bord -// corresponde bien à un pixel extreme -// 5) On recommence à couper selon le plus grand axe toutes boîtes confondues -// 6) On s'arrête quand on a le nombre de couleurs voulu +/// This is the main median cut algorithm and the function actually called to +/// reduce the palette. We get the number of pixels for each collor in the +/// occurence table and generate the cluster set from it. +// 1) RGB space is a big box +// 2) We seek the pixels with extreme values +// 3) We split the box in 2 parts on its longest axis +// 4) We pack the 2 resulting boxes again to leave no empty space between the box border and the first pixel +// 5) We take the box with the biggest number of pixels inside and we split it again +// 6) Iterate until there are 256 boxes. Associate each of them to its middle color void CS_Generate(T_Cluster_set * cs, T_Occurrence_table * to) { T_Cluster current; T_Cluster Nouveau1; T_Cluster Nouveau2; - // Tant qu'on a moins de 256 clusters + // There are less than 256 boxes while (cs->nbnb_max) { - // On récupère le plus grand cluster + // Get the biggest one CS_Get(cs,¤t); - // On le coupe en deux + // Split it Cluster_split(¤t, &Nouveau1, &Nouveau2, current.plus_large, to); - // On compacte ces deux nouveaux (il peut y avoir un espace entre l'endroit - // de la coupure et les premiers pixels du cluster) + // Pack the 2 new clusters (the split may leave some empty space between the + // box border and the first actual pixel) Cluster_pack(&Nouveau1, to); Cluster_pack(&Nouveau2, to); - // On les remet dans le set + // Put them back in the list CS_Set(cs,&Nouveau1); CS_Set(cs,&Nouveau2); } } + +/// Compute the color associated to each box in the list void CS_Compute_colors(T_Cluster_set * cs, T_Occurrence_table * to) { T_Cluster * c; @@ -838,6 +904,11 @@ void CS_Compute_colors(T_Cluster_set * cs, T_Occurrence_table * to) Cluster_compute_hue(c,to); } + +// We sort the clusters on two criterions to get a somewhat coherent palette. +// TODO : It would be better to do this in one single pass. + +/// Sort the clusters by chrominance value void CS_Sort_by_chrominance(T_Cluster_set * cs) { T_Cluster* nc; @@ -866,10 +937,12 @@ void CS_Sort_by_chrominance(T_Cluster_set * cs) prev = NULL; } - // Put the new list bavk in place + // Put the new list back in place cs->clusters = newlist; } + +/// Sort the clusters by luminance value void CS_Sort_by_luminance(T_Cluster_set * cs) { T_Cluster* nc; @@ -903,6 +976,8 @@ void CS_Sort_by_luminance(T_Cluster_set * cs) cs->clusters = newlist; } + +/// Generates the palette from the clusters, then the conversion table to map (RGB) to a palette index void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette) { int index; @@ -1028,8 +1103,7 @@ void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs) } - - +/// Compute best palette for given picture. T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size, T_Components * palette, int r, int g, int b) { @@ -1038,7 +1112,7 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size, T_Cluster_set * cs; T_Gradient_set * ds; - // Création des éléments nécessaires au calcul de palette optimisée: + // Allocate all the elements to = 0; tc = 0; cs = 0; ds = 0; to = OT_new(r, g, b); @@ -1052,7 +1126,7 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size, return 0; } - // Première étape : on compte les pixels de chaque couleur pour pouvoir trier là dessus + // Count pixels for each color OT_count_occurrences(to, image, size); cs = CS_New(256, to); @@ -1063,13 +1137,13 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size, return 0; } //CS_Check(cs); - // C'est bon, on a pu tout allouer + // Ok, everything was allocated - // On génère les clusters (avec l'algo du median cut) + // Generate the cluster set with median cut algorithm CS_Generate(cs, to); //CS_Check(cs); - // On calcule la teinte de chaque pixel (Luminance et chrominance) + // Compute the color data for each cluster (palette entry + HL) CS_Compute_colors(cs, to); //CS_Check(cs); @@ -1079,15 +1153,13 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size, GS_Generate(ds, cs); GS_Delete(ds); } - // Enfin on trie les clusters (donc les couleurs de la palette) dans un ordre - // sympa : par couleur, et par luminosité pour chaque couleur + // Sort the clusters on L and H to get a nice palette CS_Sort_by_luminance(cs); //CS_Check(cs); CS_Sort_by_chrominance(cs); //CS_Check(cs); - // Enfin on génère la palette et la table de correspondance entre chaque - // couleur 24b et sa couleur palette associée. + // And finally generate the conversion table to map RGB > pal. index CS_Generate_color_table_and_palette(cs, tc, palette); //CS_Check(cs); @@ -1096,6 +1168,8 @@ T_Conversion_table * Optimize_palette(T_Bitmap24B image, int size, return tc; } + +/// Change a value with proper ceiling and flooring int Modified_value(int value,int modif) { value+=modif; @@ -1110,10 +1184,11 @@ int Modified_value(int value,int modif) return value; } + +/// Convert a 24b image to 256 colors (with a given palette and conversion table) +/// This destroys the 24b picture ! +/// Uses floyd steinberg dithering. void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette,T_Conversion_table * tc) -// Cette fonction dégrade au fur et à mesure le bitmap source, donc soit on ne -// s'en ressert pas, soit on passe à la fonction une copie de travail du -// bitmap original. { T_Bitmap24B current; T_Bitmap24B c_plus1; @@ -1205,6 +1280,8 @@ void Convert_24b_bitmap_to_256_Floyd_Steinberg(T_Bitmap256 dest,T_Bitmap24B sour } } + +/// Converts from 24b to 256c without dithering, using given conversion table void Convert_24b_bitmap_to_256_nearest_neighbor(T_Bitmap256 dest, T_Bitmap24B source, int width, int height, __attribute__((unused)) T_Components * palette, T_Conversion_table * tc) @@ -1241,6 +1318,8 @@ void Convert_24b_bitmap_to_256_nearest_neighbor(T_Bitmap256 dest, } +// These are the allowed precisions for all the tables. +// For some of them only the first one may work because of ugly optimizations static const byte precision_24b[]= { 8,8,8, @@ -1257,11 +1336,7 @@ static const byte precision_24b[]= 3,3,2}; -// Convertie avec le plus de précision possible une image 24b en 256c -// Renvoie s'il y a eu une erreur ou pas.. - -// Cette fonction utilise l'algorithme "median cut" (Optimize_palette) pour trouver la palette, et diffuse les erreurs avec floyd-steinberg. - +// Give this one a 24b source, get back the 256c bitmap and its palette int Convert_24b_bitmap_to_256(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette) { T_Conversion_table * table; // table de conversion diff --git a/op_c.h b/op_c.h index 4f12fa30..ead494db 100644 --- a/op_c.h +++ b/op_c.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/operatio.c b/operatio.c index 04e47316..728c4e08 100644 --- a/operatio.c +++ b/operatio.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/operatio.h b/operatio.h index 9bef2eba..97cdde15 100644 --- a/operatio.h +++ b/operatio.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/pages.c b/pages.c index da98467e..00ad3a4f 100644 --- a/pages.c +++ b/pages.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Franck Charlet diff --git a/pages.h b/pages.h index 2e434c50..7ec8658f 100644 --- a/pages.h +++ b/pages.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/palette.c b/palette.c index b6474261..e58ff380 100644 --- a/palette.c +++ b/palette.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/palette.h b/palette.h index e28f280c..65d3e2e7 100644 --- a/palette.h +++ b/palette.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/pversion.c b/pversion.c index 9015041d..c1856498 100644 --- a/pversion.c +++ b/pversion.c @@ -1 +1,3 @@ +/* vim:expandtab:ts=2 sw=2: +*/ char Program_version[]="layers wip"; diff --git a/pxdouble.c b/pxdouble.c index a0758684..99a63f55 100644 --- a/pxdouble.c +++ b/pxdouble.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxdouble.h b/pxdouble.h index 3d8296f8..14810f86 100644 --- a/pxdouble.h +++ b/pxdouble.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxquad.c b/pxquad.c index d7bb35f2..47609320 100644 --- a/pxquad.c +++ b/pxquad.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxquad.h b/pxquad.h index 66ed0713..04f21950 100644 --- a/pxquad.h +++ b/pxquad.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxsimple.c b/pxsimple.c index a9290da7..9cfaff3f 100644 --- a/pxsimple.c +++ b/pxsimple.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxsimple.h b/pxsimple.h index 785a96a5..175d1a65 100644 --- a/pxsimple.h +++ b/pxsimple.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxtall.c b/pxtall.c index 71d923b7..b62a3986 100644 --- a/pxtall.c +++ b/pxtall.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxtall.h b/pxtall.h index 0499cf33..424ec774 100644 --- a/pxtall.h +++ b/pxtall.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxtall2.c b/pxtall2.c index 4393feee..1e45b972 100644 --- a/pxtall2.c +++ b/pxtall2.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxtall2.h b/pxtall2.h index eaf40fe5..478edf9f 100644 --- a/pxtall2.h +++ b/pxtall2.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxtriple.c b/pxtriple.c index fc299cfb..39fb7189 100644 --- a/pxtriple.c +++ b/pxtriple.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxtriple.h b/pxtriple.h index 6e470548..29719cdd 100644 --- a/pxtriple.h +++ b/pxtriple.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxwide.c b/pxwide.c index 2656dd25..e1aa8055 100644 --- a/pxwide.c +++ b/pxwide.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxwide.h b/pxwide.h index b1db7ec4..7ffaf24d 100644 --- a/pxwide.h +++ b/pxwide.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxwide2.c b/pxwide2.c index 498756be..0fcd8104 100644 --- a/pxwide2.c +++ b/pxwide2.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/pxwide2.h b/pxwide2.h index 15dff2d9..d6409e97 100644 --- a/pxwide2.h +++ b/pxwide2.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/readini.c b/readini.c index 7e1b9ef8..66c00678 100644 --- a/readini.c +++ b/readini.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/readini.h b/readini.h index 02188f3d..e55152f3 100644 --- a/readini.h +++ b/readini.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/readline.c b/readline.c index 8f2a509f..80a895cf 100644 --- a/readline.c +++ b/readline.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/readline.h b/readline.h index f76242a3..498fad58 100644 --- a/readline.h +++ b/readline.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/realpath.c b/realpath.c index fa74307e..ca583a15 100644 --- a/realpath.c +++ b/realpath.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ #include #include #include diff --git a/realpath.h b/realpath.h index 72c08e7f..35f625bc 100644 --- a/realpath.h +++ b/realpath.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Adrien Destugues diff --git a/saveini.c b/saveini.c index 543b8124..c97077b8 100644 --- a/saveini.c +++ b/saveini.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/saveini.h b/saveini.h index 93f9647b..c45b38f5 100644 --- a/saveini.h +++ b/saveini.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/sdlscreen.c b/sdlscreen.c index af0a266c..34ca890b 100644 --- a/sdlscreen.c +++ b/sdlscreen.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/sdlscreen.h b/sdlscreen.h index 455865ab..a7b83c2e 100644 --- a/sdlscreen.h +++ b/sdlscreen.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/setup.c b/setup.c index 548af219..b6b0bb98 100644 --- a/setup.c +++ b/setup.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/setup.h b/setup.h index 0fc2e25e..58a22b97 100644 --- a/setup.h +++ b/setup.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Peter Gordon diff --git a/shade.c b/shade.c index 31a41cf4..5b0cc9d6 100644 --- a/shade.c +++ b/shade.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/shade.h b/shade.h index 7f9e23c8..94278e55 100644 --- a/shade.h +++ b/shade.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/special.c b/special.c index 0b0c1ce1..e00ea456 100644 --- a/special.c +++ b/special.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/special.h b/special.h index 8dfa57c0..d28fa68d 100644 --- a/special.h +++ b/special.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues diff --git a/struct.h b/struct.h index b3c6e16f..e229d64d 100644 --- a/struct.h +++ b/struct.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/text.c b/text.c index 76c36313..f465249c 100644 --- a/text.c +++ b/text.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/text.h b/text.h index cb96813a..48b3e20b 100644 --- a/text.h +++ b/text.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud diff --git a/transform.c b/transform.c index 5c77ca64..a4758bfb 100644 --- a/transform.c +++ b/transform.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Yves Rizoud diff --git a/transform.h b/transform.h index 899c4443..26cf28d1 100644 --- a/transform.h +++ b/transform.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2009 Yves Rizoud diff --git a/windows.c b/windows.c index 3eeabb75..a268ff32 100644 --- a/windows.c +++ b/windows.c @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Franck Charlet @@ -914,28 +916,42 @@ void Verbose_error_message(const char * message) { short clicked_button; int line; - int i; - char buffer[36]; // 35 characters + \0 + int last_space; + int nb_char; + char buffer[36]; Open_window(300,160,"Error!"); // Word-wrap the message - for (line=0; line < 10; line++) + for (line=0; line < 12 && *message!='\0'; line++) { - for (i=0;i<35 && *message!='\0';i++) + last_space = -1; + for (nb_char=0; nb_char<35 && message[nb_char]!='\0'; nb_char++) { - if (*message == '\n') + buffer[nb_char]=message[nb_char]; + if (message[nb_char] == ' ') { - message++; + last_space = nb_char; + } + else if (message[nb_char] == '\n') + { + last_space = nb_char; break; } - buffer[i]=*message; - message++; } - buffer[i]='\0'; + // Close line buffer + if (last_space == -1) + last_space = 34; + buffer[last_space]='\0'; + + // Print Print_in_window(10,20+line*8,buffer,MC_Black,MC_Light); - if (*message=='\0') - break; + + // Next line + message=message+last_space+1; + // Strip leading spaces + while (*message == ' ') + message++; } Window_set_normal_button(300/2-20,160-23,40,14,"OK",1,1,SDLK_RETURN); // 1 @@ -1518,15 +1534,22 @@ void Compute_magnifier_data(void) } - -// ------------ Changer le facteur de zoom et tout mettre à jour ------------- +/// Changes magnifier factor and updates everything needed void Change_magnifier_factor(byte factor_index) { - short center_x; - short center_y; + int center_x; + int center_y; - center_x=Main_magnifier_offset_X+(Main_magnifier_width>>1); - center_y=Main_magnifier_offset_Y+(Main_magnifier_height>>1); + // Values that need to be computed before switching to the new zoom factor + if (Cursor_in_menu || !Main_magnifier_mode) + { + center_x=Main_magnifier_offset_X+(Main_magnifier_width>>1); + center_y=Main_magnifier_offset_Y+(Main_magnifier_height>>1); + } else { + // Zoom to cursor + center_x = (Paintbrush_X - Main_magnifier_offset_X) * 65536 / Main_magnifier_width; + center_y = (Paintbrush_Y - Main_magnifier_offset_Y) * 65536 / Main_magnifier_height; + } Main_magnifier_factor=ZOOM_FACTOR[factor_index]; Compute_magnifier_data(); @@ -1535,8 +1558,14 @@ void Change_magnifier_factor(byte factor_index) { // Recalculer le décalage de la loupe // Centrage "brut" de lécran par rapport à la loupe - Main_magnifier_offset_X=center_x-(Main_magnifier_width>>1); - Main_magnifier_offset_Y=center_y-(Main_magnifier_height>>1); + if (Cursor_in_menu) + { + Main_magnifier_offset_X=center_x-(Main_magnifier_width>>1); + Main_magnifier_offset_Y=center_y-(Main_magnifier_height>>1); + } else { + Main_magnifier_offset_X = Paintbrush_X - center_x * Main_magnifier_width / 65536 ; + Main_magnifier_offset_Y = Paintbrush_Y - center_y * Main_magnifier_height / 65536 ; + } // Correction en cas de débordement de l'image if (Main_magnifier_offset_X+Main_magnifier_width>Main_image_width) Main_magnifier_offset_X=Main_image_width-Main_magnifier_width; diff --git a/windows.h b/windows.h index 84563728..d5ccdc37 100644 --- a/windows.h +++ b/windows.h @@ -1,3 +1,5 @@ +/* vim:expandtab:ts=2 sw=2: +*/ /* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007-2008 Adrien Destugues