Merge trunk to the cpcmode5 branch. This gets us a more recent grafx2 with the cpcmode5 drawing. Now to make this mode optional so users can still work in regular mode :)
git-svn-id: svn://pulkomandy.tk/GrafX2/branches/cpcmode5@1719 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
		
							parent
							
								
									4e60f5ad74
								
							
						
					
					
						commit
						eba26aaa96
					
				
							
								
								
									
										121
									
								
								src/Makefile
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								src/Makefile
									
									
									
									
									
								
							@ -1,5 +1,6 @@
 | 
			
		||||
#  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
#  
 | 
			
		||||
#  Copyright 2011 Pawel Góralski
 | 
			
		||||
#  Copyright 2009 Per Olofsson
 | 
			
		||||
#  Copyright 2008 Peter Gordon
 | 
			
		||||
#  Copyright 2008-2010 Yves Rizoud
 | 
			
		||||
@ -25,6 +26,7 @@
 | 
			
		||||
  bindir = $(exec_prefix)/bin
 | 
			
		||||
  datarootdir = $(prefix)/share
 | 
			
		||||
  datadir = $(datarootdir)
 | 
			
		||||
  pixmapdir = $(datarootdir)/icons
 | 
			
		||||
 | 
			
		||||
# Compile with OPTIM=0 to disable gcc optimizations, to enable debug.
 | 
			
		||||
  STRIP = strip
 | 
			
		||||
@ -42,8 +44,8 @@ ifdef COMSPEC
 | 
			
		||||
  RMDIR = rmdir
 | 
			
		||||
  CP = cp
 | 
			
		||||
  BIN = ../bin/grafx2.exe
 | 
			
		||||
  COPT = -W -Wall -Wdeclaration-after-statement -O$(OPTIM) -g -ggdb `sdl-config --cflags` $(TTFCOPT) $(JOYCOPT) $(LUACOPT) $(LAYERCOPT)
 | 
			
		||||
  LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng $(LUALOPT)
 | 
			
		||||
  COPT = -W -Wall -Wdeclaration-after-statement -O$(OPTIM) -g -ggdb `sdl-config --cflags` $(TTFCOPT) $(JOYCOPT) $(VKEYCOPT) $(LUACOPT) $(LAYERCOPT)
 | 
			
		||||
  LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng14 $(LUALOPT)
 | 
			
		||||
  LUALOPT = -llua
 | 
			
		||||
  CC = gcc
 | 
			
		||||
  OBJDIR = ../obj/win32
 | 
			
		||||
@ -52,7 +54,7 @@ ifdef COMSPEC
 | 
			
		||||
  PLATFORMOBJ = $(OBJDIR)/winres.o
 | 
			
		||||
  PLATFORM = win32
 | 
			
		||||
  #some misc files we have to add to the release archive under windows.
 | 
			
		||||
  PLATFORMFILES = bin/SDL.dll bin/SDL_image.dll bin/libpng13.dll bin/zlib1.dll $(TTFLIBS)
 | 
			
		||||
  PLATFORMFILES = bin/SDL.dll bin/SDL_image.dll bin/libpng14-14.dll bin/zlib1.dll $(TTFLIBS)
 | 
			
		||||
  ZIP = zip
 | 
			
		||||
else
 | 
			
		||||
 | 
			
		||||
@ -88,7 +90,7 @@ else
 | 
			
		||||
  FWDIR = /Library/Frameworks
 | 
			
		||||
  SDLCOPT = -arch i386 -I$(FWDIR)/SDL.framework/Headers -I$(FWDIR)/SDL_image.framework/Headers -I$(FWDIR)/SDL_ttf.framework/Headers -D_THREAD_SAFE
 | 
			
		||||
  SDLLOPT = -arch i386 -L/usr/lib -framework SDL -framework SDL_image -framework SDL_ttf -framework Cocoa -framework Carbon -framework OpenGL
 | 
			
		||||
  COPT = -D__macosx__ -D__linux__ -W -Wall -Wdeclaration-after-statement -O$(OPTIM) -std=c99 -c -g $(SDLCOPT) $(TTFCOPT) -I/usr/X11/include
 | 
			
		||||
  COPT = -D_DARWIN_C_SOURCE -D__macosx__ -D__linux__ -W -Wall -Wdeclaration-after-statement -O$(OPTIM) -std=c99 -c -g $(SDLCOPT) $(TTFCOPT) -I/usr/X11/include
 | 
			
		||||
  LOPT = $(SDLLOPT) -L/usr/X11/lib -R/usr/X11/lib -lpng
 | 
			
		||||
  # Use gcc for compiling. Use ncc to build a callgraph and analyze the code.
 | 
			
		||||
  CC = gcc
 | 
			
		||||
@ -152,8 +154,15 @@ else
 | 
			
		||||
    RMDIR = rmdir
 | 
			
		||||
    CP = cp
 | 
			
		||||
    BIN = ../bin/grafx2
 | 
			
		||||
    COPT = -W -Wall -c -g `sdl-config --cflags` $(TTFCOPT) -I/boot/common/include
 | 
			
		||||
    LOPT = `sdl-config --libs` -lSDL_image -lpng -ljpeg -lz $(TTFLOPT)
 | 
			
		||||
      ifeq ($(NOLUA),1)
 | 
			
		||||
        LUACOPT =
 | 
			
		||||
        LUALOPT =
 | 
			
		||||
      else
 | 
			
		||||
            LUACOPT = -D__ENABLE_LUA__
 | 
			
		||||
            LUALOPT = -llua
 | 
			
		||||
      endif
 | 
			
		||||
    COPT = -W -Wall -c -g `sdl-config --cflags` $(TTFCOPT) -I/boot/common/include $(LUACOPT)
 | 
			
		||||
    LOPT = `sdl-config --libs` -lSDL_image -lpng -ljpeg -lz $(TTFLOPT) -lfreetype -lbe $(LUALOPT)
 | 
			
		||||
    CC = gcc
 | 
			
		||||
    OBJDIR = ../obj/haiku
 | 
			
		||||
    ZIP = zip
 | 
			
		||||
@ -197,19 +206,15 @@ else
 | 
			
		||||
      CP = cp
 | 
			
		||||
      ZIP = zip
 | 
			
		||||
      PLATFORMFILES = gfx2.png
 | 
			
		||||
      ifneq ($(ATARICROSS),1)
 | 
			
		||||
      ifeq ($(NOLUA),1)
 | 
			
		||||
        LUACOPT =
 | 
			
		||||
        LUALOPT =
 | 
			
		||||
      else
 | 
			
		||||
        ifeq (`pkg-config --exists lua --print-errors`,"")
 | 
			
		||||
            LUACOPT = `pkg-config lua --cflags`
 | 
			
		||||
            LUALOPT = `pkg-config lua --libs`
 | 
			
		||||
        else
 | 
			
		||||
            LUACOPT = `pkg-config lua5.1 --cflags`
 | 
			
		||||
            LUALOPT = `pkg-config lua5.1 --libs`
 | 
			
		||||
        endif
 | 
			
		||||
            LUACOPT = `pkg-config lua --cflags --silence-errors ||pkg-config lua5.1 --cflags --silence-errors ||pkg-config lua-5.1 --cflags`
 | 
			
		||||
            LUALOPT = `pkg-config lua --libs --silence-errors ||pkg-config lua5.1 --libs --silence-errors ||pkg-config lua-5.1 --libs`
 | 
			
		||||
      endif
 | 
			
		||||
      endif
 | 
			
		||||
 | 
			
		||||
      # These can only be used under linux and maybe freebsd. They allow to compile for the gp2x or to create a windows binary
 | 
			
		||||
      ifdef WIN32CROSS
 | 
			
		||||
        #cross compile a Win32 executable
 | 
			
		||||
@ -225,18 +230,41 @@ else
 | 
			
		||||
        #cross compile an exec for the gp2x
 | 
			
		||||
        CC = /opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/bin/arm-open2x-linux-gcc
 | 
			
		||||
        BIN = ../bin/grafx2.gpe
 | 
			
		||||
        COPT = -W -Wall -Wdeclaration-after-statement -pedantic -std=c99 -static -g -O$(OPTIM) -I/opt/open2x/gcc-4.1.1-glibc-2.3.6/include `/opt/open2x/gcc-4.1.1-glibc-2.3.6/bin/sdl-config --cflags` $(TTFCOPT) -D__GP2X__ $(TTFCOPT) $(JOYCOPT) $(LUACOPT) $(LAYERCOPT)
 | 
			
		||||
        COPT = -W -Wall -Wdeclaration-after-statement -pedantic -std=c99 -static -g -O$(OPTIM) -I/opt/open2x/gcc-4.1.1-glibc-2.3.6/include `/opt/open2x/gcc-4.1.1-glibc-2.3.6/bin/sdl-config --cflags` $(TTFCOPT) -D__GP2X__ $(TTFCOPT) $(JOYCOPT) $(VKEYCOPT) $(LUACOPT) $(LAYERCOPT)
 | 
			
		||||
        LOPT = -static -lSDL_image `/opt/open2x/gcc-4.1.1-glibc-2.3.6/bin/sdl-config --static-libs` -ljpeg -lpng -lz -lm $(TTFLOPT) $(LUALOPT)
 | 
			
		||||
        OBJDIR = ../obj/gp2x
 | 
			
		||||
        NOTTF = 1
 | 
			
		||||
        PLATFORM = gp2x
 | 
			
		||||
        STRIP = /opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/bin/arm-open2x-linux-strip
 | 
			
		||||
        JOYCOPT = -DUSE_JOYSTICK
 | 
			
		||||
 | 
			
		||||
      else ifdef AROS32CROSS
 | 
			
		||||
	#cross compile an Aros 32 bit executable
 | 
			
		||||
        BIN = ../bin/grafx2
 | 
			
		||||
        COPT = -Wall -g `i386-linux-aros-sdl-config --cflags` $(TTFCOPT)
 | 
			
		||||
        LOPT = -lSDL_image `i386-linux-aros-sdl-config --libs` -lpng -ljpeg -lz $(TTFLOPT) -lfreetype2shared
 | 
			
		||||
        CC = i386-aros-gcc
 | 
			
		||||
        OBJDIR = ../obj/aros
 | 
			
		||||
	STRIP = strip --strip-unneeded --remove-section .comment
 | 
			
		||||
        PLATFORM = AROS
 | 
			
		||||
        ZIP = lha
 | 
			
		||||
        ZIPOPT = a
 | 
			
		||||
      else ifdef ATARICROSS
 | 
			
		||||
        #cross compile an exec for atari TOS/MiNT machine
 | 
			
		||||
        CC = m68k-atari-mint-gcc
 | 
			
		||||
        BIN = ../bin/grafx2.ttp
 | 
			
		||||
	LUALOPT = -llua
 | 
			
		||||
        OBJDIR = ../obj/m68k-atari-mint
 | 
			
		||||
        PLATFORM = m68k-atari-mint
 | 
			
		||||
        STRIP = m68k-atari-mint-strip -s 
 | 
			
		||||
	X11LOPT = 
 | 
			
		||||
	COPT = -W -Wall -m68020-60 -fomit-frame-pointer -pedantic -std=c99 -Wdeclaration-after-statement -D__MINT__ -DNO_INLINE_MATH -O$(OPTIM) -c -I$(prefix)/include `$(prefix)/bin/libpng12-config --cflags` `$(prefix)/bin/sdl-config --cflags` $() $(JOYCOPT) $(LAYERCOPT) $(LUACOPT)
 | 
			
		||||
    	LOPT = -static -m68020-60 -lSDL_image `$(prefix)/bin/sdl-config --libs` -L$(prefix)/lib -ltiff -ljpeg `$(prefix)/bin/libpng12-config --libs` -lz -lm $(TTFLOPT) -lfreetype $(LUALOPT) $(LAYERLOPT)
 | 
			
		||||
      else
 | 
			
		||||
 | 
			
		||||
        # Compiles a regular linux executable for the native platform
 | 
			
		||||
        BIN = ../bin/grafx2
 | 
			
		||||
        COPT = -W -Wall -Wdeclaration-after-statement -std=c99 -c -g `sdl-config --cflags` $(TTFCOPT) $(LUACOPT)
 | 
			
		||||
        COPT = -W -Wall -Wdeclaration-after-statement -std=c99 -c -g `sdl-config --cflags` $(TTFCOPT) $(LUACOPT) $(JOYCOPT) $(VKEYCOPT) -O$(OPTIM)
 | 
			
		||||
        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
 | 
			
		||||
@ -258,6 +286,7 @@ endif
 | 
			
		||||
### BUILD SETTINGS are set according to vars set in the platform selection, the "overridable defaults", and environment variables set before launching make
 | 
			
		||||
 | 
			
		||||
#TrueType is optional: make NOTTF=1 to disable support and dependencies.
 | 
			
		||||
ifndef ($(ATARICROSS,1))
 | 
			
		||||
ifeq ($(NOTTF),1)
 | 
			
		||||
  TTFCOPT = -DNOTTF=1
 | 
			
		||||
  TTFLOPT =
 | 
			
		||||
@ -265,10 +294,23 @@ ifeq ($(NOTTF),1)
 | 
			
		||||
  TTFLABEL = -nottf
 | 
			
		||||
else
 | 
			
		||||
  TTFCOPT = 
 | 
			
		||||
  TTFLOPT = -L/usr/local/lib -lSDL_ttf $(X11LOPT)
 | 
			
		||||
  TTFLOPT = -L$(prefix)/lib -lSDL_ttf $(X11LOPT)
 | 
			
		||||
  TTFLIBS = bin/libfreetype-6.dll bin/SDL_ttf.dll
 | 
			
		||||
  TTFLABEL = 
 | 
			
		||||
endif
 | 
			
		||||
else
 | 
			
		||||
ifeq ($(NOTTF),1)
 | 
			
		||||
  TTFCOPT = -DNOTTF=1
 | 
			
		||||
  TTFLOPT =
 | 
			
		||||
  TTFLIBS =
 | 
			
		||||
  TTFLABEL = -nottf
 | 
			
		||||
else
 | 
			
		||||
  TTFCOPT = 
 | 
			
		||||
  TTFLOPT = -L$(prefix)/lib -lSDL_ttf $(X11LOPT)
 | 
			
		||||
  TTFLIBS =  
 | 
			
		||||
  TTFLABEL = 
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
#Lua scripting is optional too
 | 
			
		||||
ifeq ($(NOLUA),1)
 | 
			
		||||
@ -289,6 +331,14 @@ ifeq ($(USE_JOYSTICK),1)
 | 
			
		||||
  JOYCOPT = -DUSE_JOYSTICK
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
#To enable virtual keyboard input (mouse-driven), make VIRT_KEY=1
 | 
			
		||||
#This is automatically enabled on some platforms, but this
 | 
			
		||||
#switch allows you to test the virtual keyboard on any other platform.
 | 
			
		||||
ifeq ($(VIRT_KEY),1)
 | 
			
		||||
  VKEYCOPT = -DVIRT_KEY
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#To speed up rendering, can disable the layered editing
 | 
			
		||||
# with NOLAYERS=1
 | 
			
		||||
ifeq ($(NOLAYERS),1)
 | 
			
		||||
@ -304,11 +354,16 @@ endif
 | 
			
		||||
# 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 $(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
 | 
			
		||||
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 ../share/grafx2/skins/skin_Aurora.png ../share/grafx2/skins/skin_Clax3.gif ../share/grafx2/skins/skin_Clax2.gif ../share/grafx2/skins/skin_Clax4.gif
 | 
			
		||||
 | 
			
		||||
SCRIPT_FILES1 = ../share/grafx2/scripts/bru_db_Amigaball.lua ../share/grafx2/scripts/bru_db_ColorSphere.lua ../share/grafx2/scripts/bru_db_FindAA.lua ../share/grafx2/scripts/bru_db_Fisheye.lua ../share/grafx2/scripts/bru_db_GrayscaleAvg.lua ../share/grafx2/scripts/bru_db_GrayscaleDesat.lua ../share/grafx2/scripts/bru_db_Halfsmooth.lua ../share/grafx2/scripts/bru_db_Mandelbrot.lua ../share/grafx2/scripts/bru_db_Waves.lua ../share/grafx2/scripts/pal_db_Desaturate.lua ../share/grafx2/scripts/pal_db_ExpandColors.lua ../share/grafx2/scripts/pal_db_FillColorCube.lua ../share/grafx2/scripts/pal_db_InvertedRGB.lua ../share/grafx2/scripts/pal_db_Set3bit.lua ../share/grafx2/scripts/pal_db_Set6bit.lua ../share/grafx2/scripts/pal_db_SetC64Palette.lua ../share/grafx2/scripts/pal_db_ShiftHue.lua ../share/grafx2/scripts/pic_db_Pic2isometric.lua ../share/grafx2/scripts/pic_db_Rainbow-Dark2Bright.lua ../share/grafx2/scripts/pic_db_SierpinskyCarpet.lua
 | 
			
		||||
SCRIPT_FILES2 = ../share/grafx2/scripts/pic_db_SierpinskyTriangle.lua ../share/grafx2/scripts/pic_ni_Colorspace12bit.lua ../share/grafx2/scripts/pic_ni_Colorspace15bit.lua ../share/grafx2/scripts/pic_ni_Colorspace18bit.lua ../share/grafx2/scripts/pic_ni_GlassGridFilter.lua ../share/grafx2/scripts/pic_ni_Grid8.lua ../share/grafx2/scripts/pic_ni_Grid8red.lua ../share/grafx2/scripts/pic_ni_GridIso.lua ../share/grafx2/scripts/pic_ni_PaletteX1.lua ../share/grafx2/scripts/pic_ni_PaletteX8.lua ../share/grafx2/scripts/scn_db_RemapImage2RGB.lua ../share/grafx2/scripts/scn_db_RemapImage2RGB_ed.lua ../share/grafx2/scripts/scn_db_RemapImageTo3bitPal.lua
 | 
			
		||||
SCRIPT_FILES1= SCRIPT_FILES1 SCRIPT_FILES2
 | 
			
		||||
SCRIPT_FILES2 = ../share/grafx2/scripts/pic_db_SierpinskyTriangle.lua ../share/grafx2/scripts/pic_ni_GlassGridFilter.lua ../share/grafx2/scripts/scn_db_RemapImage2RGB.lua ../share/grafx2/scripts/scn_db_RemapImage2RGB_ed.lua ../share/grafx2/scripts/scn_db_RemapImageTo3bitPal.lua
 | 
			
		||||
SCRIPT_FILES= $(SCRIPT_FILES1) $(SCRIPT_FILES2)
 | 
			
		||||
 | 
			
		||||
SCRIPTLIB_FILES = ../share/grafx2/scripts/libs/memory.lua
 | 
			
		||||
 | 
			
		||||
FONT_FILES = ../share/grafx2/fonts/8pxfont.png ../share/grafx2/fonts/Tuffy.ttf ../share/grafx2/fonts/PF_Arma_5__.png ../share/grafx2/fonts/PF_Easta_7_.png ../share/grafx2/fonts/PF_Easta_7__.png ../share/grafx2/fonts/PF_Ronda_7__.png ../share/grafx2/fonts/PF_Tempesta_5.png ../share/grafx2/fonts/PF_Tempesta_5_.png ../share/grafx2/fonts/PF_Tempesta_5__.png ../share/grafx2/fonts/PF_Tempesta_5___.png ../share/grafx2/fonts/PF_Tempesta_7.png ../share/grafx2/fonts/PF_Tempesta_7_.png ../share/grafx2/fonts/PF_Tempesta_7__.png ../share/grafx2/fonts/PF_Tempesta_7___.png ../share/grafx2/fonts/PF_Westa_7_.png ../share/grafx2/fonts/PF_Westa_7__.png
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ifeq ($(PLATFORM),Darwin)
 | 
			
		||||
all : $(MACAPPEXE)
 | 
			
		||||
@ -316,11 +371,11 @@ $(MACAPPEXE) : $(BIN)
 | 
			
		||||
	rm -rf Grafx2.app
 | 
			
		||||
	mkdir -p Grafx2.app Grafx2.app/Contents Grafx2.app/Contents/Frameworks Grafx2.app/Contents/MacOS Grafx2.app/Contents/Resources
 | 
			
		||||
	echo 'APPL????' > Grafx2.app/Contents/PkgInfo
 | 
			
		||||
	cp Info.plist Grafx2.app/Contents
 | 
			
		||||
	cp ../Info.plist Grafx2.app/Contents
 | 
			
		||||
	cp -r English.lproj Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -r fonts Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -r skins Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -r gfx2def.ini Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -r ../share/grafx2/fonts Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -r ../share/grafx2/skins Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -r ../share/grafx2/gfx2def.ini Grafx2.app/Contents/Resources
 | 
			
		||||
	cp -Rp $(FWDIR)/SDL.framework Grafx2.app/Contents/Frameworks
 | 
			
		||||
	cp -Rp $(FWDIR)/SDL_image.framework Grafx2.app/Contents/Frameworks
 | 
			
		||||
	cp -Rp $(FWDIR)/SDL_ttf.framework Grafx2.app/Contents/Frameworks
 | 
			
		||||
@ -341,9 +396,9 @@ ziprelease: version $(BIN) release
 | 
			
		||||
	echo `sed "s/.*=\"\(.*\)\";/\1/" pversion.c`.`svnversion` | tr " :" "_-" | sed -e "s/\(wip\)\\./\1/I" > $(OBJDIR)/versiontag
 | 
			
		||||
 | 
			
		||||
	tar cvzf "../src-`cat $(OBJDIR)/versiontag`.tgz" --strip=1 ../src/*.c ../src/*.h ../src/Makefile ../src/Makefile.dep ../src/gfx2.ico 
 | 
			
		||||
	cd .. && $(ZIP) $(ZIPOPT) "grafx2-`cat $(OBJDIR:../%=%)/versiontag`$(TTFLABEL)-$(PLATFORM).$(ZIP)" $(BIN:../%=%) share/grafx2/gfx2def.ini $(SCRIPT_FILES:../%=%) $(SKIN_FILES:../%=%) share/grafx2/gfx2.gif share/icons/grafx2.svg doc/README.txt doc/COMPILING.txt doc/gpl-2.0.txt share/grafx2/fonts/8pxfont.png doc/README-zlib1.txt doc/README-SDL.txt doc/README-SDL_image.txt doc/README-SDL_ttf.txt doc/README-lua.txt share/grafx2/fonts/Tuffy.ttf src-`cat $(OBJDIR:../%=%)/versiontag`.tgz $(PLATFORMFILES:../%=%)
 | 
			
		||||
	cd .. && $(ZIP) $(ZIPOPT) "grafx2-`cat $(OBJDIR:../%=%)/versiontag`$(TTFLABEL)-$(PLATFORM).$(ZIP)" $(BIN:../%=%) share/grafx2/gfx2def.ini $(SCRIPT_FILES:../%=%) $(SCRIPTLIB_FILES:../%=%) $(SKIN_FILES:../%=%) share/grafx2/gfx2.gif share/icons/grafx2.svg doc/README.txt doc/COMPILING.txt doc/gpl-2.0.txt doc/PF_fonts.txt $(FONT_FILES:../%=%) doc/README-zlib1.txt doc/README-SDL.txt doc/README-SDL_image.txt doc/README-SDL_ttf.txt doc/README-lua.txt src-`cat $(OBJDIR:../%=%)/versiontag`.tgz $(PLATFORMFILES:../%=%)
 | 
			
		||||
	$(DELCOMMAND) "../src-`cat $(OBJDIR)/versiontag`.tgz"
 | 
			
		||||
	tar cvzf "../grafx2-`cat $(OBJDIR)/versiontag`$(TTFLABEL)-src.tgz" --strip=1 --transform 's,^,grafx2/,g' ../src/*.c ../src/*.h ../src/Makefile ../src/Makefile.dep ../share/grafx2/gfx2def.ini $(SCRIPT_FILES) $(SKIN_FILES) ../src/gfx2.ico ../share/grafx2/gfx2.gif ../share/icons/grafx2.svg ../doc/README.txt ../doc/COMPILING.txt ../doc/gpl-2.0.txt ../misc/unix/grafx2.1 ../misc/unix/grafx2.xpm ../misc/unix/grafx2.desktop ../share/grafx2/fonts/8pxfont.png ../share/grafx2/fonts/Tuffy.ttf
 | 
			
		||||
	tar cvzf "../grafx2-`cat $(OBJDIR)/versiontag`$(TTFLABEL)-src.tgz" --strip=1 --transform 's,^,grafx2/,g' ../src/*.c ../src/*.h ../src/Makefile ../src/Makefile.dep ../share/grafx2/gfx2def.ini $(SCRIPT_FILES) $(SCRIPTLIB_FILES) $(SKIN_FILES) ../src/gfx2.ico ../share/grafx2/gfx2.gif ../share/icons/grafx2.svg ../doc/README.txt ../doc/COMPILING.txt ../doc/gpl-2.0.txt ../doc/PF_fonts.txt ../misc/unix/grafx2.1 ../misc/unix/grafx2.xpm ../misc/unix/grafx2.desktop $(FONT_FILES)
 | 
			
		||||
	$(DELCOMMAND) "$(OBJDIR)/versiontag"
 | 
			
		||||
 | 
			
		||||
testsed :
 | 
			
		||||
@ -400,8 +455,9 @@ install : $(BIN)
 | 
			
		||||
	test -d $(DESTDIR)$(datadir)/grafx2/fonts || $(MKDIR) $(DESTDIR)$(datadir)/grafx2/fonts
 | 
			
		||||
	test -d $(DESTDIR)$(datadir)/grafx2/skins || $(MKDIR) $(DESTDIR)$(datadir)/grafx2/skins
 | 
			
		||||
	test -d $(DESTDIR)$(datadir)/grafx2/scripts || $(MKDIR) $(DESTDIR)$(datadir)/grafx2/scripts
 | 
			
		||||
	test -d $(DESTDIR)$(datadir)/grafx2/scripts/libs || $(MKDIR) $(DESTDIR)$(datadir)/grafx2/scripts/libs
 | 
			
		||||
	test -d $(DESTDIR)$(datadir)/applications || $(MKDIR) $(DESTDIR)$(datadir)/applications
 | 
			
		||||
	test -d $(DESTDIR)$(datadir)/icons || $(MKDIR) $(DESTDIR)$(datadir)/icons
 | 
			
		||||
	test -d $(DESTDIR)$(pixmapdir) || $(MKDIR) $(DESTDIR)$(pixmapdir)
 | 
			
		||||
	# Copy files
 | 
			
		||||
	$(CP) $(BIN) $(DESTDIR)$(bindir)
 | 
			
		||||
	$(CP) ../share/grafx2/gfx2def.ini $(DESTDIR)$(datadir)/grafx2/
 | 
			
		||||
@ -409,10 +465,11 @@ install : $(BIN)
 | 
			
		||||
	$(CP) ../share/grafx2/fonts/* $(DESTDIR)$(datadir)/grafx2/fonts/
 | 
			
		||||
	$(CP) $(SKIN_FILES) $(DESTDIR)$(datadir)/grafx2/skins/
 | 
			
		||||
	$(CP) $(SCRIPT_FILES) $(DESTDIR)$(datadir)/grafx2/scripts/
 | 
			
		||||
	$(CP) $(SCRIPTLIB_FILES) $(DESTDIR)$(datadir)/grafx2/scripts/libs/
 | 
			
		||||
	# Icon and desktop file for debian
 | 
			
		||||
	$(CP) ../misc/unix/grafx2.desktop $(DESTDIR)$(datadir)/applications/
 | 
			
		||||
	$(CP) ../misc/unix/grafx2.xpm $(DESTDIR)$(datadir)/icons/
 | 
			
		||||
	$(CP) ../share/icons/grafx2.svg $(DESTDIR)$(datadir)/icons/
 | 
			
		||||
	$(CP) ../misc/unix/grafx2.xpm $(DESTDIR)$(pixmapdir)
 | 
			
		||||
	$(CP) ../share/icons/grafx2.svg $(DESTDIR)$(pixmapdir)
 | 
			
		||||
	@echo Install complete
 | 
			
		||||
  
 | 
			
		||||
# Linux uninstallation of the program
 | 
			
		||||
@ -424,13 +481,15 @@ uninstall :
 | 
			
		||||
	$(if $(wildcard $(DESTDIR)$(datadir)/grafx2/fonts),,$(RMDIR) $(DESTDIR)$(datadir)/grafx2/fonts)
 | 
			
		||||
	$(DELCOMMAND) $(SKIN_FILES:../share%=$(DESTDIR)$(datadir)%)
 | 
			
		||||
	$(if $(wildcard $(DESTDIR)$(datadir)/grafx2/skins),,$(RMDIR) $(DESTDIR)$(datadir)/grafx2/skins)
 | 
			
		||||
	$(DELCOMMAND) $(SCRIPTLIB_FILES:../share%=$(DESTDIR)$(datadir)%)
 | 
			
		||||
	$(if $(wildcard $(DESTDIR)$(datadir)/grafx2/scripts/libs),,$(RMDIR) $(DESTDIR)$(datadir)/grafx2/scripts/libs)
 | 
			
		||||
	$(DELCOMMAND) $(SCRIPT_FILES:../share%=$(DESTDIR)$(datadir)%)
 | 
			
		||||
	$(if $(wildcard $(DESTDIR)$(datadir)/grafx2/scripts),,$(RMDIR) $(DESTDIR)$(datadir)/grafx2/scripts)
 | 
			
		||||
	$(if $(wildcard $(DESTDIR)$(datadir)/grafx2),,$(RMDIR) $(DESTDIR)$(datadir)/grafx2)
 | 
			
		||||
	# Icon and desktop file for debian
 | 
			
		||||
	$(DELCOMMAND) $(DESTDIR)$(datadir)/applications/grafx2.desktop
 | 
			
		||||
	$(DELCOMMAND) $(DESTDIR)$(datadir)/icons/grafx2.xpm
 | 
			
		||||
	$(DELCOMMAND) $(DESTDIR)$(datadir)/icons/grafx2.svg
 | 
			
		||||
	$(DELCOMMAND) $(DESTDIR)$(pixmapdir)/grafx2.xpm
 | 
			
		||||
	$(DELCOMMAND) $(DESTDIR)$(pixmapdir)/grafx2.svg
 | 
			
		||||
	@echo Uninstall complete
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
$(OBJDIR)/SFont.o: SFont.c SFont.h
 | 
			
		||||
$(OBJDIR)/brush.o: brush.c global.h struct.h const.h graph.h misc.h errors.h \
 | 
			
		||||
 windows.h sdlscreen.h brush.h
 | 
			
		||||
$(OBJDIR)/brush_ops.o: brush_ops.c brush.h struct.h const.h buttons.h engine.h \
 | 
			
		||||
@ -5,12 +6,13 @@ $(OBJDIR)/brush_ops.o: brush_ops.c brush.h struct.h const.h buttons.h engine.h \
 | 
			
		||||
$(OBJDIR)/buttons.o: buttons.c const.h struct.h global.h misc.h graph.h engine.h \
 | 
			
		||||
 readline.h filesel.h loadsave.h init.h buttons.h operatio.h pages.h \
 | 
			
		||||
 palette.h errors.h readini.h saveini.h shade.h io.h help.h text.h \
 | 
			
		||||
 sdlscreen.h windows.h brush.h input.h special.h
 | 
			
		||||
 sdlscreen.h windows.h brush.h input.h special.h setup.h
 | 
			
		||||
$(OBJDIR)/buttons_effects.o: buttons_effects.c buttons.h struct.h const.h engine.h \
 | 
			
		||||
 global.h graph.h help.h input.h misc.h readline.h sdlscreen.h windows.h
 | 
			
		||||
 global.h graph.h help.h input.h misc.h readline.h sdlscreen.h windows.h \
 | 
			
		||||
 brush.h
 | 
			
		||||
$(OBJDIR)/engine.o: engine.c const.h struct.h global.h graph.h misc.h special.h \
 | 
			
		||||
 buttons.h operatio.h shade.h errors.h sdlscreen.h windows.h brush.h \
 | 
			
		||||
 input.h engine.h pages.h layers.h
 | 
			
		||||
 input.h engine.h pages.h layers.h factory.h loadsave.h io.h
 | 
			
		||||
$(OBJDIR)/factory.o: factory.c brush.h struct.h const.h buttons.h engine.h errors.h \
 | 
			
		||||
 filesel.h loadsave.h global.h graph.h io.h misc.h pages.h readline.h \
 | 
			
		||||
 sdlscreen.h windows.h palette.h input.h help.h
 | 
			
		||||
@ -21,7 +23,8 @@ $(OBJDIR)/filesel.o: filesel.c const.h struct.h global.h misc.h errors.h io.h \
 | 
			
		||||
 help.h filesel.h
 | 
			
		||||
$(OBJDIR)/graph.o: graph.c global.h struct.h const.h engine.h buttons.h pages.h \
 | 
			
		||||
 errors.h sdlscreen.h graph.h misc.h pxsimple.h pxtall.h pxwide.h \
 | 
			
		||||
 pxdouble.h pxtriple.h pxwide2.h pxtall2.h pxquad.h windows.h input.h
 | 
			
		||||
 pxdouble.h pxtriple.h pxwide2.h pxtall2.h pxquad.h windows.h input.h \
 | 
			
		||||
 brush.h
 | 
			
		||||
$(OBJDIR)/help.o: help.c const.h struct.h global.h misc.h engine.h helpfile.h \
 | 
			
		||||
 help.h sdlscreen.h text.h keyboard.h windows.h input.h hotkeys.h \
 | 
			
		||||
 errors.h pages.h
 | 
			
		||||
@ -29,9 +32,9 @@ $(OBJDIR)/hotkeys.o: hotkeys.c struct.h const.h global.h hotkeys.h
 | 
			
		||||
$(OBJDIR)/init.o: init.c buttons.h struct.h const.h errors.h global.h graph.h \
 | 
			
		||||
 init.h io.h factory.h help.h hotkeys.h keyboard.h loadsave.h misc.h \
 | 
			
		||||
 mountlist.h operatio.h palette.h sdlscreen.h setup.h transform.h \
 | 
			
		||||
 windows.h layers.h
 | 
			
		||||
 windows.h layers.h special.h
 | 
			
		||||
$(OBJDIR)/input.o: input.c global.h struct.h const.h keyboard.h sdlscreen.h \
 | 
			
		||||
 windows.h errors.h misc.h input.h
 | 
			
		||||
 windows.h errors.h misc.h buttons.h input.h loadsave.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)/layers.o: layers.c const.h struct.h global.h windows.h engine.h pages.h \
 | 
			
		||||
@ -39,18 +42,20 @@ $(OBJDIR)/layers.o: layers.c const.h struct.h global.h windows.h engine.h pages.
 | 
			
		||||
$(OBJDIR)/libraw2crtc.o: libraw2crtc.c const.h global.h struct.h loadsave.h
 | 
			
		||||
$(OBJDIR)/loadsave.o: loadsave.c buttons.h struct.h const.h errors.h global.h io.h \
 | 
			
		||||
 loadsave.h misc.h graph.h op_c.h pages.h palette.h sdlscreen.h windows.h \
 | 
			
		||||
 engine.h
 | 
			
		||||
 engine.h brush.h setup.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
 | 
			
		||||
 io.h text.h setup.h windows.h brush.h palette.h realpath.h input.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 graph.h pages.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 mountlist.h
 | 
			
		||||
$(OBJDIR)/op_c.o: op_c.c op_c.h struct.h const.h errors.h
 | 
			
		||||
$(OBJDIR)/mountlist.o: mountlist.c
 | 
			
		||||
$(OBJDIR)/op_c.o: op_c.c op_c.h struct.h const.h errors.h global.h engine.h \
 | 
			
		||||
 windows.h
 | 
			
		||||
$(OBJDIR)/operatio.o: operatio.c const.h struct.h global.h misc.h engine.h graph.h \
 | 
			
		||||
 operatio.h buttons.h pages.h errors.h sdlscreen.h brush.h windows.h
 | 
			
		||||
 operatio.h buttons.h pages.h errors.h sdlscreen.h brush.h windows.h \
 | 
			
		||||
 input.h
 | 
			
		||||
$(OBJDIR)/pages.o: pages.c global.h struct.h const.h pages.h errors.h loadsave.h \
 | 
			
		||||
 misc.h windows.h
 | 
			
		||||
$(OBJDIR)/palette.o: palette.c const.h struct.h global.h misc.h engine.h readline.h \
 | 
			
		||||
@ -63,34 +68,35 @@ $(OBJDIR)/pxquad.o: pxquad.c global.h struct.h const.h sdlscreen.h misc.h graph.
 | 
			
		||||
 pxquad.h
 | 
			
		||||
$(OBJDIR)/pxsimple.o: pxsimple.c global.h struct.h const.h sdlscreen.h misc.h \
 | 
			
		||||
 graph.h pxsimple.h
 | 
			
		||||
$(OBJDIR)/pxtall2.o: pxtall2.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
 | 
			
		||||
 pxtall2.h
 | 
			
		||||
$(OBJDIR)/pxtall.o: pxtall.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
 | 
			
		||||
 pxtall.h pxsimple.h
 | 
			
		||||
$(OBJDIR)/pxtall2.o: pxtall2.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
 | 
			
		||||
 pxtall2.h
 | 
			
		||||
$(OBJDIR)/pxtriple.o: pxtriple.c global.h struct.h const.h sdlscreen.h misc.h \
 | 
			
		||||
 graph.h pxtriple.h
 | 
			
		||||
$(OBJDIR)/pxwide2.o: pxwide2.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
 | 
			
		||||
 pxwide2.h
 | 
			
		||||
$(OBJDIR)/pxwide.o: pxwide.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
 | 
			
		||||
 pxwide.h
 | 
			
		||||
$(OBJDIR)/readini.o: readini.c const.h errors.h global.h struct.h misc.h readini.h
 | 
			
		||||
$(OBJDIR)/pxwide2.o: pxwide2.c global.h struct.h const.h sdlscreen.h misc.h graph.h \
 | 
			
		||||
 pxwide2.h
 | 
			
		||||
$(OBJDIR)/readini.o: readini.c const.h errors.h global.h struct.h misc.h readini.h \
 | 
			
		||||
 setup.h
 | 
			
		||||
$(OBJDIR)/readline.o: readline.c const.h struct.h global.h misc.h errors.h \
 | 
			
		||||
 sdlscreen.h readline.h windows.h input.h
 | 
			
		||||
$(OBJDIR)/realpath.o: realpath.c
 | 
			
		||||
$(OBJDIR)/saveini.o: saveini.c const.h global.h struct.h readini.h io.h errors.h \
 | 
			
		||||
 misc.h saveini.h
 | 
			
		||||
 misc.h saveini.h setup.h
 | 
			
		||||
$(OBJDIR)/sdlscreen.o: sdlscreen.c global.h struct.h const.h sdlscreen.h errors.h \
 | 
			
		||||
 misc.h
 | 
			
		||||
$(OBJDIR)/setup.o: setup.c struct.h const.h io.h setup.h
 | 
			
		||||
$(OBJDIR)/SFont.o: SFont.c SFont.h
 | 
			
		||||
$(OBJDIR)/shade.o: shade.c global.h struct.h const.h graph.h engine.h errors.h \
 | 
			
		||||
 misc.h readline.h help.h sdlscreen.h windows.h input.h shade.h
 | 
			
		||||
$(OBJDIR)/special.o: special.c const.h struct.h global.h graph.h engine.h windows.h \
 | 
			
		||||
 special.h pages.h misc.h buttons.h
 | 
			
		||||
$(OBJDIR)/text.o: text.c SFont.h struct.h const.h global.h sdlscreen.h io.h \
 | 
			
		||||
 errors.h
 | 
			
		||||
 errors.h windows.h misc.h setup.h
 | 
			
		||||
$(OBJDIR)/tiles.o: tiles.c
 | 
			
		||||
$(OBJDIR)/transform.o: transform.c global.h struct.h const.h transform.h engine.h \
 | 
			
		||||
 sdlscreen.h windows.h input.h help.h misc.h readline.h buttons.h pages.h
 | 
			
		||||
$(OBJDIR)/version.o: version.c
 | 
			
		||||
$(OBJDIR)/windows.o: windows.c windows.h struct.h const.h engine.h errors.h \
 | 
			
		||||
 global.h graph.h input.h misc.h readline.h sdlscreen.h
 | 
			
		||||
 global.h graph.h input.h misc.h op_c.h readline.h sdlscreen.h palette.h
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								src/SFont.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/SFont.c
									
									
									
									
									
								
							@ -69,7 +69,7 @@ static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
 | 
			
		||||
 | 
			
		||||
SFont_Font* SFont_InitFont(SDL_Surface* Surface)
 | 
			
		||||
{
 | 
			
		||||
    int x = 0, i = 0;
 | 
			
		||||
    int x = 0, i = 33;
 | 
			
		||||
    Uint32 pixel;
 | 
			
		||||
    SFont_Font* Font;
 | 
			
		||||
    Uint32 pink;
 | 
			
		||||
@ -78,21 +78,42 @@ SFont_Font* SFont_InitFont(SDL_Surface* Surface)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    Font = (SFont_Font *) malloc(sizeof(SFont_Font));
 | 
			
		||||
    memset(Font, 0, sizeof(SFont_Font));
 | 
			
		||||
    
 | 
			
		||||
    Font->Surface = Surface;
 | 
			
		||||
 | 
			
		||||
    SDL_LockSurface(Surface);
 | 
			
		||||
 | 
			
		||||
    pink = SDL_MapRGB(Surface->format, 255, 0, 255);
 | 
			
		||||
    pink = GetPixel(Surface, 0, 0);
 | 
			
		||||
    while (x < Surface->w) {
 | 
			
		||||
        if (GetPixel(Surface, x, 0) == pink) { 
 | 
			
		||||
            Font->CharPos[i++]=x;
 | 
			
		||||
            while((x < Surface->w) && (GetPixel(Surface, x, 0)== pink))
 | 
			
		||||
        if (GetPixel(Surface, x, 0) != pink) { 
 | 
			
		||||
            Font->CharBegin[i]=x;
 | 
			
		||||
            while((x < Surface->w) && (GetPixel(Surface, x, 0)!= pink))
 | 
			
		||||
                x++;
 | 
			
		||||
            Font->CharPos[i++]=x;
 | 
			
		||||
            Font->CharWidth[i]=x-Font->CharBegin[i];
 | 
			
		||||
            i++;
 | 
			
		||||
        }
 | 
			
		||||
        x++;
 | 
			
		||||
    }
 | 
			
		||||
    Font->MaxPos = x-1;
 | 
			
		||||
    
 | 
			
		||||
    // Create lowercase characters, if not present
 | 
			
		||||
    for (i=0; i <26; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (Font->CharWidth['a'+i]==0)
 | 
			
		||||
      {
 | 
			
		||||
        Font->CharBegin['a'+i]=Font->CharBegin['A'+i];
 | 
			
		||||
        Font->CharWidth['a'+i]=Font->CharWidth['A'+i];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Determine space width.    
 | 
			
		||||
    // This strange format doesn't allow font designer to write explicit
 | 
			
		||||
    // space as a character.
 | 
			
		||||
    // Rule: A space should be as large as the character " if available,
 | 
			
		||||
    // or 'a' if it's not.
 | 
			
		||||
    Font->Space = Font->CharWidth[(int)'"'];
 | 
			
		||||
    if (Font->Space<2)
 | 
			
		||||
      Font->Space = Font->CharWidth[(int)'a'];
 | 
			
		||||
    
 | 
			
		||||
    pixel = GetPixel(Surface, 0, Surface->h-1);
 | 
			
		||||
    SDL_UnlockSurface(Surface);
 | 
			
		||||
@ -111,7 +132,6 @@ void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font,
 | 
			
		||||
                 int x, int y, const char *text)
 | 
			
		||||
{
 | 
			
		||||
    const char* c;
 | 
			
		||||
    int charoffset;
 | 
			
		||||
    SDL_Rect srcrect, dstrect;
 | 
			
		||||
 | 
			
		||||
    if(text == NULL)
 | 
			
		||||
@ -123,42 +143,39 @@ void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font,
 | 
			
		||||
    srcrect.h = dstrect.h = Font->Surface->h - 1;
 | 
			
		||||
 | 
			
		||||
    for(c = text; *c != '\0' && x <= Surface->w ; c++) {
 | 
			
		||||
        charoffset = ((int) (*c - 33)) * 2 + 1;
 | 
			
		||||
        // skip spaces and nonprintable characters
 | 
			
		||||
        if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) {
 | 
			
		||||
            x += Font->CharPos[2]-Font->CharPos[1];
 | 
			
		||||
        if (*c == ' ' || Font->CharWidth[(int)*c]==0) {
 | 
			
		||||
            x += Font->Space;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        srcrect.w = Font->CharPos[charoffset+2] - Font->CharPos[charoffset];
 | 
			
		||||
        srcrect.w = Font->CharWidth[(int)*c];
 | 
			
		||||
        dstrect.w = srcrect.w;
 | 
			
		||||
        srcrect.x = Font->CharPos[charoffset];
 | 
			
		||||
        srcrect.x = Font->CharBegin[(int)*c];
 | 
			
		||||
        dstrect.x = x;
 | 
			
		||||
 | 
			
		||||
        SDL_BlitSurface(Font->Surface, &srcrect, Surface, &dstrect); 
 | 
			
		||||
 | 
			
		||||
        x += Font->CharPos[charoffset+1] - Font->CharPos[charoffset];
 | 
			
		||||
        x += Font->CharWidth[(int)*c];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SFont_TextWidth(const SFont_Font *Font, const char *text)
 | 
			
		||||
{
 | 
			
		||||
    const char* c;
 | 
			
		||||
    int charoffset=0;
 | 
			
		||||
    int width = 0;
 | 
			
		||||
 | 
			
		||||
    if(text == NULL)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    for(c = text; *c != '\0'; c++) {
 | 
			
		||||
        charoffset = ((int) *c - 33) * 2 + 1;
 | 
			
		||||
        // skip spaces and nonprintable characters
 | 
			
		||||
        if (*c == ' ' || charoffset < 0 || charoffset > Font->MaxPos) {
 | 
			
		||||
            width += Font->CharPos[2]-Font->CharPos[1];
 | 
			
		||||
        if (*c == ' ' || Font->CharWidth[(int)*c]==0) {
 | 
			
		||||
            width += Font->Space;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        width += Font->CharPos[charoffset+1] - Font->CharPos[charoffset];
 | 
			
		||||
        width += Font->CharWidth[(int)*c];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return width;
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,9 @@ extern "C" {
 | 
			
		||||
/// and call InitFont( YourFont );
 | 
			
		||||
typedef struct {
 | 
			
		||||
        SDL_Surface *Surface;   
 | 
			
		||||
        int CharPos[512];
 | 
			
		||||
        int MaxPos;
 | 
			
		||||
        int CharBegin[256];
 | 
			
		||||
        int CharWidth[256];
 | 
			
		||||
        int Space;
 | 
			
		||||
} SFont_Font;
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										769
									
								
								src/brush.c
									
									
									
									
									
								
							
							
						
						
									
										769
									
								
								src/brush.c
									
									
									
									
									
								
							@ -587,66 +587,97 @@ void Display_paintbrush(short x,short y,byte color,byte is_preview)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Changes the Brush size, discarding its previous content.
 | 
			
		||||
/// @return 0 OK, 1 Failed
 | 
			
		||||
byte Realloc_brush(word new_brush_width, word new_brush_height)
 | 
			
		||||
/// @return 0 on success, non-zero on failure (memory?).
 | 
			
		||||
/// @param new_brush: Optionally, you can provide an already allocated new
 | 
			
		||||
///        brush - otherwise, this function performs the allocation.
 | 
			
		||||
/// @param old_brush: If the caller passes NULL, this function will free the old
 | 
			
		||||
///        pixel data. If the caller provides the address of a (free) byte
 | 
			
		||||
///        pointer, the function will make it point to the original pixel data,
 | 
			
		||||
///        in this case it will be the caller's responsibility to free() it
 | 
			
		||||
///        (after transferring pixels to Brush, usually).
 | 
			
		||||
byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush, byte **old_brush)
 | 
			
		||||
{
 | 
			
		||||
  byte return_code=0;
 | 
			
		||||
 | 
			
		||||
  byte *new_smear_brush;
 | 
			
		||||
  byte *new_brush_remapped;
 | 
			
		||||
  word new_smear_brush_width;
 | 
			
		||||
  word new_smear_brush_height;
 | 
			
		||||
  byte new_brush_is_provided;
 | 
			
		||||
  
 | 
			
		||||
  new_brush_is_provided = (new_brush!=NULL);
 | 
			
		||||
  
 | 
			
		||||
  if (!new_brush_is_provided)
 | 
			
		||||
  {
 | 
			
		||||
    new_brush=(byte *)malloc(((long)new_brush_height)*new_brush_width);
 | 
			
		||||
    if (new_brush == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      Error(0);
 | 
			
		||||
      if (old_brush)
 | 
			
		||||
        *old_brush=NULL;
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  new_smear_brush_width=(new_brush_width>MAX_PAINTBRUSH_SIZE)?new_brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
  new_smear_brush_height=(new_brush_height>MAX_PAINTBRUSH_SIZE)?new_brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
  new_smear_brush=NULL;
 | 
			
		||||
  if ( (((long)Smear_brush_height)*Smear_brush_width) !=
 | 
			
		||||
       (((long)new_smear_brush_width)*new_smear_brush_height) )
 | 
			
		||||
  {
 | 
			
		||||
    new_smear_brush=(byte *)malloc(((long)new_smear_brush_height)*new_smear_brush_width);
 | 
			
		||||
    if (new_smear_brush == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      Error(0);
 | 
			
		||||
      if (old_brush)
 | 
			
		||||
        *old_brush=NULL;
 | 
			
		||||
      if (!new_brush_is_provided)
 | 
			
		||||
        free(new_brush);
 | 
			
		||||
      return 2;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  new_brush_remapped=NULL;
 | 
			
		||||
  if ( (((long)Brush_height)*Brush_width) !=
 | 
			
		||||
       (((long)new_brush_height)*new_brush_width) )
 | 
			
		||||
  {
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=(byte *)malloc(((long)new_brush_height)*new_brush_width);
 | 
			
		||||
    if (Brush == NULL)
 | 
			
		||||
    new_brush_remapped=(byte *)malloc(((long)new_brush_height)*new_brush_width);
 | 
			
		||||
    if (new_brush_remapped == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      Error(0);
 | 
			
		||||
      return_code=1;
 | 
			
		||||
  
 | 
			
		||||
      Brush=(byte *)malloc(1*1);
 | 
			
		||||
      if(Brush == NULL)
 | 
			
		||||
      {
 | 
			
		||||
          Error(ERROR_MEMORY);
 | 
			
		||||
          exit(ERROR_MEMORY);
 | 
			
		||||
      }
 | 
			
		||||
      new_brush_height=new_brush_width=1;
 | 
			
		||||
      *Brush=Fore_color;
 | 
			
		||||
      free(new_smear_brush);
 | 
			
		||||
      if (old_brush)
 | 
			
		||||
        *old_brush=NULL;  
 | 
			
		||||
      if (!new_brush_is_provided)
 | 
			
		||||
        free(new_brush);
 | 
			
		||||
      return 3;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // All allocations successful: can replace globals
 | 
			
		||||
  Brush_width=new_brush_width;
 | 
			
		||||
  Brush_height=new_brush_height;
 | 
			
		||||
  Brush_original_back_color=Back_color;
 | 
			
		||||
  
 | 
			
		||||
  free(Smear_brush);
 | 
			
		||||
  Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
  Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
  Smear_brush=(byte *)malloc(((long)Smear_brush_height)*Smear_brush_width);
 | 
			
		||||
  
 | 
			
		||||
  if (Smear_brush == NULL) // Failed to allocate the smear brush
 | 
			
		||||
  if (new_smear_brush)
 | 
			
		||||
  {
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return_code=1;
 | 
			
		||||
  
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=(byte *)malloc(1*1);
 | 
			
		||||
    if(Brush == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      Error(ERROR_MEMORY);
 | 
			
		||||
      exit(ERROR_MEMORY);
 | 
			
		||||
    }
 | 
			
		||||
    Brush_height=1;
 | 
			
		||||
    Brush_width=1;
 | 
			
		||||
  
 | 
			
		||||
    Smear_brush=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE);
 | 
			
		||||
    if(Smear_brush == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      Error(ERROR_MEMORY);
 | 
			
		||||
      exit(ERROR_MEMORY);
 | 
			
		||||
    }
 | 
			
		||||
    Smear_brush_height=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush_width=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    free(Smear_brush);
 | 
			
		||||
    Smear_brush=new_smear_brush;
 | 
			
		||||
  }
 | 
			
		||||
  return return_code;
 | 
			
		||||
  Smear_brush_width=new_smear_brush_width;
 | 
			
		||||
  Smear_brush_height=new_smear_brush_height;
 | 
			
		||||
 | 
			
		||||
  // Save or free the old brush pixels
 | 
			
		||||
  if (old_brush)
 | 
			
		||||
    *old_brush=Brush_original_pixels;
 | 
			
		||||
  else
 | 
			
		||||
    free(old_brush);
 | 
			
		||||
  Brush_original_pixels=new_brush;
 | 
			
		||||
  // Assign new brush
 | 
			
		||||
  if (new_brush_remapped)
 | 
			
		||||
  {
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=new_brush_remapped;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -828,7 +859,7 @@ void Capture_brush(short start_x,short start_y,short end_x,short end_y,short cle
 | 
			
		||||
    if (start_y+new_brush_height>Main_image_height)
 | 
			
		||||
      new_brush_height=Main_image_height-start_y;
 | 
			
		||||
 | 
			
		||||
    if (Realloc_brush(new_brush_width, new_brush_height) != 0)
 | 
			
		||||
    if (Realloc_brush(new_brush_width, new_brush_height, NULL, NULL))
 | 
			
		||||
      return; // Unable to allocate the new brush, keep the old one.
 | 
			
		||||
 | 
			
		||||
    Copy_image_to_brush(start_x,start_y,Brush_width,Brush_height,Main_image_width);
 | 
			
		||||
@ -843,6 +874,10 @@ void Capture_brush(short start_x,short start_y,short end_x,short end_y,short cle
 | 
			
		||||
        }
 | 
			
		||||
      Update_part_of_screen(start_x,start_y,Brush_width,Brush_height);
 | 
			
		||||
    }
 | 
			
		||||
    // Grab palette
 | 
			
		||||
    memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
 | 
			
		||||
    // Remap (no change)
 | 
			
		||||
    Remap_brush();
 | 
			
		||||
 | 
			
		||||
    // On centre la prise sur la brosse
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
@ -851,32 +886,25 @@ void Capture_brush(short start_x,short start_y,short end_x,short end_y,short cle
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Rotate_90_deg()
 | 
			
		||||
void Rotate_90_deg(void)
 | 
			
		||||
{
 | 
			
		||||
  short temp;
 | 
			
		||||
  byte * new_brush;
 | 
			
		||||
 | 
			
		||||
  new_brush=(byte *)malloc(((size_t)Brush_height)*Brush_width);
 | 
			
		||||
  if (new_brush)
 | 
			
		||||
  byte * old_brush;
 | 
			
		||||
  
 | 
			
		||||
  if (Realloc_brush(Brush_height, Brush_width, NULL, &old_brush))
 | 
			
		||||
  {
 | 
			
		||||
    Rotate_90_deg_lowlevel(Brush,new_brush,Brush_width,Brush_height);
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=new_brush;
 | 
			
		||||
 | 
			
		||||
    temp=Brush_width;
 | 
			
		||||
    Brush_width=Brush_height;
 | 
			
		||||
    Brush_height=temp;
 | 
			
		||||
 | 
			
		||||
    temp=Smear_brush_width;
 | 
			
		||||
    Smear_brush_width=Smear_brush_height;
 | 
			
		||||
    Smear_brush_height=temp;
 | 
			
		||||
 | 
			
		||||
    // On centre la prise sur la brosse
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
    Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  Rotate_90_deg_lowlevel(old_brush,Brush_original_pixels,Brush_height,Brush_width);
 | 
			
		||||
  
 | 
			
		||||
  free(old_brush);
 | 
			
		||||
 | 
			
		||||
  // Remap according to the last used remap table
 | 
			
		||||
  Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
 | 
			
		||||
 | 
			
		||||
  // On centre la prise sur la brosse
 | 
			
		||||
  Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
  Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -884,34 +912,45 @@ void Remap_brush(void)
 | 
			
		||||
{
 | 
			
		||||
  short x_pos; // Variable de balayage de la brosse
 | 
			
		||||
  short y_pos; // Variable de balayage de la brosse
 | 
			
		||||
  byte  used[256]; // Tableau de booléens "La couleur est utilisée"
 | 
			
		||||
  int   color;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // On commence par initialiser le tableau de booléens à faux
 | 
			
		||||
  for (color=0;color<=255;color++)
 | 
			
		||||
    used[color]=0;
 | 
			
		||||
    Brush_colormap[color]=0;
 | 
			
		||||
 | 
			
		||||
  // On calcule la table d'utilisation des couleurs
 | 
			
		||||
  for (y_pos=0;y_pos<Brush_height;y_pos++)
 | 
			
		||||
    for (x_pos=0;x_pos<Brush_width;x_pos++)
 | 
			
		||||
      used[Read_pixel_from_brush(x_pos,y_pos)]=1;
 | 
			
		||||
      Brush_colormap[*(Brush_original_pixels + y_pos * Brush_width + x_pos)]=1;
 | 
			
		||||
 | 
			
		||||
  //  On n'est pas censé remapper la couleur de transparence, sinon la brosse
 | 
			
		||||
  // changera de forme, donc on dit pour l'instant qu'elle n'est pas utilisée
 | 
			
		||||
  // ainsi on ne s'embêtera pas à la recalculer
 | 
			
		||||
  used[Back_color]=0;
 | 
			
		||||
  Brush_colormap[Back_color]=0;
 | 
			
		||||
 | 
			
		||||
  //   On va maintenant se servir de la table "used" comme table de
 | 
			
		||||
  //   On va maintenant se servir de la table comme table de
 | 
			
		||||
  // conversion: pour chaque indice, la table donne une couleur de
 | 
			
		||||
  // remplacement.
 | 
			
		||||
  // Note : Seules les couleurs utilisées on besoin d'êtres recalculées: les
 | 
			
		||||
  //       autres ne seront jamais consultées dans la nouvelle table de
 | 
			
		||||
  //       conversion puisque elles n'existent pas dans la brosse, donc elles
 | 
			
		||||
  //       ne seront pas utilisées par Remap_brush_LOWLEVEL.
 | 
			
		||||
  //       ne seront pas utilisées par Remap_general_lowlevel.
 | 
			
		||||
  for (color=0;color<=255;color++)
 | 
			
		||||
    if (used[color] != 0)
 | 
			
		||||
      used[color]=Best_color(Spare_palette[color].R,Spare_palette[color].G,Spare_palette[color].B);
 | 
			
		||||
    if (Brush_colormap[color] != 0)
 | 
			
		||||
    {
 | 
			
		||||
      byte r,g,b;
 | 
			
		||||
      r=Brush_original_palette[color].R;
 | 
			
		||||
      g=Brush_original_palette[color].G;
 | 
			
		||||
      b=Brush_original_palette[color].B;
 | 
			
		||||
      
 | 
			
		||||
      // When remapping to same palette, ensure we keep same color index
 | 
			
		||||
      if (r==Main_palette[color].R && g==Main_palette[color].G && b==Main_palette[color].B)
 | 
			
		||||
        Brush_colormap[color]=color;
 | 
			
		||||
      else
 | 
			
		||||
        // Usual method: closest by r g b
 | 
			
		||||
        Brush_colormap[color]=Best_color_perceptual(r,g,b);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  //   Il reste une couleur non calculée dans la table qu'il faut mettre à
 | 
			
		||||
  // jour: c'est la couleur de fond. On l'avait inhibée pour éviter son
 | 
			
		||||
@ -919,13 +958,13 @@ void Remap_brush(void)
 | 
			
		||||
  // la brosse, on va mettre dans la table une relation d'équivalence entre
 | 
			
		||||
  // les deux palettes: comme on ne veut pas que la couleur soit remplacée,
 | 
			
		||||
  // on va dire qu'on veut qu'elle soit remplacée par la couleur en question.
 | 
			
		||||
  used[Back_color]=Back_color;
 | 
			
		||||
  Brush_colormap[Back_color]=Back_color;
 | 
			
		||||
 | 
			
		||||
  //   Maintenant qu'on a une super table de conversion qui n'a que le nom
 | 
			
		||||
  // qui craint un peu, on peut faire l'échange dans la brosse de toutes les
 | 
			
		||||
  // teintes.
 | 
			
		||||
  Remap_general_lowlevel(used,Brush,Brush_width,Brush_height,Brush_width);
 | 
			
		||||
  //Remap_brush_LOWLEVEL(used);
 | 
			
		||||
  Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -934,104 +973,97 @@ void Outline_brush(void)
 | 
			
		||||
{
 | 
			
		||||
  long /*Pos,*/x_pos,y_pos;
 | 
			
		||||
  byte state;
 | 
			
		||||
  byte * new_brush;
 | 
			
		||||
  byte * temp;
 | 
			
		||||
  word width;
 | 
			
		||||
  word height;
 | 
			
		||||
  byte * old_brush;
 | 
			
		||||
  word old_width;
 | 
			
		||||
  word old_height;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  width=Brush_width+2;
 | 
			
		||||
  height=Brush_height+2;
 | 
			
		||||
  new_brush=(byte *)malloc(((long)width)*height);
 | 
			
		||||
 | 
			
		||||
  if (new_brush)
 | 
			
		||||
  old_width=Brush_width;
 | 
			
		||||
  old_height=Brush_height;
 | 
			
		||||
  
 | 
			
		||||
  SWAP_PBYTES(Brush, Brush_original_pixels);
 | 
			
		||||
  if(Realloc_brush(Brush_width+2, Brush_height+2, NULL, &old_brush))
 | 
			
		||||
  {
 | 
			
		||||
    // On remplit la bordure ajoutée par la Backcolor
 | 
			
		||||
    memset(new_brush,Back_color,((long)width)*height);
 | 
			
		||||
    Error(0);
 | 
			
		||||
    SWAP_PBYTES(Brush, Brush_original_pixels);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    // On copie la brosse courante dans la nouvelle
 | 
			
		||||
    Copy_part_of_image_to_another(Brush, // source
 | 
			
		||||
        0, 0, Brush_width, Brush_height, Brush_width,
 | 
			
		||||
        new_brush, // Destination
 | 
			
		||||
        1, 1, width);
 | 
			
		||||
  // On remplit la bordure ajoutée par la Backcolor
 | 
			
		||||
  memset(Brush,Back_color,((long)Brush_width)*Brush_height);
 | 
			
		||||
 | 
			
		||||
    // On intervertit la nouvelle et l'ancienne brosse:
 | 
			
		||||
    temp=Brush;
 | 
			
		||||
    Brush=new_brush;
 | 
			
		||||
    Brush_width+=2;
 | 
			
		||||
    Brush_height+=2;
 | 
			
		||||
    width-=2;
 | 
			
		||||
    height-=2;
 | 
			
		||||
  // On copie la brosse courante dans la nouvelle
 | 
			
		||||
  Copy_part_of_image_to_another(old_brush, // source
 | 
			
		||||
      0, 0, old_width, old_height, old_width,
 | 
			
		||||
      Brush, // Destination
 | 
			
		||||
      1, 1, Brush_width);
 | 
			
		||||
 | 
			
		||||
    // Si on "outline" avec une couleur différente de la Back_color on y va!
 | 
			
		||||
    if (Fore_color!=Back_color)
 | 
			
		||||
  // Si on "outline" avec une couleur différente de la Back_color on y va!
 | 
			
		||||
  if (Fore_color!=Back_color)
 | 
			
		||||
  {
 | 
			
		||||
    // 1er balayage (horizontal)
 | 
			
		||||
    for (y_pos=1; y_pos<Brush_height-1; y_pos++)
 | 
			
		||||
    {
 | 
			
		||||
      // 1er balayage (horizontal)
 | 
			
		||||
      for (y_pos=1; y_pos<Brush_height-1; y_pos++)
 | 
			
		||||
      {
 | 
			
		||||
        state=0;
 | 
			
		||||
        for (x_pos=1; x_pos<Brush_width-1; x_pos++)
 | 
			
		||||
        {
 | 
			
		||||
          if (temp[((y_pos-1)*width)+x_pos-1]==Back_color)
 | 
			
		||||
          {
 | 
			
		||||
            if (state != 0)
 | 
			
		||||
            {
 | 
			
		||||
              Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
              state=0;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          else if (state == 0)
 | 
			
		||||
          {
 | 
			
		||||
            Pixel_in_brush(x_pos-1,y_pos,Fore_color);
 | 
			
		||||
            state=1;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // Cas du dernier pixel à droite de la ligne
 | 
			
		||||
        if (state != 0)
 | 
			
		||||
          Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 2ème balayage (vertical)
 | 
			
		||||
      state=0;
 | 
			
		||||
      for (x_pos=1; x_pos<Brush_width-1; x_pos++)
 | 
			
		||||
      {
 | 
			
		||||
        state=0;
 | 
			
		||||
        for (y_pos=1; y_pos<Brush_height-1; y_pos++)
 | 
			
		||||
        if (old_brush[((y_pos-1)*old_width)+x_pos-1]==Back_color)
 | 
			
		||||
        {
 | 
			
		||||
          if (temp[((y_pos-1)*width)+x_pos-1]==Back_color)
 | 
			
		||||
          if (state != 0)
 | 
			
		||||
          {
 | 
			
		||||
            if (state != 0)
 | 
			
		||||
            {
 | 
			
		||||
              Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
              state=0;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          else if (state == 0)
 | 
			
		||||
          {
 | 
			
		||||
              Pixel_in_brush(x_pos,y_pos-1,Fore_color);
 | 
			
		||||
              state=1;
 | 
			
		||||
            Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
            state=0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // Cas du dernier pixel en bas de la colonne
 | 
			
		||||
        if (state != 0)
 | 
			
		||||
          Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
        else if (state == 0)
 | 
			
		||||
        {
 | 
			
		||||
          Pixel_in_brush(x_pos-1,y_pos,Fore_color);
 | 
			
		||||
          state=1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // Cas du dernier pixel à droite de la ligne
 | 
			
		||||
      if (state != 0)
 | 
			
		||||
        Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // On recentre la prise sur la brosse
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
    Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
 | 
			
		||||
    free(temp); // Libération de l'ancienne brosse
 | 
			
		||||
    temp = NULL;
 | 
			
		||||
 | 
			
		||||
    // Réallocation d'un buffer de Smear
 | 
			
		||||
    free(Smear_brush);
 | 
			
		||||
    Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush=(byte *)malloc(((long)Smear_brush_width)*Smear_brush_height);
 | 
			
		||||
    // 2ème balayage (vertical)
 | 
			
		||||
    for (x_pos=1; x_pos<Brush_width-1; x_pos++)
 | 
			
		||||
    {
 | 
			
		||||
      state=0;
 | 
			
		||||
      for (y_pos=1; y_pos<Brush_height-1; y_pos++)
 | 
			
		||||
      {
 | 
			
		||||
        if (old_brush[((y_pos-1)*old_width)+x_pos-1]==Back_color)
 | 
			
		||||
        {
 | 
			
		||||
          if (state != 0)
 | 
			
		||||
          {
 | 
			
		||||
            Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
            state=0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else if (state == 0)
 | 
			
		||||
        {
 | 
			
		||||
            Pixel_in_brush(x_pos,y_pos-1,Fore_color);
 | 
			
		||||
            state=1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // Cas du dernier pixel en bas de la colonne
 | 
			
		||||
      if (state != 0)
 | 
			
		||||
        Pixel_in_brush(x_pos,y_pos,Fore_color);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
    Error(0); // Pas assez de mémoire!
 | 
			
		||||
  // Adopt the current palette.
 | 
			
		||||
  memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
 | 
			
		||||
  memcpy(Brush_original_pixels, Brush, (long)Brush_width*Brush_height);
 | 
			
		||||
  for (i=0; i<256; i++)
 | 
			
		||||
    Brush_colormap[i]=i;
 | 
			
		||||
  //--
 | 
			
		||||
 | 
			
		||||
  // On recentre la prise sur la brosse
 | 
			
		||||
  Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
  Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
 | 
			
		||||
  free(old_brush); // Libération de l'ancienne brosse
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1039,112 +1071,105 @@ void Nibble_brush(void)
 | 
			
		||||
{
 | 
			
		||||
  long x_pos,y_pos;
 | 
			
		||||
  byte state;
 | 
			
		||||
  byte * new_brush;
 | 
			
		||||
  byte * temp;
 | 
			
		||||
  word width;
 | 
			
		||||
  word height;
 | 
			
		||||
  byte * old_brush;
 | 
			
		||||
  word old_width;
 | 
			
		||||
  word old_height;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if ( (Brush_width>2) && (Brush_height>2) )
 | 
			
		||||
  {
 | 
			
		||||
    width=Brush_width-2;
 | 
			
		||||
    height=Brush_height-2;
 | 
			
		||||
    new_brush=(byte *)malloc(((long)width)*height);
 | 
			
		||||
 | 
			
		||||
    if (new_brush)
 | 
			
		||||
    old_width=Brush_width;
 | 
			
		||||
    old_height=Brush_height;
 | 
			
		||||
    
 | 
			
		||||
    SWAP_PBYTES(Brush, Brush_original_pixels);
 | 
			
		||||
    if (Realloc_brush(Brush_width-2, Brush_height-2, NULL, &old_brush))
 | 
			
		||||
    {
 | 
			
		||||
      // On copie la brosse courante dans la nouvelle
 | 
			
		||||
      Copy_part_of_image_to_another(Brush, // source
 | 
			
		||||
                                               1,
 | 
			
		||||
                                               1,
 | 
			
		||||
                                               width,
 | 
			
		||||
                                               height,
 | 
			
		||||
                                               Brush_width,
 | 
			
		||||
                                               new_brush, // Destination
 | 
			
		||||
                                               0,
 | 
			
		||||
                                               0,
 | 
			
		||||
                                               width);
 | 
			
		||||
      Error(0);
 | 
			
		||||
      SWAP_PBYTES(Brush, Brush_original_pixels);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    // On copie l'ancienne brosse dans la nouvelle
 | 
			
		||||
    Copy_part_of_image_to_another(old_brush, // source
 | 
			
		||||
                                             1,
 | 
			
		||||
                                             1,
 | 
			
		||||
                                             old_width-2,
 | 
			
		||||
                                             old_height-2,
 | 
			
		||||
                                             old_width,
 | 
			
		||||
                                             Brush, // Destination
 | 
			
		||||
                                             0,
 | 
			
		||||
                                             0,
 | 
			
		||||
                                             Brush_width);
 | 
			
		||||
 | 
			
		||||
      // On intervertit la nouvelle et l'ancienne brosse:
 | 
			
		||||
      temp=Brush;
 | 
			
		||||
      Brush=new_brush;
 | 
			
		||||
      Brush_width-=2;
 | 
			
		||||
      Brush_height-=2;
 | 
			
		||||
      width+=2;
 | 
			
		||||
      height+=2;
 | 
			
		||||
 | 
			
		||||
      // 1er balayage (horizontal)
 | 
			
		||||
      for (y_pos=0; y_pos<Brush_height; y_pos++)
 | 
			
		||||
      {
 | 
			
		||||
        state=(temp[(y_pos+1)*width]!=Back_color);
 | 
			
		||||
        for (x_pos=0; x_pos<Brush_width; x_pos++)
 | 
			
		||||
        {
 | 
			
		||||
          if (temp[((y_pos+1)*width)+x_pos+1]==Back_color)
 | 
			
		||||
          {
 | 
			
		||||
            if (state != 0)
 | 
			
		||||
            {
 | 
			
		||||
              if (x_pos>0)
 | 
			
		||||
                Pixel_in_brush(x_pos-1,y_pos,Back_color);
 | 
			
		||||
              state=0;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            if (state == 0)
 | 
			
		||||
            {
 | 
			
		||||
              Pixel_in_brush(x_pos,y_pos,Back_color);
 | 
			
		||||
              state=1;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // Cas du dernier pixel à droite de la ligne
 | 
			
		||||
        if (temp[((y_pos+1)*width)+x_pos+1]==Back_color)
 | 
			
		||||
          Pixel_in_brush(x_pos-1,y_pos,Back_color);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 2ème balayage (vertical)
 | 
			
		||||
    // 1er balayage (horizontal)
 | 
			
		||||
    for (y_pos=0; y_pos<Brush_height; y_pos++)
 | 
			
		||||
    {
 | 
			
		||||
      state=(old_brush[(y_pos+1)*old_width]!=Back_color);
 | 
			
		||||
      for (x_pos=0; x_pos<Brush_width; x_pos++)
 | 
			
		||||
      {
 | 
			
		||||
        state=(temp[width+x_pos+1]!=Back_color);;
 | 
			
		||||
        for (y_pos=0; y_pos<Brush_height; y_pos++)
 | 
			
		||||
        if (old_brush[((y_pos+1)*old_width)+x_pos+1]==Back_color)
 | 
			
		||||
        {
 | 
			
		||||
          if (temp[((y_pos+1)*width)+x_pos+1]==Back_color)
 | 
			
		||||
          if (state != 0)
 | 
			
		||||
          {
 | 
			
		||||
            if (state)
 | 
			
		||||
            {
 | 
			
		||||
              if (y_pos>0)
 | 
			
		||||
                Pixel_in_brush(x_pos,y_pos-1,Back_color);
 | 
			
		||||
              state=0;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            if (state == 0)
 | 
			
		||||
            {
 | 
			
		||||
              Pixel_in_brush(x_pos,y_pos,Back_color);
 | 
			
		||||
              state=1;
 | 
			
		||||
            }
 | 
			
		||||
            if (x_pos>0)
 | 
			
		||||
              Pixel_in_brush(x_pos-1,y_pos,Back_color);
 | 
			
		||||
            state=0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          if (state == 0)
 | 
			
		||||
          {
 | 
			
		||||
            Pixel_in_brush(x_pos,y_pos,Back_color);
 | 
			
		||||
            state=1;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // Cas du dernier pixel en bas de la colonne
 | 
			
		||||
        if (temp[((y_pos+1)*width)+x_pos+1]==Back_color)
 | 
			
		||||
          Pixel_in_brush(x_pos,y_pos-1,Back_color);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // On recentre la prise sur la brosse
 | 
			
		||||
      Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
      Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
 | 
			
		||||
      free(temp); // Libération de l'ancienne brosse
 | 
			
		||||
      temp = NULL;
 | 
			
		||||
 | 
			
		||||
      // Réallocation d'un buffer de Smear
 | 
			
		||||
      free(Smear_brush);
 | 
			
		||||
      Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      Smear_brush=(byte *)malloc(((long)Smear_brush_width)*Smear_brush_height);
 | 
			
		||||
      // Cas du dernier pixel à droite de la ligne
 | 
			
		||||
      if (old_brush[((y_pos+1)*old_width)+x_pos+1]==Back_color)
 | 
			
		||||
        Pixel_in_brush(x_pos-1,y_pos,Back_color);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      Error(0);  // Pas assez de mémoire!
 | 
			
		||||
 | 
			
		||||
    // 2ème balayage (vertical)
 | 
			
		||||
    for (x_pos=0; x_pos<Brush_width; x_pos++)
 | 
			
		||||
    {
 | 
			
		||||
      state=(old_brush[old_width+x_pos+1]!=Back_color);;
 | 
			
		||||
      for (y_pos=0; y_pos<Brush_height; y_pos++)
 | 
			
		||||
      {
 | 
			
		||||
        if (old_brush[((y_pos+1)*old_width)+x_pos+1]==Back_color)
 | 
			
		||||
        {
 | 
			
		||||
          if (state)
 | 
			
		||||
          {
 | 
			
		||||
            if (y_pos>0)
 | 
			
		||||
              Pixel_in_brush(x_pos,y_pos-1,Back_color);
 | 
			
		||||
            state=0;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          if (state == 0)
 | 
			
		||||
          {
 | 
			
		||||
            Pixel_in_brush(x_pos,y_pos,Back_color);
 | 
			
		||||
            state=1;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // Cas du dernier pixel en bas de la colonne
 | 
			
		||||
      if (old_brush[((y_pos+1)*old_width)+x_pos+1]==Back_color)
 | 
			
		||||
        Pixel_in_brush(x_pos,y_pos-1,Back_color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(old_brush);
 | 
			
		||||
    // Adopt the current palette.
 | 
			
		||||
    memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
 | 
			
		||||
    memcpy(Brush_original_pixels, Brush, (long)Brush_width*Brush_height);
 | 
			
		||||
    for (i=0; i<256; i++)
 | 
			
		||||
      Brush_colormap[i]=i;
 | 
			
		||||
    //--
 | 
			
		||||
 | 
			
		||||
    // On recentre la prise sur la brosse
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
    Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1162,7 +1187,6 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear)
 | 
			
		||||
  word  new_brush_width;
 | 
			
		||||
  word  new_brush_height;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // On recherche les bornes de la brosse:
 | 
			
		||||
  for (temp=0; temp<2*vertices; temp+=2)
 | 
			
		||||
  {
 | 
			
		||||
@ -1204,46 +1228,15 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear)
 | 
			
		||||
    new_brush_width=(end_x-start_x)+1;
 | 
			
		||||
    new_brush_height=(end_y-start_y)+1;
 | 
			
		||||
 | 
			
		||||
    if ( (((long)Brush_height)*Brush_width) !=
 | 
			
		||||
         (((long)new_brush_height)*new_brush_width) )
 | 
			
		||||
    {
 | 
			
		||||
      free(Brush);
 | 
			
		||||
      Brush=(byte *)malloc(((long)new_brush_height)*new_brush_width);
 | 
			
		||||
      if (!Brush)
 | 
			
		||||
      {
 | 
			
		||||
        Error(0);
 | 
			
		||||
 | 
			
		||||
        Brush=(byte *)malloc(1*1);
 | 
			
		||||
        if(Brush==NULL) Error(ERROR_MEMORY);
 | 
			
		||||
        new_brush_height=new_brush_width=1;
 | 
			
		||||
        *Brush=Fore_color;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    Brush_width=new_brush_width;
 | 
			
		||||
    Brush_height=new_brush_height;
 | 
			
		||||
 | 
			
		||||
    free(Smear_brush);
 | 
			
		||||
    Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush=(byte *)malloc(((long)Smear_brush_height)*Smear_brush_width);
 | 
			
		||||
 | 
			
		||||
    if (!Smear_brush) // On ne peut même pas allouer la brosse du smear!
 | 
			
		||||
    if (Realloc_brush(new_brush_width, new_brush_height, NULL, NULL))
 | 
			
		||||
    {
 | 
			
		||||
      Error(0);
 | 
			
		||||
 | 
			
		||||
      free(Brush);
 | 
			
		||||
      Brush=(byte *)malloc(1*1);
 | 
			
		||||
      if(Brush==NULL) Error(ERROR_MEMORY);
 | 
			
		||||
      Brush_height=1;
 | 
			
		||||
      Brush_width=1;
 | 
			
		||||
 | 
			
		||||
      Smear_brush=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE);
 | 
			
		||||
      Smear_brush_height=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      Smear_brush_width=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Brush_offset_X=start_x;
 | 
			
		||||
    Brush_offset_Y=start_y;
 | 
			
		||||
    
 | 
			
		||||
    Pixel_figure=Pixel_figure_in_brush;
 | 
			
		||||
 | 
			
		||||
    memset(Brush,Back_color,(long)Brush_width*Brush_height);
 | 
			
		||||
@ -1271,6 +1264,13 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear)
 | 
			
		||||
          if (clear)
 | 
			
		||||
            Pixel_in_current_screen(x_pos,y_pos,Back_color,0);
 | 
			
		||||
        }
 | 
			
		||||
    // Grab palette
 | 
			
		||||
    memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
 | 
			
		||||
    // Init colormap
 | 
			
		||||
    for (temp=0; temp<256; temp++)
 | 
			
		||||
      Brush_colormap[temp]=temp;
 | 
			
		||||
    // Copy Brush to original
 | 
			
		||||
    memcpy(Brush_original_pixels, Brush, (long)Brush_width*Brush_height);
 | 
			
		||||
 | 
			
		||||
    // On centre la prise sur la brosse
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
@ -1304,50 +1304,27 @@ void Stretch_brush(short x1, short y1, short x2, short y2)
 | 
			
		||||
  }
 | 
			
		||||
  new_brush_height++;
 | 
			
		||||
 | 
			
		||||
  // Free some memory
 | 
			
		||||
  free(Smear_brush);
 | 
			
		||||
  Smear_brush = NULL;
 | 
			
		||||
 | 
			
		||||
  if ((new_brush=((byte *)malloc(new_brush_width*new_brush_height))))
 | 
			
		||||
  new_brush=((byte *)malloc(new_brush_width*new_brush_height));
 | 
			
		||||
  if (!new_brush)
 | 
			
		||||
  {
 | 
			
		||||
    Rescale(Brush, Brush_width, Brush_height, new_brush, new_brush_width, new_brush_height, x2<x1, y2<y1);
 | 
			
		||||
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=new_brush;
 | 
			
		||||
 | 
			
		||||
    Brush_width=new_brush_width;
 | 
			
		||||
    Brush_height=new_brush_height;
 | 
			
		||||
 | 
			
		||||
    Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush=(byte *)malloc(((long)Smear_brush_height)*Smear_brush_width);
 | 
			
		||||
 | 
			
		||||
    if (!Smear_brush) // On ne peut même pas allouer la brosse du smear!
 | 
			
		||||
    {
 | 
			
		||||
      Error(0);
 | 
			
		||||
 | 
			
		||||
      free(Brush);
 | 
			
		||||
      Brush=(byte *)malloc(1*1);
 | 
			
		||||
      Brush_height=1;
 | 
			
		||||
      Brush_width=1;
 | 
			
		||||
 | 
			
		||||
      Smear_brush=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE);
 | 
			
		||||
      Smear_brush_height=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      Smear_brush_width=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
    Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    // Ici la libération de mémoire n'a pas suffi donc on remet dans l'état
 | 
			
		||||
    // où c'etait avant. On a juste à réallouer la Smear_brush car il y a
 | 
			
		||||
    // normalement la place pour elle puisque rien d'autre n'a pu être alloué
 | 
			
		||||
    // entre temps.
 | 
			
		||||
    Smear_brush=(byte *)malloc(((long)Smear_brush_height)*Smear_brush_width);
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  Rescale(Brush_original_pixels, Brush_width, Brush_height, new_brush, new_brush_width, new_brush_height, x2<x1, y2<y1);
 | 
			
		||||
 | 
			
		||||
  if (Realloc_brush(new_brush_width, new_brush_height, new_brush, NULL))
 | 
			
		||||
  {
 | 
			
		||||
    free(new_brush);
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // Remap according to the last used remap table
 | 
			
		||||
  Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
 | 
			
		||||
  
 | 
			
		||||
  Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
  Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1578,9 +1555,6 @@ void Distort_brush(short x1, short y1, short x2, short y2, short x3, short y3, s
 | 
			
		||||
  short min_x, max_x, min_y, max_y;
 | 
			
		||||
  short width, height;
 | 
			
		||||
  byte * new_brush;
 | 
			
		||||
  byte * new_smear_brush;
 | 
			
		||||
  short new_smear_brush_width;
 | 
			
		||||
  short new_smear_brush_height;
 | 
			
		||||
  
 | 
			
		||||
  // Move all coordinates to start on (0,0)
 | 
			
		||||
  min_x=Min4(x1,x2,x3,x4);
 | 
			
		||||
@ -1601,24 +1575,11 @@ void Distort_brush(short x1, short y1, short x2, short y2, short x3, short y3, s
 | 
			
		||||
  width=Max(max_x-min_x, 1);
 | 
			
		||||
  height=Max(max_y-min_y, 1);
 | 
			
		||||
    
 | 
			
		||||
  new_smear_brush_width=(width>MAX_PAINTBRUSH_SIZE)?width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
  new_smear_brush_height=(height>MAX_PAINTBRUSH_SIZE)?height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
 | 
			
		||||
  new_smear_brush=(byte *)malloc(((long)new_smear_brush_height)*new_smear_brush_width);
 | 
			
		||||
  if (! new_smear_brush)
 | 
			
		||||
  {
 | 
			
		||||
    // Out of memory while allocating new smear brush
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  new_brush=((byte *)malloc((long)width*height));
 | 
			
		||||
  if (!new_brush)
 | 
			
		||||
  {
 | 
			
		||||
    // Out of memory while allocating new brush
 | 
			
		||||
    Error(0);
 | 
			
		||||
    free(new_smear_brush);
 | 
			
		||||
    new_smear_brush = NULL;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1631,18 +1592,14 @@ void Distort_brush(short x1, short y1, short x2, short y2, short x3, short y3, s
 | 
			
		||||
  Distort_buffer_width=width;
 | 
			
		||||
  Draw_brush_linear_distort(0, 0, (Brush_width<<16), (Brush_height<<16), (x1<<16), (y1<<16), (x2<<16), (y2<<16), (x3<<16), (y3<<16), (x4<<16), (y4<<16));
 | 
			
		||||
 | 
			
		||||
  // Free old brushes
 | 
			
		||||
  free(Smear_brush);
 | 
			
		||||
  free(Brush);
 | 
			
		||||
 | 
			
		||||
  // Point to the new ones
 | 
			
		||||
  Brush=new_brush;
 | 
			
		||||
  Brush_width=width;
 | 
			
		||||
  Brush_height=height;
 | 
			
		||||
 | 
			
		||||
  Smear_brush=new_smear_brush;
 | 
			
		||||
  Smear_brush_width=new_smear_brush_width;
 | 
			
		||||
  Smear_brush_height=new_smear_brush_height;
 | 
			
		||||
  if (Realloc_brush(width, height, new_brush, NULL))
 | 
			
		||||
  {
 | 
			
		||||
    free(new_brush);
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // Remap according to the last used remap table
 | 
			
		||||
  Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
 | 
			
		||||
 | 
			
		||||
  // Re-center brush handle  
 | 
			
		||||
  Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
@ -1867,7 +1824,7 @@ void Compute_quad_texture(int x1,int y1,int xt1,int yt1,
 | 
			
		||||
      xt=Round((float)(ScanY_Xt[0][y])+(temp*(ScanY_Xt[1][y]-ScanY_Xt[0][y])));
 | 
			
		||||
      yt=Round((float)(ScanY_Yt[0][y])+(temp*(ScanY_Yt[1][y]-ScanY_Yt[0][y])));
 | 
			
		||||
      if (xt>=0 && yt>=0)
 | 
			
		||||
        buffer[x+(y*width)]=Read_pixel_from_brush(xt,yt);
 | 
			
		||||
        buffer[x+(y*width)]=*(Brush_original_pixels + yt * Brush_width + xt);
 | 
			
		||||
    }
 | 
			
		||||
    for (; x<width; x++)
 | 
			
		||||
      buffer[x+(y*width)]=Back_color;
 | 
			
		||||
@ -1920,54 +1877,32 @@ void Rotate_brush(float angle)
 | 
			
		||||
  new_brush_width=x_max+1-x_min;
 | 
			
		||||
  new_brush_height=y_max+1-y_min;
 | 
			
		||||
 | 
			
		||||
  free(Smear_brush); // On libère un peu de mémoire
 | 
			
		||||
  Smear_brush = NULL;
 | 
			
		||||
 | 
			
		||||
  if ((new_brush=((byte *)malloc(new_brush_width*new_brush_height))))
 | 
			
		||||
  new_brush=(byte *)malloc(new_brush_width*new_brush_height);
 | 
			
		||||
  
 | 
			
		||||
  if (!new_brush)
 | 
			
		||||
  {
 | 
			
		||||
    // Et maintenant on calcule la nouvelle brosse tournée.
 | 
			
		||||
    Compute_quad_texture(x1,y1,               0,               0,
 | 
			
		||||
                          x2,y2,Brush_width-1,               0,
 | 
			
		||||
                          x3,y3,               0,Brush_height-1,
 | 
			
		||||
                          x4,y4,Brush_width-1,Brush_height-1,
 | 
			
		||||
                          new_brush,new_brush_width,new_brush_height);
 | 
			
		||||
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=new_brush;
 | 
			
		||||
 | 
			
		||||
    Brush_width=new_brush_width;
 | 
			
		||||
    Brush_height=new_brush_height;
 | 
			
		||||
 | 
			
		||||
    Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush=(byte *)malloc(((long)Smear_brush_height)*Smear_brush_width);
 | 
			
		||||
 | 
			
		||||
    if (!Smear_brush) // On ne peut même pas allouer la brosse du smear!
 | 
			
		||||
    {
 | 
			
		||||
      Error(0);
 | 
			
		||||
 | 
			
		||||
      free(Brush);
 | 
			
		||||
      Brush=(byte *)malloc(1*1);
 | 
			
		||||
      Brush_height=1;
 | 
			
		||||
      Brush_width=1;
 | 
			
		||||
 | 
			
		||||
      Smear_brush=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE);
 | 
			
		||||
      Smear_brush_height=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      Smear_brush_width=MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
    Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    // Ici la libération de mémoire n'a pas suffit donc on remet dans l'état
 | 
			
		||||
    // où c'etait avant. On a juste à réallouer la Smear_brush car il y a
 | 
			
		||||
    // normalement la place pour elle puisque rien d'autre n'a pu être alloué
 | 
			
		||||
    // entre temps.
 | 
			
		||||
    Smear_brush=(byte *)malloc(((long)Smear_brush_height)*Smear_brush_width);
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // Et maintenant on calcule la nouvelle brosse tournée.
 | 
			
		||||
  Compute_quad_texture(x1,y1,               0,               0,
 | 
			
		||||
                        x2,y2,Brush_width-1,               0,
 | 
			
		||||
                        x3,y3,               0,Brush_height-1,
 | 
			
		||||
                        x4,y4,Brush_width-1,Brush_height-1,
 | 
			
		||||
                        new_brush,new_brush_width,new_brush_height);
 | 
			
		||||
  
 | 
			
		||||
  if (Realloc_brush(new_brush_width, new_brush_height, new_brush, NULL))
 | 
			
		||||
  {
 | 
			
		||||
    free(new_brush);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // Remap according to the last used remap table
 | 
			
		||||
  Remap_general_lowlevel(Brush_colormap,Brush_original_pixels,Brush,Brush_width,Brush_height,Brush_width);
 | 
			
		||||
 | 
			
		||||
  // Center offsets
 | 
			
		||||
  Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
  Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2090,3 +2025,25 @@ void Rotate_brush_preview(float angle)
 | 
			
		||||
  end_y=Max(Max(y1,y2),Max(y3,y4));
 | 
			
		||||
  Update_part_of_screen(start_x,start_y,end_x-start_x+1,end_y-start_y+1);
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
/// Sets brush's original palette and color mapping.
 | 
			
		||||
void Brush_set_palette(T_Palette *palette)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  byte need_remap;
 | 
			
		||||
  
 | 
			
		||||
  need_remap=0;
 | 
			
		||||
  
 | 
			
		||||
  memcpy(Brush_original_palette,palette,sizeof(T_Palette));
 | 
			
		||||
  for (i=0;i<256;i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (Brush_original_palette[i].R!=Main_palette[i].R
 | 
			
		||||
     || Brush_original_palette[i].G!=Main_palette[i].G
 | 
			
		||||
     || Brush_original_palette[i].B!=Main_palette[i].B)
 | 
			
		||||
    {
 | 
			
		||||
      need_remap=1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										15
									
								
								src/brush.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/brush.h
									
									
									
									
									
								
							@ -111,10 +111,19 @@ void Capture_brush_with_lasso(int vertices, short * points,short clear);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Changes the Brush size, discarding its previous content.
 | 
			
		||||
/// @return 0 OK, 1 Failed
 | 
			
		||||
byte Realloc_brush(word new_brush_width, word new_brush_height);
 | 
			
		||||
/// Changes the Brush size.
 | 
			
		||||
/// @return 0 on success, non-zero on failure (memory?).
 | 
			
		||||
/// @param new_brush: Optionally, you can provide an already allocated new
 | 
			
		||||
///        brush - otherwise, this function performs the allocation.
 | 
			
		||||
/// @param old_brush: If the caller passes NULL, this function will free the old
 | 
			
		||||
///        pixel data. If the caller provides the address of a (free) byte
 | 
			
		||||
///        pointer, the function will make it point to the original pixel data,
 | 
			
		||||
///        in this case it will be the caller's responsibility to free() it
 | 
			
		||||
///        (after transferring pixels to Brush, usually).
 | 
			
		||||
byte Realloc_brush(word new_brush_width, word new_brush_height, byte *new_brush, byte **old_brush);
 | 
			
		||||
 | 
			
		||||
/// Sets brush's original palette and color mapping.
 | 
			
		||||
void Brush_set_palette(T_Palette *palette);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										110
									
								
								src/brush_ops.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								src/brush_ops.c
									
									
									
									
									
								
							@ -38,7 +38,7 @@
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__VBCC__)||defined(__GP2X__)
 | 
			
		||||
#if defined(__VBCC__) || defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
    #define M_PI 3.141592653589793238462643
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -251,6 +251,106 @@ void Colorpicker_0_1(void)
 | 
			
		||||
  Unselect_button(BUTTON_COLORPICKER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////// OPERATION_RMB_COLORPICK
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte Rightclick_colorpick(byte cursor_visible)
 | 
			
		||||
{
 | 
			
		||||
  // Check if the rightclick colorpick should take over:
 | 
			
		||||
  if (!Config.Right_click_colorpick)
 | 
			
		||||
    return 0;
 | 
			
		||||
  if (Mouse_K!=RIGHT_SIDE)
 | 
			
		||||
    return 0;    
 | 
			
		||||
  // In these modes, the Foreground color is ignored,
 | 
			
		||||
  // so the RMB should act as normal.
 | 
			
		||||
  if (Shade_mode||Quick_shade_mode||Tiling_mode)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  Colorpicker_color=-1;
 | 
			
		||||
  Colorpicker_X=-1;
 | 
			
		||||
  Colorpicker_Y=-1;
 | 
			
		||||
  
 | 
			
		||||
  if (cursor_visible)
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
  Start_operation_stack(OPERATION_RMB_COLORPICK);
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  
 | 
			
		||||
  // Just an indicator to go to next step
 | 
			
		||||
  Operation_push(1);
 | 
			
		||||
  Rightclick_colorpick_2_1();
 | 
			
		||||
  
 | 
			
		||||
  if (cursor_visible)
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Rightclick_colorpick_2_1(void)
 | 
			
		||||
//
 | 
			
		||||
// Opération   : OPERATION_RMB_COLORPICK
 | 
			
		||||
// Click Souris: 2
 | 
			
		||||
// Taille_Pile : 1
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  char str[4];
 | 
			
		||||
 | 
			
		||||
  if ( (Colorpicker_X!=Paintbrush_X)
 | 
			
		||||
    || (Colorpicker_Y!=Paintbrush_Y) )
 | 
			
		||||
  {
 | 
			
		||||
    if ( (Paintbrush_X>=0) && (Paintbrush_Y>=0)
 | 
			
		||||
      && (Paintbrush_X<Main_image_width)
 | 
			
		||||
      && (Paintbrush_Y<Main_image_height) )
 | 
			
		||||
      Colorpicker_color=Read_pixel_from_current_screen(Paintbrush_X,Paintbrush_Y);
 | 
			
		||||
    else
 | 
			
		||||
      Colorpicker_color=0;
 | 
			
		||||
 | 
			
		||||
    Colorpicker_X=Paintbrush_X;
 | 
			
		||||
    Colorpicker_Y=Paintbrush_Y;
 | 
			
		||||
 | 
			
		||||
    if (Menu_is_visible)
 | 
			
		||||
    {
 | 
			
		||||
      Print_coordinates();
 | 
			
		||||
      Num2str(Colorpicker_color,str,3);
 | 
			
		||||
      Print_in_menu(str,20);
 | 
			
		||||
      Print_general(170*Menu_factor_X,Menu_status_Y," ",0,Colorpicker_color);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Rightclick_colorpick_0_1(void)
 | 
			
		||||
//
 | 
			
		||||
// Opération   : OPERATION_RMB_COLORPICK
 | 
			
		||||
// Click Souris: 0
 | 
			
		||||
// Taille_Pile : 1
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  short dummy;
 | 
			
		||||
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
  
 | 
			
		||||
  Operation_pop(&dummy);
 | 
			
		||||
  Set_fore_color(Colorpicker_color);
 | 
			
		||||
  
 | 
			
		||||
  // Restore previous operation
 | 
			
		||||
  Start_operation_stack(Operation_before_interrupt);
 | 
			
		||||
  
 | 
			
		||||
  // Erase the color block which shows the picked color
 | 
			
		||||
  if (Operation_before_interrupt!=OPERATION_REPLACE)
 | 
			
		||||
    if ( (Mouse_Y<Menu_Y) && (Menu_is_visible) &&
 | 
			
		||||
         ( (!Main_magnifier_mode) || (Mouse_X<Main_separator_position) || (Mouse_X>=Main_X_zoom) ) )
 | 
			
		||||
      Print_in_menu("X:       Y:             ",0);
 | 
			
		||||
 | 
			
		||||
  Print_coordinates();
 | 
			
		||||
  
 | 
			
		||||
  Display_cursor();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////// OPERATION_GRAB_BRUSH
 | 
			
		||||
 | 
			
		||||
@ -858,6 +958,10 @@ void Rotate_brush_1_5(void)
 | 
			
		||||
  Operation_pop(&old_y);
 | 
			
		||||
  Operation_pop(&old_x);
 | 
			
		||||
 | 
			
		||||
  // On corrige les coordonnées de la ligne si la touche shift est appuyée...
 | 
			
		||||
  if(SDL_GetModState() & KMOD_SHIFT)
 | 
			
		||||
    Clamp_coordinates_regular_angle(Brush_rotation_center_X,Brush_rotation_center_Y,&Paintbrush_X,&Paintbrush_Y);
 | 
			
		||||
 | 
			
		||||
  if ( (Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=2) )
 | 
			
		||||
  {
 | 
			
		||||
    if ( (Brush_rotation_center_X==Paintbrush_X)
 | 
			
		||||
@ -921,6 +1025,10 @@ void Rotate_brush_0_5(void)
 | 
			
		||||
  Operation_pop(&old_y);
 | 
			
		||||
  Operation_pop(&old_x);
 | 
			
		||||
 | 
			
		||||
  // On corrige les coordonnées de la ligne si la touche shift est appuyée...
 | 
			
		||||
  if(SDL_GetModState() & KMOD_SHIFT)
 | 
			
		||||
    Clamp_coordinates_regular_angle(Brush_rotation_center_X,Brush_rotation_center_Y,&Paintbrush_X,&Paintbrush_Y);
 | 
			
		||||
 | 
			
		||||
  if ((Paintbrush_X!=old_x) || (Paintbrush_Y!=old_y) || (prev_state!=3))
 | 
			
		||||
  {
 | 
			
		||||
    if ( (Brush_rotation_center_X==Paintbrush_X)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1067
									
								
								src/buttons.c
									
									
									
									
									
								
							
							
						
						
									
										1067
									
								
								src/buttons.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -670,5 +670,9 @@ void Button_Smear_mode(void);
 | 
			
		||||
 | 
			
		||||
void Button_Brush_container(void);
 | 
			
		||||
 | 
			
		||||
byte Store_paintbrush(int index);
 | 
			
		||||
 | 
			
		||||
void Select_paintbrush(int index);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "brush.h"
 | 
			
		||||
 | 
			
		||||
//---------- Menu dans lequel on tagge des couleurs (genre Stencil) ----------
 | 
			
		||||
void Menu_tag_colors(char * window_title, byte * table, byte * mode, byte can_cancel, const char *help_section, word close_shortcut)
 | 
			
		||||
@ -279,7 +280,7 @@ void Button_Grid_menu(void)
 | 
			
		||||
    {
 | 
			
		||||
      case 3 :
 | 
			
		||||
        Num2str(chosen_X,str,2);
 | 
			
		||||
        Readline(39,26,str,2,1);
 | 
			
		||||
        Readline(39,26,str,2,INPUT_TYPE_INTEGER);
 | 
			
		||||
        chosen_X=atoi(str);
 | 
			
		||||
        // On corrige les dimensions
 | 
			
		||||
        if ((!chosen_X) || (chosen_X>80))
 | 
			
		||||
@ -301,7 +302,7 @@ void Button_Grid_menu(void)
 | 
			
		||||
        break;
 | 
			
		||||
      case 4 :
 | 
			
		||||
        Num2str(chosen_Y,str,2);
 | 
			
		||||
        Readline(39,47,str,2,1);
 | 
			
		||||
        Readline(39,47,str,2,INPUT_TYPE_INTEGER);
 | 
			
		||||
        chosen_Y=atoi(str);
 | 
			
		||||
        // On corrige les dimensions
 | 
			
		||||
        if ((!chosen_Y) || (chosen_Y>80))
 | 
			
		||||
@ -323,7 +324,7 @@ void Button_Grid_menu(void)
 | 
			
		||||
        break;
 | 
			
		||||
      case 5 :
 | 
			
		||||
        Num2str(dx_selected,str,2);
 | 
			
		||||
        Readline(97,26,str,2,1);
 | 
			
		||||
        Readline(97,26,str,2,INPUT_TYPE_INTEGER);
 | 
			
		||||
        dx_selected=atoi(str);
 | 
			
		||||
        // On corrige les dimensions
 | 
			
		||||
        if (dx_selected>79)
 | 
			
		||||
@ -338,7 +339,7 @@ void Button_Grid_menu(void)
 | 
			
		||||
        break;
 | 
			
		||||
      case 6 :
 | 
			
		||||
        Num2str(dy_selected,str,2);
 | 
			
		||||
        Readline(97,47,str,2,1);
 | 
			
		||||
        Readline(97,47,str,2,INPUT_TYPE_INTEGER);
 | 
			
		||||
        dy_selected=atoi(str);
 | 
			
		||||
        // On corrige les dimensions
 | 
			
		||||
        if (dy_selected>79)
 | 
			
		||||
@ -479,7 +480,7 @@ void Button_Smooth_menu(void)
 | 
			
		||||
        Num2str(chosen_matrix[x][y],str,2);
 | 
			
		||||
        Readline(matrix_input[x][y]->Pos_X+2,
 | 
			
		||||
                 matrix_input[x][y]->Pos_Y+2,
 | 
			
		||||
                 str,2,1);
 | 
			
		||||
                 str,2,INPUT_TYPE_INTEGER);
 | 
			
		||||
        chosen_matrix[x][y]=atoi(str);
 | 
			
		||||
        Display_cursor();
 | 
			
		||||
      }
 | 
			
		||||
@ -553,6 +554,9 @@ void Button_Colorize_mode(void)
 | 
			
		||||
        break;
 | 
			
		||||
      case 2 :
 | 
			
		||||
        Effect_function=Effect_substractive_colorize;
 | 
			
		||||
        break;
 | 
			
		||||
      case 3 :
 | 
			
		||||
        Effect_function=Effect_alpha_colorize;
 | 
			
		||||
    }
 | 
			
		||||
    Shade_mode=0;
 | 
			
		||||
    Quick_shade_mode=0;
 | 
			
		||||
@ -572,10 +576,12 @@ void Button_Colorize_display_selection(int mode)
 | 
			
		||||
  Print_in_window(4,37," ",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(4,57," ",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(4,74," ",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(4,91," ",MC_Black,MC_Light);
 | 
			
		||||
    // Partie droite
 | 
			
		||||
  Print_in_window(129,37," ",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(129,57," ",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(129,74," ",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(129,91," ",MC_Black,MC_Light);
 | 
			
		||||
 | 
			
		||||
  // Ensuite, on affiche la flèche là où il le faut:
 | 
			
		||||
  switch(mode)
 | 
			
		||||
@ -588,6 +594,9 @@ void Button_Colorize_display_selection(int mode)
 | 
			
		||||
      break;
 | 
			
		||||
    case 2 : // Méthode soustractive
 | 
			
		||||
      y_pos=74;
 | 
			
		||||
      break;
 | 
			
		||||
    case 3 : // Méthode alpha
 | 
			
		||||
      y_pos=91;
 | 
			
		||||
  }
 | 
			
		||||
  Print_in_window(4,y_pos,"\020",MC_Black,MC_Light);
 | 
			
		||||
  Print_in_window(129,y_pos,"\021",MC_Black,MC_Light);
 | 
			
		||||
@ -600,7 +609,7 @@ void Button_Colorize_menu(void)
 | 
			
		||||
  short clicked_button;
 | 
			
		||||
  char  str[4];
 | 
			
		||||
 | 
			
		||||
  Open_window(140,118,"Transparency");
 | 
			
		||||
  Open_window(140,135,"Transparency");
 | 
			
		||||
 | 
			
		||||
  Print_in_window(16,23,"Opacity:",MC_Dark,MC_Light);
 | 
			
		||||
  Window_set_input_button(87,21,3);                               // 1
 | 
			
		||||
@ -610,9 +619,10 @@ void Button_Colorize_menu(void)
 | 
			
		||||
 | 
			
		||||
  Window_set_normal_button(16,54,108,14,"Additive"   ,2,1,SDLK_d); // 3
 | 
			
		||||
  Window_set_normal_button(16,71,108,14,"Subtractive",1,1,SDLK_s); // 4
 | 
			
		||||
  Window_set_normal_button(16,88,108,14,"Alpha",1,1,SDLK_a); // 4
 | 
			
		||||
 | 
			
		||||
  Window_set_normal_button(16,94, 51,14,"Cancel"     ,0,1,KEY_ESC); // 5
 | 
			
		||||
  Window_set_normal_button(73,94, 51,14,"OK"         ,0,1,SDLK_RETURN); // 6
 | 
			
		||||
  Window_set_normal_button(16,111, 51,14,"Cancel"     ,0,1,KEY_ESC); // 5
 | 
			
		||||
  Window_set_normal_button(73,111, 51,14,"OK"         ,0,1,SDLK_RETURN); // 6
 | 
			
		||||
 | 
			
		||||
  Num2str(Colorize_opacity,str,3);
 | 
			
		||||
  Window_input_content(Window_special_button_list,str);
 | 
			
		||||
@ -632,7 +642,7 @@ void Button_Colorize_menu(void)
 | 
			
		||||
    {
 | 
			
		||||
      case 1: // Zone de saisie de l'opacité
 | 
			
		||||
        Num2str(chosen_opacity,str,3);
 | 
			
		||||
        Readline(89,23,str,3,1);
 | 
			
		||||
        Readline(89,23,str,3,INPUT_TYPE_INTEGER);
 | 
			
		||||
        chosen_opacity=atoi(str);
 | 
			
		||||
        // On corrige le pourcentage
 | 
			
		||||
        if (chosen_opacity>100)
 | 
			
		||||
@ -643,9 +653,10 @@ void Button_Colorize_menu(void)
 | 
			
		||||
        }
 | 
			
		||||
        Display_cursor();
 | 
			
		||||
        break;
 | 
			
		||||
      case 2: // Méthode interpolée
 | 
			
		||||
      case 3: // Méthode additive
 | 
			
		||||
      case 4: // Méthode soustractive
 | 
			
		||||
      case 2: // Interpolated method
 | 
			
		||||
      case 3: // Additive method
 | 
			
		||||
      case 4: // Substractive method
 | 
			
		||||
      case 5: // Alpha method
 | 
			
		||||
        selected_mode=clicked_button-2;
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Button_Colorize_display_selection(selected_mode);
 | 
			
		||||
@ -654,13 +665,13 @@ void Button_Colorize_menu(void)
 | 
			
		||||
    if (Is_shortcut(Key,0x100+BUTTON_HELP))
 | 
			
		||||
      Window_help(BUTTON_EFFECTS, "TRANSPARENCY");
 | 
			
		||||
      else if (Is_shortcut(Key,SPECIAL_COLORIZE_MENU))
 | 
			
		||||
        clicked_button=6;
 | 
			
		||||
        clicked_button=7;
 | 
			
		||||
  }
 | 
			
		||||
  while (clicked_button<5);
 | 
			
		||||
  while (clicked_button<6);
 | 
			
		||||
 | 
			
		||||
  Close_window();
 | 
			
		||||
 | 
			
		||||
  if (clicked_button==6) // OK
 | 
			
		||||
  if (clicked_button==7) // OK
 | 
			
		||||
  {
 | 
			
		||||
    Colorize_opacity      =chosen_opacity;
 | 
			
		||||
    Colorize_current_mode=selected_mode;
 | 
			
		||||
@ -724,7 +735,7 @@ void Button_Tiling_menu(void)
 | 
			
		||||
    if (clicked_button==3)  // Zone de saisie du décalage X
 | 
			
		||||
    {
 | 
			
		||||
      Num2str(chosen_offset_x,str,4);
 | 
			
		||||
      Readline(93,23,str,4,1);
 | 
			
		||||
      Readline(93,23,str,4,INPUT_TYPE_INTEGER);
 | 
			
		||||
      chosen_offset_x=atoi(str);
 | 
			
		||||
      // On corrige le décalage en X
 | 
			
		||||
      if (chosen_offset_x>=Brush_width)
 | 
			
		||||
@ -739,7 +750,7 @@ void Button_Tiling_menu(void)
 | 
			
		||||
    if (clicked_button==4)  // Zone de saisie du décalage Y
 | 
			
		||||
    {
 | 
			
		||||
      Num2str(chosen_offset_y,str,4);
 | 
			
		||||
      Readline(93,37,str,4,1);
 | 
			
		||||
      Readline(93,37,str,4,INPUT_TYPE_INTEGER);
 | 
			
		||||
      chosen_offset_y=atoi(str);
 | 
			
		||||
      // On corrige le décalage en Y
 | 
			
		||||
      if (chosen_offset_y>=Brush_height)
 | 
			
		||||
@ -975,8 +986,8 @@ void Button_Sieve_menu(void)
 | 
			
		||||
  {
 | 
			
		||||
    clicked_button=Window_clicked_button();
 | 
			
		||||
 | 
			
		||||
  origin_x=Window_pos_X+(Menu_factor_X*Window_special_button_list->Pos_X);
 | 
			
		||||
  origin_y=Window_pos_Y+(Menu_factor_Y*Window_special_button_list->Pos_Y);
 | 
			
		||||
    origin_x=Window_pos_X+(Menu_factor_X*Window_special_button_list->Pos_X);
 | 
			
		||||
    origin_y=Window_pos_Y+(Menu_factor_Y*Window_special_button_list->Pos_Y);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    switch (clicked_button)
 | 
			
		||||
@ -1063,15 +1074,22 @@ void Button_Sieve_menu(void)
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case  7 : // Transfer to brush
 | 
			
		||||
        Brush_width=Sieve_width;
 | 
			
		||||
        Brush_height=Sieve_height;
 | 
			
		||||
        free(Brush);
 | 
			
		||||
        Brush=(byte *)malloc(((long)Brush_height)*Brush_width);
 | 
			
		||||
      
 | 
			
		||||
        if (Realloc_brush(Sieve_width, Sieve_height, NULL, NULL))
 | 
			
		||||
          break;
 | 
			
		||||
        
 | 
			
		||||
        for (y_pos=0; y_pos<Sieve_height; y_pos++)
 | 
			
		||||
          for (x_pos=0; x_pos<Sieve_width; x_pos++)
 | 
			
		||||
            Pixel_in_brush(x_pos,y_pos,(Sieve[x_pos][y_pos])?Fore_color:Back_color);
 | 
			
		||||
            *(Brush_original_pixels + y_pos * Brush_width + x_pos) = (Sieve[x_pos][y_pos])?Fore_color:Back_color;
 | 
			
		||||
        
 | 
			
		||||
        // Grab palette
 | 
			
		||||
        memcpy(Brush_original_palette, Main_palette,sizeof(T_Palette));
 | 
			
		||||
        // Remap (no change)
 | 
			
		||||
        Remap_brush();
 | 
			
		||||
 | 
			
		||||
        Brush_offset_X=(Brush_width>>1);
 | 
			
		||||
        Brush_offset_Y=(Brush_height>>1);
 | 
			
		||||
        
 | 
			
		||||
        Change_paintbrush_shape(PAINTBRUSH_SHAPE_COLOR_BRUSH);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								src/const.h
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								src/const.h
									
									
									
									
									
								
							@ -37,7 +37,6 @@
 | 
			
		||||
#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              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.
 | 
			
		||||
@ -45,9 +44,10 @@
 | 
			
		||||
#define CURSOR_SPRITE_WIDTH       15    ///< Width of a mouse cursor sprite.
 | 
			
		||||
#define CURSOR_SPRITE_HEIGHT      15    ///< Height of a mouse cursor sprite.
 | 
			
		||||
#define NB_EFFECTS_SPRITES        9     ///< Number of effect sprites.
 | 
			
		||||
#define NB_MENU_SPRITES           20    ///< Number of menu sprites.
 | 
			
		||||
#define MENU_SPRITE_WIDTH         14    ///< Width of a menu sprite in pixels
 | 
			
		||||
#define MENU_SPRITE_HEIGHT        14    ///< Height of a menu sprite in pixels
 | 
			
		||||
#define MENU_SPRITE_WIDTH         16    ///< Width of a menu sprite in pixels
 | 
			
		||||
#define MENU_SPRITE_HEIGHT        16    ///< Height of a menu sprite in pixels
 | 
			
		||||
#define EFFECT_SPRITE_WIDTH       14    ///< Width of an effect sprite in pixels
 | 
			
		||||
#define EFFECT_SPRITE_HEIGHT      14    ///< Height of an effect sprite in pixels
 | 
			
		||||
#define LAYER_SPRITE_WIDTH        14    ///< Width of a layer button in pixels
 | 
			
		||||
#define LAYER_SPRITE_HEIGHT       10    ///< Height of a layer button in pixels
 | 
			
		||||
#define PAINTBRUSH_WIDTH          16    ///< Width of a preset paintbrush sprite
 | 
			
		||||
@ -120,6 +120,7 @@ enum FILE_FORMATS
 | 
			
		||||
  FORMAT_KCF,
 | 
			
		||||
  FORMAT_PAL,
 | 
			
		||||
  FORMAT_SCR,
 | 
			
		||||
  FORMAT_XPM,
 | 
			
		||||
  FORMAT_MISC, ///< Must be last of enum: others formats recognized by SDL_image
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -210,9 +211,17 @@ enum PAINTBRUSH_SHAPES
 | 
			
		||||
  PAINTBRUSH_SHAPE_DIAMOND,
 | 
			
		||||
  PAINTBRUSH_SHAPE_SIEVE_ROUND,
 | 
			
		||||
  PAINTBRUSH_SHAPE_SIEVE_SQUARE,
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED1,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED2,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED3,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED4,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED5,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED6,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED7,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_RESERVED8,   ///< Reserved for future use
 | 
			
		||||
  PAINTBRUSH_SHAPE_MISC,        ///< A raw monochrome bitmap, can't be resized. This must be the last of the preset paintbrush types.
 | 
			
		||||
  PAINTBRUSH_SHAPE_POINT,       ///< Used to reduce the paintbrush to a single pixel, during operations like floodfill.
 | 
			
		||||
  PAINTBRUSH_SHAPE_NONE, ///< Used to display no cursor at all (colorpicker)
 | 
			
		||||
  PAINTBRUSH_SHAPE_NONE,        ///< Used to display no cursor at all (colorpicker)
 | 
			
		||||
  PAINTBRUSH_SHAPE_COLOR_BRUSH, ///< User's brush, in color mode
 | 
			
		||||
  PAINTBRUSH_SHAPE_MONO_BRUSH,  ///< User's brush, in mono mode
 | 
			
		||||
  PAINTBRUSH_SHAPE_MAX          ///< Upper limit.
 | 
			
		||||
@ -222,6 +231,8 @@ enum PAINTBRUSH_SHAPES
 | 
			
		||||
#define BUTTON_RELEASED 0
 | 
			
		||||
/// State of a menu button that is being pressed.
 | 
			
		||||
#define BUTTON_PRESSED  1
 | 
			
		||||
/// State of a button temporarily highligted
 | 
			
		||||
#define BUTTON_HIGHLIGHTED 2
 | 
			
		||||
 | 
			
		||||
/// The different modes of the Shade
 | 
			
		||||
enum SHADE_MODES
 | 
			
		||||
@ -243,7 +254,9 @@ enum CHUNKS_CFG
 | 
			
		||||
  CHUNK_SMOOTH          = 6, ///< Smooth effect settings
 | 
			
		||||
  CHUNK_EXCLUDE_COLORS  = 7, ///< List of excluded colors
 | 
			
		||||
  CHUNK_QUICK_SHADE     = 8, ///< QShade effect settings
 | 
			
		||||
  CHUNK_GRID            = 9,
 | 
			
		||||
  CHUNK_GRID            = 9, ///< Grid settings
 | 
			
		||||
  CHUNK_BRUSH           =10, ///< Paintbrushes
 | 
			
		||||
  CHUNK_SCRIPTS         =11, ///< Callable scripts
 | 
			
		||||
  CHUNK_MAX
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -257,7 +270,8 @@ enum ICON_TYPES
 | 
			
		||||
  ICON_NETWORK,      ///< "Network" drive
 | 
			
		||||
  ICON_STAR,         ///< Star (favorite)
 | 
			
		||||
  ICON_DROPDOWN,     ///< Dropdown arrow
 | 
			
		||||
  NB_ICON_SPRITES    ///< Number of 8x8 icons
 | 
			
		||||
  NB_ICON_SPRITES,   ///< Number of 8x8 icons
 | 
			
		||||
  ICON_NONE          ///< None of the above
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Identifiers for the buttons in the menu.
 | 
			
		||||
@ -316,6 +330,24 @@ enum BUTTON_NUMBERS
 | 
			
		||||
  NB_BUTTONS            ///< Number of buttons in the menu bar.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum MENU_SPRITE
 | 
			
		||||
{
 | 
			
		||||
  MENU_SPRITE_COLOR_BRUSH=0,
 | 
			
		||||
  MENU_SPRITE_MONO_BRUSH,
 | 
			
		||||
  MENU_SPRITE_DISCONTINUOUS_DRAW,
 | 
			
		||||
  MENU_SPRITE_POINT_DRAW,
 | 
			
		||||
  MENU_SPRITE_CONTOUR_DRAW,
 | 
			
		||||
  MENU_SPRITE_4_POINTS_CURVE,
 | 
			
		||||
  MENU_SPRITE_K_LINE,
 | 
			
		||||
  MENU_SPRITE_CENTERED_LINES,
 | 
			
		||||
  MENU_SPRITE_ELLIPSES,
 | 
			
		||||
  MENU_SPRITE_POLYFORM,
 | 
			
		||||
  MENU_SPRITE_REPLACE,
 | 
			
		||||
  MENU_SPRITE_GRAD_ELLIPSE,
 | 
			
		||||
  MENU_SPRITE_VERTICAL_PALETTE_SCROLL,
 | 
			
		||||
  NB_MENU_SPRITES ///< Number of menu sprites.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Identifiers of special actions that can have a keyboard shortcut.
 | 
			
		||||
/// They are special in the sense that there's no button in the menu for them,
 | 
			
		||||
@ -364,6 +396,10 @@ enum SPECIAL_ACTIONS
 | 
			
		||||
  SPECIAL_GET_BRUSH_COLORS,
 | 
			
		||||
  SPECIAL_RECOLORIZE_BRUSH,
 | 
			
		||||
  SPECIAL_ROTATE_ANY_ANGLE,
 | 
			
		||||
  SPECIAL_BRUSH_DOUBLE,
 | 
			
		||||
  SPECIAL_BRUSH_DOUBLE_WIDTH,
 | 
			
		||||
  SPECIAL_BRUSH_DOUBLE_HEIGHT,
 | 
			
		||||
  SPECIAL_BRUSH_HALVE,
 | 
			
		||||
  SPECIAL_LOAD_BRUSH,
 | 
			
		||||
  SPECIAL_SAVE_BRUSH,
 | 
			
		||||
  SPECIAL_INVERT_SIEVE,
 | 
			
		||||
@ -435,8 +471,22 @@ enum SPECIAL_ACTIONS
 | 
			
		||||
  SPECIAL_LAYER7_TOGGLE,
 | 
			
		||||
  SPECIAL_LAYER8_SELECT,
 | 
			
		||||
  SPECIAL_LAYER8_TOGGLE,
 | 
			
		||||
  SPECIAL_REPEAT_SCRIPT,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_1,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_2,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_3,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_4,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_5,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_6,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_7,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_8,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_9,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_10,
 | 
			
		||||
  SPECIAL_CYCLE_MODE,
 | 
			
		||||
 | 
			
		||||
  SPECIAL_FORMAT_CHECKER,
 | 
			
		||||
  SPECIAL_FORMAT_CHECKER_MENU,
 | 
			
		||||
 | 
			
		||||
  NB_SPECIAL_SHORTCUTS            ///< Number of special shortcuts
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -448,7 +498,7 @@ enum OPERATIONS
 | 
			
		||||
  OPERATION_POINT_DRAW,        ///< Freehand point-by-point draw
 | 
			
		||||
  OPERATION_FILLED_CONTOUR,    ///< Filled contour
 | 
			
		||||
  OPERATION_LINE,              ///< Lines
 | 
			
		||||
  OPERATION_K_LIGNE,           ///< Linked lines
 | 
			
		||||
  OPERATION_K_LINE,            ///< Linked lines
 | 
			
		||||
  OPERATION_CENTERED_LINES,    ///< Centered lines
 | 
			
		||||
  OPERATION_EMPTY_RECTANGLE,   ///< Empty rectangle
 | 
			
		||||
  OPERATION_FILLED_RECTANGLE,  ///< Filled rectangle
 | 
			
		||||
@ -476,6 +526,7 @@ enum OPERATIONS
 | 
			
		||||
  OPERATION_STRETCH_BRUSH,     ///< Stretch brush
 | 
			
		||||
  OPERATION_DISTORT_BRUSH,     ///< Distort brush
 | 
			
		||||
  OPERATION_GRAD_RECTANGLE,    ///< Gradient-filled rectangle
 | 
			
		||||
  OPERATION_RMB_COLORPICK,     ///< Colorpick on right mouse button
 | 
			
		||||
  NB_OPERATIONS                ///< Number of operations handled by the engine
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										664
									
								
								src/engine.c
									
									
									
									
									
								
							
							
						
						
									
										664
									
								
								src/engine.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								src/engine.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/engine.h
									
									
									
									
									
								
							@ -30,7 +30,7 @@
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
 | 
			
		||||
void Main_handler          (void);
 | 
			
		||||
void Draw_menu_button_frame(byte btn_number,byte pressed);
 | 
			
		||||
void Draw_menu_button      (byte btn_number,byte pressed);
 | 
			
		||||
void Unselect_button       (int btn_number);
 | 
			
		||||
void Select_button         (int btn_number,byte click);
 | 
			
		||||
void Open_window           (word width,word height, const char * title);
 | 
			
		||||
@ -40,25 +40,25 @@ void Open_popup            (word x_pos, word y_pos, word width, word height);
 | 
			
		||||
void Close_popup           (void);
 | 
			
		||||
 | 
			
		||||
void Window_draw_normal_bouton(word x_pos,word y_pos,word width,word height,
 | 
			
		||||
  char * title,byte undersc_letter,byte clickable);
 | 
			
		||||
  const char * title,byte undersc_letter,byte clickable);
 | 
			
		||||
void Window_select_normal_button(word x_pos,word y_pos,word width,word height);
 | 
			
		||||
void Window_unselect_normal_button(word x_pos,word y_pos,word width,word height);
 | 
			
		||||
void Window_draw_palette_bouton(word x_pos,word y_pos);
 | 
			
		||||
 | 
			
		||||
void Compute_slider_cursor_height(T_Scroller_button * button);
 | 
			
		||||
void Compute_slider_cursor_length(T_Scroller_button * button);
 | 
			
		||||
void Window_draw_slider(T_Scroller_button * button);
 | 
			
		||||
void Window_draw_scroller_bouton(T_Scroller_button * button);
 | 
			
		||||
void Window_draw_scroller_button(T_Scroller_button * button);
 | 
			
		||||
 | 
			
		||||
void Window_input_content(T_Special_button * button, char * content);
 | 
			
		||||
void Window_clear_input_button(T_Special_button * button);
 | 
			
		||||
void Window_draw_input_bouton(word x_pos, word y_pos, word width_in_characters);
 | 
			
		||||
 | 
			
		||||
T_Normal_button * Window_set_normal_button(word x_pos, word y_pos,
 | 
			
		||||
  word width, word height, char * title, byte undersc_letter,
 | 
			
		||||
  word width, word height, const char * title, byte undersc_letter,
 | 
			
		||||
  byte clickable, word shortcut);
 | 
			
		||||
 | 
			
		||||
T_Normal_button * Window_set_repeatable_button(word x_pos, word y_pos,
 | 
			
		||||
  word width, word height, char * title, byte undersc_letter,
 | 
			
		||||
  word width, word height, const char * title, byte undersc_letter,
 | 
			
		||||
  byte clickable, word shortcut);
 | 
			
		||||
 | 
			
		||||
T_Palette_button * Window_set_palette_button(word x_pos, word y_pos);
 | 
			
		||||
@ -69,6 +69,10 @@ T_Scroller_button * Window_set_scroller_button(word x_pos, word y_pos,
 | 
			
		||||
  word height, word nb_elements, word nb_elements_visible,
 | 
			
		||||
  word initial_position);
 | 
			
		||||
 | 
			
		||||
T_Scroller_button * Window_set_horizontal_scroller_button(word x_pos, word y_pos,
 | 
			
		||||
  word height, word nb_elements, word nb_elements_visible,
 | 
			
		||||
  word initial_position);
 | 
			
		||||
 | 
			
		||||
T_Special_button * Window_set_special_button(word x_pos, word y_pos, word width,
 | 
			
		||||
  word height);
 | 
			
		||||
 | 
			
		||||
@ -111,4 +115,9 @@ void Pixel_background(int x_pos, int y_pos, byte color);
 | 
			
		||||
/// Updates the status bar line with a color number.
 | 
			
		||||
/// Used when hovering the menu palette.
 | 
			
		||||
void Status_print_palette_color(byte color);
 | 
			
		||||
 | 
			
		||||
/// Puts the user in wait mode for the specified time ( in 1/100s),
 | 
			
		||||
/// though the mouse still works.
 | 
			
		||||
void Delay_with_active_mouse(int delay);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1036
									
								
								src/factory.c
									
									
									
									
									
								
							
							
						
						
									
										1036
									
								
								src/factory.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,3 +1,13 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
void Button_Brush_Factory(void);
 | 
			
		||||
void Repeat_script(void);
 | 
			
		||||
 | 
			
		||||
/// Lua scripts bound to shortcut keys.
 | 
			
		||||
extern char * Bound_script[10];
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Run a lua script linked to a shortcut, 0-9.
 | 
			
		||||
/// Before: Cursor hidden
 | 
			
		||||
/// After: Cursor shown
 | 
			
		||||
void Run_numbered_script(byte index);
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2009 Petter Lindquist
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -27,6 +28,19 @@
 | 
			
		||||
 | 
			
		||||
#ifndef __no_pnglib__
 | 
			
		||||
#include <png.h>
 | 
			
		||||
#if (PNG_LIBPNG_VER_MAJOR <= 1) && (PNG_LIBPNG_VER_MINOR < 4)
 | 
			
		||||
  // Compatibility layer to allow us to use libng 1.4 or any older one.
 | 
			
		||||
  
 | 
			
		||||
  // This function is renamed in 1.4
 | 
			
		||||
  #define png_set_expand_gray_1_2_4_to_8(x) png_set_gray_1_2_4_to_8(x)
 | 
			
		||||
  
 | 
			
		||||
  // Wrappers that are mandatory in 1.4. Older version allowed direct access.
 | 
			
		||||
  #define png_get_rowbytes(png_ptr,info_ptr) ((info_ptr)->rowbytes)
 | 
			
		||||
  #define png_get_image_width(png_ptr,info_ptr) ((info_ptr)->width)
 | 
			
		||||
  #define png_get_image_height(png_ptr,info_ptr) ((info_ptr)->height)
 | 
			
		||||
  #define png_get_bit_depth(png_ptr,info_ptr) ((info_ptr)->bit_depth)
 | 
			
		||||
  #define png_get_color_type(png_ptr,info_ptr) ((info_ptr)->color_type)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@ -59,11 +73,11 @@ void Test_IMG(T_IO_Context * context)
 | 
			
		||||
  if ((file=fopen(filename, "rb")))
 | 
			
		||||
  {
 | 
			
		||||
    // Lecture et vérification de la signature
 | 
			
		||||
    if (Read_bytes(file,IMG_header.Filler1,sizeof(IMG_header.Filler1))
 | 
			
		||||
    if (Read_bytes(file,IMG_header.Filler1,6)
 | 
			
		||||
    && Read_word_le(file,&(IMG_header.Width))
 | 
			
		||||
    && Read_word_le(file,&(IMG_header.Height))
 | 
			
		||||
    && Read_bytes(file,IMG_header.Filler2,sizeof(IMG_header.Filler2))
 | 
			
		||||
    && Read_bytes(file,IMG_header.Palette,sizeof(IMG_header.Palette))
 | 
			
		||||
    && Read_bytes(file,IMG_header.Filler2,118)
 | 
			
		||||
    && Read_bytes(file,IMG_header.Palette,sizeof(T_Palette))
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
      if ( (!memcmp(IMG_header.Filler1,signature,6))
 | 
			
		||||
@ -94,11 +108,11 @@ void Load_IMG(T_IO_Context * context)
 | 
			
		||||
  {
 | 
			
		||||
    file_size=File_length_file(file);
 | 
			
		||||
 | 
			
		||||
    if (Read_bytes(file,IMG_header.Filler1,sizeof(IMG_header.Filler1))
 | 
			
		||||
    if (Read_bytes(file,IMG_header.Filler1,6)
 | 
			
		||||
    && Read_word_le(file,&(IMG_header.Width))
 | 
			
		||||
    && Read_word_le(file,&(IMG_header.Height))
 | 
			
		||||
    && Read_bytes(file,IMG_header.Filler2,sizeof(IMG_header.Filler2))
 | 
			
		||||
    && Read_bytes(file,IMG_header.Palette,sizeof(IMG_header.Palette))
 | 
			
		||||
    && Read_bytes(file,IMG_header.Filler2,118)
 | 
			
		||||
    && Read_bytes(file,IMG_header.Palette,sizeof(T_Palette))
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -167,11 +181,11 @@ void Save_IMG(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
    memcpy(IMG_header.Palette,context->Palette,sizeof(T_Palette));
 | 
			
		||||
 | 
			
		||||
    if (Write_bytes(file,IMG_header.Filler1,sizeof(IMG_header.Filler1))
 | 
			
		||||
    if (Write_bytes(file,IMG_header.Filler1,6)
 | 
			
		||||
    && Write_word_le(file,IMG_header.Width)
 | 
			
		||||
    && Write_word_le(file,IMG_header.Height)
 | 
			
		||||
    && Write_bytes(file,IMG_header.Filler2,sizeof(IMG_header.Filler2))
 | 
			
		||||
    && Write_bytes(file,IMG_header.Palette,sizeof(IMG_header.Palette))
 | 
			
		||||
    && Write_bytes(file,IMG_header.Filler2,118)
 | 
			
		||||
    && Write_bytes(file,IMG_header.Palette,sizeof(T_Palette))
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
@ -204,7 +218,6 @@ void Save_IMG(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// LBM ////////////////////////////////////
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  word  Width;
 | 
			
		||||
@ -221,7 +234,6 @@ typedef struct
 | 
			
		||||
  word  X_screen;
 | 
			
		||||
  word  Y_screen;
 | 
			
		||||
} T_LBM_Header;
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
byte * LBM_buffer;
 | 
			
		||||
FILE *LBM_file;
 | 
			
		||||
@ -375,28 +387,42 @@ void Test_LBM(T_IO_Context * context)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // ------------------------- Attendre une section -------------------------
 | 
			
		||||
  byte Wait_for(byte * expected_section)
 | 
			
		||||
  {
 | 
			
		||||
    // Valeur retournée: 1=Section trouvée, 0=Section non trouvée (erreur)
 | 
			
		||||
    dword Taille_section;
 | 
			
		||||
    byte section_read[4];
 | 
			
		||||
// Inspired by Allegro: storing a 4-character identifier as a 32bit litteral
 | 
			
		||||
#define ID4(a,b,c,d) ((((a)&255)<<24) | (((b)&255)<<16) | (((c)&255)<<8) | (((d)&255)))
 | 
			
		||||
 | 
			
		||||
/// Skips the current section in an ILBM file.
 | 
			
		||||
/// This function should be called while the file pointer is right
 | 
			
		||||
/// after the 4-character code that identifies the section.
 | 
			
		||||
int LBM_Skip_section(void)
 | 
			
		||||
{
 | 
			
		||||
  dword size;
 | 
			
		||||
  
 | 
			
		||||
  if (!Read_dword_be(LBM_file,&size))
 | 
			
		||||
    return 0;
 | 
			
		||||
  if (size&1)
 | 
			
		||||
    size++;
 | 
			
		||||
  if (fseek(LBM_file,size,SEEK_CUR))
 | 
			
		||||
    return 0;
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------------------- Attendre une section -------------------------
 | 
			
		||||
byte LBM_Wait_for(byte * expected_section)
 | 
			
		||||
{
 | 
			
		||||
  // Valeur retournée: 1=Section trouvée, 0=Section non trouvée (erreur)
 | 
			
		||||
  byte section_read[4];
 | 
			
		||||
 | 
			
		||||
  if (! Read_bytes(LBM_file,section_read,4))
 | 
			
		||||
    return 0;
 | 
			
		||||
  while (memcmp(section_read,expected_section,4)) // Sect. pas encore trouvée
 | 
			
		||||
  {
 | 
			
		||||
    if (!LBM_Skip_section())
 | 
			
		||||
      return 0;
 | 
			
		||||
    if (! Read_bytes(LBM_file,section_read,4))
 | 
			
		||||
      return 0;
 | 
			
		||||
    while (memcmp(section_read,expected_section,4)) // Sect. pas encore trouvée
 | 
			
		||||
    {
 | 
			
		||||
      if (!Read_dword_be(LBM_file,&Taille_section))
 | 
			
		||||
        return 0;
 | 
			
		||||
      if (Taille_section&1)
 | 
			
		||||
        Taille_section++;
 | 
			
		||||
      if (fseek(LBM_file,Taille_section,SEEK_CUR))
 | 
			
		||||
        return 0;
 | 
			
		||||
      if (! Read_bytes(LBM_file,section_read,4))
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Les images ILBM sont stockés en bitplanes donc on doit trifouiller les bits pour
 | 
			
		||||
// en faire du chunky
 | 
			
		||||
@ -509,7 +535,7 @@ void Load_LBM(T_IO_Context * context)
 | 
			
		||||
  byte  temp_byte;
 | 
			
		||||
  short b256;
 | 
			
		||||
  dword nb_colors;
 | 
			
		||||
  dword image_size;
 | 
			
		||||
  dword section_size;
 | 
			
		||||
  short x_pos;
 | 
			
		||||
  short y_pos;
 | 
			
		||||
  short counter;
 | 
			
		||||
@ -531,7 +557,7 @@ void Load_LBM(T_IO_Context * context)
 | 
			
		||||
    Read_bytes(LBM_file,section,4);
 | 
			
		||||
    Read_dword_be(LBM_file,&dummy);
 | 
			
		||||
    Read_bytes(LBM_file,format,4);
 | 
			
		||||
    if (!Wait_for((byte *)"BMHD"))
 | 
			
		||||
    if (!LBM_Wait_for((byte *)"BMHD"))
 | 
			
		||||
      File_error=1;
 | 
			
		||||
    Read_dword_be(LBM_file,&dummy);
 | 
			
		||||
 | 
			
		||||
@ -551,7 +577,7 @@ void Load_LBM(T_IO_Context * context)
 | 
			
		||||
      && (Read_word_be(LBM_file,&header.Y_screen))
 | 
			
		||||
      && header.Width && header.Height)
 | 
			
		||||
    {
 | 
			
		||||
      if ( (header.BitPlanes) && (Wait_for((byte *)"CMAP")) )
 | 
			
		||||
      if ( (header.BitPlanes) && (LBM_Wait_for((byte *)"CMAP")) )
 | 
			
		||||
      {
 | 
			
		||||
        Read_dword_be(LBM_file,&nb_colors);
 | 
			
		||||
        nb_colors/=3;
 | 
			
		||||
@ -604,16 +630,73 @@ void Load_LBM(T_IO_Context * context)
 | 
			
		||||
              if (Read_byte(LBM_file,&temp_byte))
 | 
			
		||||
                File_error=2;
 | 
			
		||||
 | 
			
		||||
            if ( (Wait_for((byte *)"BODY")) && (!File_error) )
 | 
			
		||||
            // Keep reading sections until we find the body
 | 
			
		||||
            while (1)
 | 
			
		||||
            {
 | 
			
		||||
              Read_dword_be(LBM_file,&image_size);
 | 
			
		||||
              //swab((char *)&header.Width ,(char *)&context->Width,2);
 | 
			
		||||
              //swab((char *)&header.Height,(char *)&context->Height,2);
 | 
			
		||||
              if (! Read_bytes(LBM_file,section,4))
 | 
			
		||||
              {
 | 
			
		||||
                File_error=2;
 | 
			
		||||
                break;
 | 
			
		||||
              }
 | 
			
		||||
              // Found body : stop searching
 | 
			
		||||
              if (!memcmp(section,"BODY",4))
 | 
			
		||||
                break;
 | 
			
		||||
              else if (!memcmp(section,"CRNG",4))
 | 
			
		||||
              {
 | 
			
		||||
                // Handle CRNG
 | 
			
		||||
                
 | 
			
		||||
                // The content of a CRNG is as follows:
 | 
			
		||||
                word padding;
 | 
			
		||||
                word rate;
 | 
			
		||||
                word flags;
 | 
			
		||||
                byte min_col;
 | 
			
		||||
                byte max_col;
 | 
			
		||||
                //
 | 
			
		||||
                if ( (Read_dword_be(LBM_file,§ion_size))
 | 
			
		||||
                  && (Read_word_be(LBM_file,&padding))
 | 
			
		||||
                  && (Read_word_be(LBM_file,&rate))
 | 
			
		||||
                  && (Read_word_be(LBM_file,&flags))
 | 
			
		||||
                  && (Read_byte(LBM_file,&min_col))
 | 
			
		||||
                  && (Read_byte(LBM_file,&max_col)))
 | 
			
		||||
                {
 | 
			
		||||
                  if (section_size == 8 && min_col != max_col)
 | 
			
		||||
                  {
 | 
			
		||||
                    // Valid cycling range
 | 
			
		||||
                    if (max_col<min_col)
 | 
			
		||||
                    SWAP_BYTES(min_col,max_col)
 | 
			
		||||
                    
 | 
			
		||||
                    context->Cycle_range[context->Color_cycles].Start=min_col;
 | 
			
		||||
                    context->Cycle_range[context->Color_cycles].End=max_col;
 | 
			
		||||
                    context->Cycle_range[context->Color_cycles].Inverse=(flags&2)?1:0;
 | 
			
		||||
                    context->Cycle_range[context->Color_cycles].Speed=(flags&1) ? rate/78 : 0;
 | 
			
		||||
                                        
 | 
			
		||||
                    context->Color_cycles++;
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                  File_error=2;
 | 
			
		||||
                  break;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
              else
 | 
			
		||||
              {
 | 
			
		||||
                // ignore any number of unknown sections
 | 
			
		||||
                if (!LBM_Skip_section())
 | 
			
		||||
                {
 | 
			
		||||
                  File_error=2;
 | 
			
		||||
                  break;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
              
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( !File_error )
 | 
			
		||||
            {
 | 
			
		||||
              Read_dword_be(LBM_file,§ion_size);
 | 
			
		||||
              context->Width = header.Width;
 | 
			
		||||
              context->Height = header.Height;
 | 
			
		||||
 | 
			
		||||
              //swab((char *)&header.X_screen,(char *)&Original_screen_X,2);
 | 
			
		||||
              //swab((char *)&header.Y_screen,(char *)&Original_screen_Y,2);
 | 
			
		||||
              Original_screen_X = header.X_screen;
 | 
			
		||||
              Original_screen_Y = header.Y_screen;
 | 
			
		||||
 | 
			
		||||
@ -874,6 +957,7 @@ void Save_LBM(T_IO_Context * context)
 | 
			
		||||
  byte temp_byte;
 | 
			
		||||
  word real_width;
 | 
			
		||||
  int file_size;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  File_error=0;
 | 
			
		||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
			
		||||
@ -890,7 +974,6 @@ void Save_LBM(T_IO_Context * context)
 | 
			
		||||
    // On corrige la largeur de l'image pour qu'elle soit multiple de 2
 | 
			
		||||
    real_width=context->Width+(context->Width&1);
 | 
			
		||||
 | 
			
		||||
    //swab((byte *)&real_width,(byte *)&header.Width,2);
 | 
			
		||||
    header.Width=context->Width;
 | 
			
		||||
    header.Height=context->Height;
 | 
			
		||||
    header.X_org=0;
 | 
			
		||||
@ -923,7 +1006,23 @@ void Save_LBM(T_IO_Context * context)
 | 
			
		||||
    Write_dword_be(LBM_file,sizeof(T_Palette));
 | 
			
		||||
 | 
			
		||||
    Write_bytes(LBM_file,context->Palette,sizeof(T_Palette));
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    for (i=0; i<context->Color_cycles; i++)
 | 
			
		||||
    {
 | 
			
		||||
      word flags=0;
 | 
			
		||||
      flags|= context->Cycle_range[i].Speed?1:0; // Cycling or not
 | 
			
		||||
      flags|= context->Cycle_range[i].Inverse?2:0; // Inverted
 | 
			
		||||
              
 | 
			
		||||
      Write_bytes(LBM_file,"CRNG",4);
 | 
			
		||||
      Write_dword_be(LBM_file,8); // Section size
 | 
			
		||||
      Write_word_be(LBM_file,0); // Padding
 | 
			
		||||
      Write_word_be(LBM_file,context->Cycle_range[i].Speed*78); // Rate
 | 
			
		||||
      Write_word_be(LBM_file,flags); // Flags
 | 
			
		||||
      Write_byte(LBM_file,context->Cycle_range[i].Start); // Min color
 | 
			
		||||
      Write_byte(LBM_file,context->Cycle_range[i].End); // Max color
 | 
			
		||||
      // No padding, size is multiple of 2
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Write_bytes(LBM_file,"BODY",4);
 | 
			
		||||
    Write_dword_be(LBM_file,0); // On mettra la taille à jour à la fin
 | 
			
		||||
 | 
			
		||||
@ -948,8 +1047,8 @@ void Save_LBM(T_IO_Context * context)
 | 
			
		||||
      file_size=File_length(filename);
 | 
			
		||||
      
 | 
			
		||||
      LBM_file=fopen(filename,"rb+");
 | 
			
		||||
      fseek(LBM_file,820,SEEK_SET);
 | 
			
		||||
      Write_dword_be(LBM_file,file_size-824);
 | 
			
		||||
      fseek(LBM_file,820+context->Color_cycles*16,SEEK_SET);
 | 
			
		||||
      Write_dword_be(LBM_file,file_size-824-context->Color_cycles*16);
 | 
			
		||||
 | 
			
		||||
      if (!File_error)
 | 
			
		||||
      {
 | 
			
		||||
@ -1554,7 +1653,6 @@ void Save_BMP(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// GIF ////////////////////////////////////
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  word Width;   // Width of the complete image area
 | 
			
		||||
@ -1573,7 +1671,6 @@ typedef struct
 | 
			
		||||
  byte Indicator;     // Misc image information
 | 
			
		||||
  byte Nb_bits_pixel; // Nb de bits par pixel
 | 
			
		||||
} T_GIF_IDB;          // Image Descriptor Block
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
@ -1735,7 +1832,7 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
  word color_index; // index de traitement d'une couleur
 | 
			
		||||
  byte size_to_read; // Nombre de données à lire      (divers)
 | 
			
		||||
  byte block_identifier;  // Code indicateur du type de bloc en cours
 | 
			
		||||
  word initial_nb_bits;   // Nb de bits au début du traitement LZW
 | 
			
		||||
  byte initial_nb_bits;   // Nb de bits au début du traitement LZW
 | 
			
		||||
  word special_case=0;       // Mémoire pour le cas spécial
 | 
			
		||||
  word old_code=0;       // Code précédent
 | 
			
		||||
  word byte_read;         // Sauvegarde du code en cours de lecture
 | 
			
		||||
@ -1787,8 +1884,6 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
        // Ordre de Classement   = (LSDB.Aspect and $80)
 | 
			
		||||
 | 
			
		||||
        nb_colors=(1 << ((LSDB.Resol & 0x07)+1));
 | 
			
		||||
        initial_nb_bits=(LSDB.Resol & 0x07)+2;
 | 
			
		||||
 | 
			
		||||
        if (LSDB.Resol & 0x80)
 | 
			
		||||
        {
 | 
			
		||||
          // Palette globale dispo:
 | 
			
		||||
@ -1796,24 +1891,12 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
          if (Config.Clear_palette)
 | 
			
		||||
            memset(context->Palette,0,sizeof(T_Palette));
 | 
			
		||||
 | 
			
		||||
          //   On peut maintenant charger la nouvelle palette:
 | 
			
		||||
          if (!(LSDB.Aspect & 0x80))
 | 
			
		||||
            // Palette dans l'ordre:
 | 
			
		||||
            for(color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
            {
 | 
			
		||||
              Read_byte(GIF_file,&(context->Palette[color_index].R));
 | 
			
		||||
              Read_byte(GIF_file,&(context->Palette[color_index].G));
 | 
			
		||||
              Read_byte(GIF_file,&(context->Palette[color_index].B));
 | 
			
		||||
            }
 | 
			
		||||
          else
 | 
			
		||||
          // Load the palette
 | 
			
		||||
          for(color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
          {
 | 
			
		||||
            // Palette triée par composantes:
 | 
			
		||||
            for (color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
              Read_byte(GIF_file,&(context->Palette[color_index].R));
 | 
			
		||||
            for (color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
              Read_byte(GIF_file,&(context->Palette[color_index].G));
 | 
			
		||||
            for (color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
              Read_byte(GIF_file,&(context->Palette[color_index].B));
 | 
			
		||||
            Read_byte(GIF_file,&(context->Palette[color_index].R));
 | 
			
		||||
            Read_byte(GIF_file,&(context->Palette[color_index].G));
 | 
			
		||||
            Read_byte(GIF_file,&(context->Palette[color_index].B));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1924,6 +2007,57 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
                          }
 | 
			
		||||
                        }
 | 
			
		||||
                      }
 | 
			
		||||
                      else if (!memcmp(aeb,"CRNG\0\0\0\0" "1.0",0x0B))
 | 
			
		||||
                      {            
 | 
			
		||||
                        // Color animation. Similar to a LBM CRNG chunk.
 | 
			
		||||
                        word rate;
 | 
			
		||||
                        word flags;
 | 
			
		||||
                        byte min_col;
 | 
			
		||||
                        byte max_col;
 | 
			
		||||
                        //
 | 
			
		||||
                        Read_byte(GIF_file,&size_to_read);
 | 
			
		||||
                        for(;size_to_read>0 && !File_error;size_to_read-=6)
 | 
			
		||||
                        {
 | 
			
		||||
                          if ( (Read_word_be(GIF_file,&rate))
 | 
			
		||||
                            && (Read_word_be(GIF_file,&flags))
 | 
			
		||||
                            && (Read_byte(GIF_file,&min_col))
 | 
			
		||||
                            && (Read_byte(GIF_file,&max_col)))
 | 
			
		||||
                          {
 | 
			
		||||
                            if (min_col != max_col)
 | 
			
		||||
                            {
 | 
			
		||||
                              // Valid cycling range
 | 
			
		||||
                              if (max_col<min_col)
 | 
			
		||||
                              SWAP_BYTES(min_col,max_col)
 | 
			
		||||
                              
 | 
			
		||||
                              context->Cycle_range[context->Color_cycles].Start=min_col;
 | 
			
		||||
                              context->Cycle_range[context->Color_cycles].End=max_col;
 | 
			
		||||
                              context->Cycle_range[context->Color_cycles].Inverse=(flags&2)?1:0;
 | 
			
		||||
                              context->Cycle_range[context->Color_cycles].Speed=(flags&1)?rate/78:0;
 | 
			
		||||
                                                  
 | 
			
		||||
                              context->Color_cycles++;
 | 
			
		||||
                            }
 | 
			
		||||
                          }
 | 
			
		||||
                          else
 | 
			
		||||
                          {
 | 
			
		||||
                            File_error=1;
 | 
			
		||||
                          }
 | 
			
		||||
                        }
 | 
			
		||||
                        // Read end-of-block delimiter
 | 
			
		||||
                        if (!File_error)
 | 
			
		||||
                          Read_byte(GIF_file,&size_to_read);
 | 
			
		||||
                        if (size_to_read!=0)
 | 
			
		||||
                          File_error=1;
 | 
			
		||||
                      }
 | 
			
		||||
                      else
 | 
			
		||||
                      {
 | 
			
		||||
                        // Unknown extension, skip.
 | 
			
		||||
                        Read_byte(GIF_file,&size_to_read);
 | 
			
		||||
                        while (size_to_read!=0 && !File_error)
 | 
			
		||||
                        {
 | 
			
		||||
                          fseek(GIF_file,size_to_read,SEEK_CUR);
 | 
			
		||||
                          Read_byte(GIF_file,&size_to_read);
 | 
			
		||||
                        }
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
@ -1961,7 +2095,6 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
                && Read_word_le(GIF_file,&(IDB.Image_width))
 | 
			
		||||
                && Read_word_le(GIF_file,&(IDB.Image_height))
 | 
			
		||||
                && Read_byte(GIF_file,&(IDB.Indicator))
 | 
			
		||||
                && Read_byte(GIF_file,&(IDB.Nb_bits_pixel))
 | 
			
		||||
                && IDB.Image_width && IDB.Image_height)
 | 
			
		||||
              {
 | 
			
		||||
    
 | 
			
		||||
@ -1974,42 +2107,38 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
                {
 | 
			
		||||
                  // Palette locale dispo
 | 
			
		||||
    
 | 
			
		||||
                  if (Config.Clear_palette)
 | 
			
		||||
                    memset(context->Palette,0,sizeof(T_Palette));
 | 
			
		||||
 | 
			
		||||
                  nb_colors=(1 << ((IDB.Indicator & 0x07)+1));
 | 
			
		||||
                  initial_nb_bits=(IDB.Indicator & 0x07)+2;
 | 
			
		||||
    
 | 
			
		||||
                  if (!(IDB.Indicator & 0x40))
 | 
			
		||||
                    // Palette dans l'ordre:
 | 
			
		||||
                    for(color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
                    {   
 | 
			
		||||
                      Read_byte(GIF_file,&(context->Palette[color_index].R));
 | 
			
		||||
                      Read_byte(GIF_file,&(context->Palette[color_index].G));
 | 
			
		||||
                      Read_byte(GIF_file,&(context->Palette[color_index].B));
 | 
			
		||||
                    }
 | 
			
		||||
                  else
 | 
			
		||||
                  {
 | 
			
		||||
                    // Palette triée par composantes:
 | 
			
		||||
                    for (color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
                      Read_byte(GIF_file,&(context->Palette[color_index].R));
 | 
			
		||||
                    for (color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
                      Read_byte(GIF_file,&(context->Palette[color_index].G));
 | 
			
		||||
                    for (color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
                      Read_byte(GIF_file,&(context->Palette[color_index].B));
 | 
			
		||||
                  // Load the palette
 | 
			
		||||
                  for(color_index=0;color_index<nb_colors;color_index++)
 | 
			
		||||
                  {   
 | 
			
		||||
                    Read_byte(GIF_file,&(context->Palette[color_index].R));
 | 
			
		||||
                    Read_byte(GIF_file,&(context->Palette[color_index].G));
 | 
			
		||||
                    Read_byte(GIF_file,&(context->Palette[color_index].B));
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                }
 | 
			
		||||
    
 | 
			
		||||
                Palette_loaded(context);
 | 
			
		||||
 | 
			
		||||
                File_error=0;
 | 
			
		||||
                if (!Read_byte(GIF_file,&(initial_nb_bits)))
 | 
			
		||||
                  File_error=1;
 | 
			
		||||
    
 | 
			
		||||
                value_clr   =nb_colors+0;
 | 
			
		||||
                value_eof   =nb_colors+1;
 | 
			
		||||
                alphabet_free=nb_colors+2;
 | 
			
		||||
                GIF_nb_bits  =initial_nb_bits;
 | 
			
		||||
                value_clr    =(1<<initial_nb_bits)+0;
 | 
			
		||||
                value_eof    =(1<<initial_nb_bits)+1;
 | 
			
		||||
                alphabet_free=(1<<initial_nb_bits)+2;
 | 
			
		||||
 | 
			
		||||
                GIF_nb_bits  =initial_nb_bits + 1;
 | 
			
		||||
                alphabet_max      =((1 <<  GIF_nb_bits)-1);
 | 
			
		||||
                GIF_interlaced    =(IDB.Indicator & 0x40);
 | 
			
		||||
                GIF_pass         =0;
 | 
			
		||||
    
 | 
			
		||||
                /*Init_lecture();*/
 | 
			
		||||
    
 | 
			
		||||
                File_error=0;
 | 
			
		||||
 | 
			
		||||
                GIF_finished_interlaced_image=0;
 | 
			
		||||
    
 | 
			
		||||
                //////////////////////////////////////////// DECOMPRESSION LZW //
 | 
			
		||||
@ -2057,9 +2186,9 @@ void Load_GIF(T_IO_Context * context)
 | 
			
		||||
                    }
 | 
			
		||||
                    else // Code Clear rencontré
 | 
			
		||||
                    {
 | 
			
		||||
                      GIF_nb_bits       =initial_nb_bits;
 | 
			
		||||
                      GIF_nb_bits       =initial_nb_bits + 1;
 | 
			
		||||
                      alphabet_max      =((1 <<  GIF_nb_bits)-1);
 | 
			
		||||
                      alphabet_free     =nb_colors+2;
 | 
			
		||||
                      alphabet_free     =(1<<initial_nb_bits)+2;
 | 
			
		||||
                      special_case       =GIF_get_next_code();
 | 
			
		||||
                      old_code       =GIF_current_code;
 | 
			
		||||
                      GIF_new_pixel(context, &IDB, GIF_current_code);
 | 
			
		||||
@ -2251,15 +2380,19 @@ void Save_GIF(T_IO_Context * context)
 | 
			
		||||
          Write_byte(GIF_file,LSDB.Aspect) )
 | 
			
		||||
      {
 | 
			
		||||
        // Le LSDB a été correctement écrit.
 | 
			
		||||
 | 
			
		||||
        int i;
 | 
			
		||||
        // On sauve la palette
 | 
			
		||||
        if (Write_bytes(GIF_file,context->Palette,768))
 | 
			
		||||
        for(i=0;i<256 && !File_error;i++)
 | 
			
		||||
        {
 | 
			
		||||
          if (!Write_byte(GIF_file,context->Palette[i].R)
 | 
			
		||||
            ||!Write_byte(GIF_file,context->Palette[i].G)
 | 
			
		||||
            ||!Write_byte(GIF_file,context->Palette[i].B))
 | 
			
		||||
            File_error=1;
 | 
			
		||||
        }
 | 
			
		||||
        if (!File_error)
 | 
			
		||||
        {
 | 
			
		||||
          // La palette a été correctement écrite.
 | 
			
		||||
 | 
			
		||||
          //   Le jour où on se servira des blocks d'extensions pour placer
 | 
			
		||||
          // des commentaires, on le fera ici.
 | 
			
		||||
 | 
			
		||||
          // Ecriture de la transparence
 | 
			
		||||
          //Write_bytes(GIF_file,"\x21\xF9\x04\x01\x00\x00\xNN\x00",8);
 | 
			
		||||
 | 
			
		||||
@ -2275,6 +2408,26 @@ void Save_GIF(T_IO_Context * context)
 | 
			
		||||
            Write_byte(GIF_file,strlen(context->Comment));
 | 
			
		||||
            Write_bytes(GIF_file,context->Comment,strlen(context->Comment)+1);
 | 
			
		||||
          }
 | 
			
		||||
          // Write cycling colors
 | 
			
		||||
          if (context->Color_cycles)
 | 
			
		||||
          {
 | 
			
		||||
            int i;
 | 
			
		||||
            
 | 
			
		||||
            Write_bytes(GIF_file,"\x21\xff\x0B" "CRNG\0\0\0\0" "1.0",14);
 | 
			
		||||
            Write_byte(GIF_file,context->Color_cycles*6);
 | 
			
		||||
            for (i=0; i<context->Color_cycles; i++)
 | 
			
		||||
            {
 | 
			
		||||
              word flags=0;
 | 
			
		||||
              flags|= context->Cycle_range[i].Speed?1:0; // Cycling or not
 | 
			
		||||
              flags|= context->Cycle_range[i].Inverse?2:0; // Inverted
 | 
			
		||||
              
 | 
			
		||||
              Write_word_be(GIF_file,context->Cycle_range[i].Speed*78); // Rate
 | 
			
		||||
              Write_word_be(GIF_file,flags); // Flags
 | 
			
		||||
              Write_byte(GIF_file,context->Cycle_range[i].Start); // Min color
 | 
			
		||||
              Write_byte(GIF_file,context->Cycle_range[i].End); // Max color
 | 
			
		||||
            }
 | 
			
		||||
            Write_byte(GIF_file,0);
 | 
			
		||||
          }
 | 
			
		||||
          
 | 
			
		||||
          // Loop on all layers
 | 
			
		||||
          for (current_layer=0; 
 | 
			
		||||
@ -2282,7 +2435,7 @@ void Save_GIF(T_IO_Context * context)
 | 
			
		||||
            current_layer++)
 | 
			
		||||
          {
 | 
			
		||||
            // Write a Graphic Control Extension
 | 
			
		||||
            char GCE_block[] = "\x21\xF9\x04\x04\x05\x00\x00\x00";
 | 
			
		||||
            byte GCE_block[] = "\x21\xF9\x04\x04\x05\x00\x00\x00";
 | 
			
		||||
            // 'Default' values:
 | 
			
		||||
            //    Disposal method "Do not dispose"
 | 
			
		||||
            //    Duration 5/100s (minimum viable value for current web browsers)
 | 
			
		||||
@ -2542,7 +2695,6 @@ void Save_GIF(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// PCX ////////////////////////////////////
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
  {
 | 
			
		||||
    byte Manufacturer;       // |_ Il font chier ces cons! Ils auraient pu
 | 
			
		||||
@ -2564,7 +2716,6 @@ typedef struct
 | 
			
		||||
    word Screen_Y;           // |  l'écran d'origine
 | 
			
		||||
    byte Filler[54];         // Ca... J'adore!
 | 
			
		||||
  } T_PCX_Header;
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
T_PCX_Header PCX_header;
 | 
			
		||||
 | 
			
		||||
@ -3010,14 +3161,14 @@ void Save_PCX(T_IO_Context * context)
 | 
			
		||||
        Write_word_le(file,PCX_header.Y_max) &&
 | 
			
		||||
        Write_word_le(file,PCX_header.X_dpi) &&
 | 
			
		||||
        Write_word_le(file,PCX_header.Y_dpi) &&
 | 
			
		||||
        Write_bytes(file,&(PCX_header.Palette_16c),sizeof(PCX_header.Palette_16c)) &&        
 | 
			
		||||
        Write_bytes(file,&(PCX_header.Palette_16c),48) &&
 | 
			
		||||
        Write_bytes(file,&(PCX_header.Reserved),1) &&
 | 
			
		||||
        Write_bytes(file,&(PCX_header.Plane),1) &&
 | 
			
		||||
        Write_word_le(file,PCX_header.Bytes_per_plane_line) &&
 | 
			
		||||
        Write_word_le(file,PCX_header.Palette_info) &&
 | 
			
		||||
        Write_word_le(file,PCX_header.Screen_X) &&
 | 
			
		||||
        Write_word_le(file,PCX_header.Screen_Y) &&
 | 
			
		||||
        Write_bytes(file,&(PCX_header.Filler),sizeof(PCX_header.Filler)) )
 | 
			
		||||
        Write_bytes(file,&(PCX_header.Filler),54) )
 | 
			
		||||
    {
 | 
			
		||||
      line_size=PCX_header.Bytes_per_plane_line*PCX_header.Plane;
 | 
			
		||||
     
 | 
			
		||||
@ -3102,7 +3253,7 @@ void Test_SCx(T_IO_Context * context)
 | 
			
		||||
  if ((file=fopen(filename, "rb")))
 | 
			
		||||
  {
 | 
			
		||||
    // Lecture et vérification de la signature
 | 
			
		||||
    if (Read_bytes(file,SCx_header.Filler1,sizeof(SCx_header.Filler1))
 | 
			
		||||
    if (Read_bytes(file,SCx_header.Filler1,4)
 | 
			
		||||
    && Read_word_le(file, &(SCx_header.Width))
 | 
			
		||||
    && Read_word_le(file, &(SCx_header.Height))
 | 
			
		||||
    && Read_byte(file, &(SCx_header.Filler2))
 | 
			
		||||
@ -3138,7 +3289,7 @@ void Load_SCx(T_IO_Context * context)
 | 
			
		||||
  {
 | 
			
		||||
    file_size=File_length_file(file);
 | 
			
		||||
 | 
			
		||||
    if (Read_bytes(file,SCx_header.Filler1,sizeof(SCx_header.Filler1))
 | 
			
		||||
    if (Read_bytes(file,SCx_header.Filler1,4)
 | 
			
		||||
    && Read_word_le(file, &(SCx_header.Width))
 | 
			
		||||
    && Read_word_le(file, &(SCx_header.Height))
 | 
			
		||||
    && Read_byte(file, &(SCx_header.Filler2))
 | 
			
		||||
@ -3259,7 +3410,7 @@ void Save_SCx(T_IO_Context * context)
 | 
			
		||||
    SCx_header.Filler2=0xAF;
 | 
			
		||||
    SCx_header.Planes=0x00;
 | 
			
		||||
 | 
			
		||||
    if (Write_bytes(file,SCx_header.Filler1,sizeof(SCx_header.Filler1))
 | 
			
		||||
    if (Write_bytes(file,SCx_header.Filler1,4)
 | 
			
		||||
    && Write_word_le(file, SCx_header.Width)
 | 
			
		||||
    && Write_word_le(file, SCx_header.Height)
 | 
			
		||||
    && Write_byte(file, SCx_header.Filler2)
 | 
			
		||||
@ -3294,6 +3445,44 @@ void Save_SCx(T_IO_Context * context)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// XPM ////////////////////////////////////
 | 
			
		||||
void Save_XPM(T_IO_Context* context)
 | 
			
		||||
{
 | 
			
		||||
  FILE* file;
 | 
			
		||||
  char filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
  int i,j;
 | 
			
		||||
 | 
			
		||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
			
		||||
  File_error = 0;
 | 
			
		||||
 | 
			
		||||
  file = fopen(filename, "w");
 | 
			
		||||
  if (file == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    File_error = 1;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fprintf(file, "/* XPM */\nstatic char* pixmap[] = {\n");
 | 
			
		||||
  fprintf(file, "\"%d %d 256 2\",\n", context->Width, context->Height);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    fprintf(file,"\"%2.2X c #%2.2x%2.2x%2.2x\",\n", i, context->Palette[i].R, context->Palette[i].G,
 | 
			
		||||
      context->Palette[i].B);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (j = 0; j < context->Height; j++)
 | 
			
		||||
  {
 | 
			
		||||
    fprintf(file, "\"");
 | 
			
		||||
    for (i = 0; i < context->Width; i++)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf(file, "%2.2X", Get_pixel(context, i, j));
 | 
			
		||||
    }
 | 
			
		||||
    fprintf(file,"\"\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fclose(file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// PNG ////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
@ -3322,7 +3511,71 @@ void Test_PNG(T_IO_Context * context)
 | 
			
		||||
    fclose(file);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Used by a callback in Load_PNG
 | 
			
		||||
T_IO_Context * PNG_current_context;
 | 
			
		||||
 | 
			
		||||
int PNG_read_unknown_chunk(__attribute__((unused)) png_structp ptr, png_unknown_chunkp chunk)
 | 
			
		||||
{
 | 
			
		||||
  // png_unknown_chunkp members:
 | 
			
		||||
  //    png_byte name[5];
 | 
			
		||||
  //    png_byte *data;
 | 
			
		||||
  //    png_size_t size;
 | 
			
		||||
  
 | 
			
		||||
  if (!strcmp((const char *)chunk->name, "crNg"))
 | 
			
		||||
  {
 | 
			
		||||
    // Color animation. Similar to a LBM CRNG chunk.
 | 
			
		||||
    unsigned int i;
 | 
			
		||||
    byte *chunk_ptr = chunk->data;
 | 
			
		||||
    
 | 
			
		||||
    // Should be a multiple of 6
 | 
			
		||||
    if (chunk->size % 6)
 | 
			
		||||
      return (-1);
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    for(i=0;i<chunk->size/6 && i<16; i++)
 | 
			
		||||
    {
 | 
			
		||||
      word rate;
 | 
			
		||||
      word flags;
 | 
			
		||||
      byte min_col;
 | 
			
		||||
      byte max_col;
 | 
			
		||||
      
 | 
			
		||||
      // Rate (big-endian word)
 | 
			
		||||
      rate = *(chunk_ptr++) << 8;
 | 
			
		||||
      rate |= *(chunk_ptr++);
 | 
			
		||||
      
 | 
			
		||||
      // Flags (big-endian)
 | 
			
		||||
      flags = *(chunk_ptr++) << 8;
 | 
			
		||||
      flags |= *(chunk_ptr++);
 | 
			
		||||
 | 
			
		||||
      // Min color
 | 
			
		||||
      min_col = *(chunk_ptr++);
 | 
			
		||||
      // Max color
 | 
			
		||||
      max_col = *(chunk_ptr++);
 | 
			
		||||
 | 
			
		||||
      // Check validity
 | 
			
		||||
      if (min_col != max_col)
 | 
			
		||||
      {
 | 
			
		||||
        // Valid cycling range
 | 
			
		||||
        if (max_col<min_col)
 | 
			
		||||
          SWAP_BYTES(min_col,max_col)
 | 
			
		||||
        
 | 
			
		||||
          PNG_current_context->Cycle_range[i].Start=min_col;
 | 
			
		||||
          PNG_current_context->Cycle_range[i].End=max_col;
 | 
			
		||||
          PNG_current_context->Cycle_range[i].Inverse=(flags&2)?1:0;
 | 
			
		||||
          PNG_current_context->Cycle_range[i].Speed=(flags&1) ? rate/78 : 0;
 | 
			
		||||
                              
 | 
			
		||||
          PNG_current_context->Color_cycles=i+1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    return (1); // >0 = success
 | 
			
		||||
  }
 | 
			
		||||
  return (0); /* did not recognize */
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
png_bytep * Row_pointers;
 | 
			
		||||
// -- Lire un fichier au format PNG -----------------------------------------
 | 
			
		||||
void Load_PNG(T_IO_Context * context)
 | 
			
		||||
@ -3360,6 +3613,7 @@ void Load_PNG(T_IO_Context * context)
 | 
			
		||||
          {
 | 
			
		||||
            png_byte color_type;
 | 
			
		||||
            png_byte bit_depth;
 | 
			
		||||
            png_voidp user_chunk_ptr;
 | 
			
		||||
            
 | 
			
		||||
            // Setup a return point. If a pnglib loading error occurs
 | 
			
		||||
            // in this if(), the else will be executed.
 | 
			
		||||
@ -3368,11 +3622,18 @@ void Load_PNG(T_IO_Context * context)
 | 
			
		||||
              png_init_io(png_ptr, file);
 | 
			
		||||
              // Inform pnglib we already loaded the header.
 | 
			
		||||
              png_set_sig_bytes(png_ptr, 8);
 | 
			
		||||
            
 | 
			
		||||
              
 | 
			
		||||
              // Hook the handler for unknown chunks
 | 
			
		||||
              user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
 | 
			
		||||
              png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, &PNG_read_unknown_chunk);
 | 
			
		||||
              // This is a horrid way to pass parameters, but we don't get 
 | 
			
		||||
              // much choice. PNG loader can't be reintrant.
 | 
			
		||||
              PNG_current_context=context;
 | 
			
		||||
 | 
			
		||||
              // Load file information
 | 
			
		||||
              png_read_info(png_ptr, info_ptr);
 | 
			
		||||
              color_type = info_ptr->color_type;
 | 
			
		||||
              bit_depth = info_ptr->bit_depth;
 | 
			
		||||
              color_type = png_get_color_type(png_ptr,info_ptr);
 | 
			
		||||
              bit_depth = png_get_bit_depth(png_ptr,info_ptr);
 | 
			
		||||
              
 | 
			
		||||
              // If it's any supported file
 | 
			
		||||
              // (Note: As of writing this, this test covers every possible 
 | 
			
		||||
@ -3425,9 +3686,9 @@ void Load_PNG(T_IO_Context * context)
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
                if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 | 
			
		||||
                  Pre_load(context,info_ptr->width,info_ptr->height,File_length_file(file),FORMAT_PNG,PIXEL_SIMPLE,1);
 | 
			
		||||
                  Pre_load(context,png_get_image_width(png_ptr,info_ptr),png_get_image_height(png_ptr,info_ptr),File_length_file(file),FORMAT_PNG,PIXEL_SIMPLE,1);
 | 
			
		||||
                else
 | 
			
		||||
                  Pre_load(context, info_ptr->width,info_ptr->height,File_length_file(file),FORMAT_PNG,context->Ratio,0);
 | 
			
		||||
                  Pre_load(context,png_get_image_width(png_ptr,info_ptr),png_get_image_height(png_ptr,info_ptr),File_length_file(file),FORMAT_PNG,context->Ratio,0);
 | 
			
		||||
 | 
			
		||||
                if (File_error==0)
 | 
			
		||||
                {
 | 
			
		||||
@ -3535,8 +3796,8 @@ void Load_PNG(T_IO_Context * context)
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  
 | 
			
		||||
                  context->Width=info_ptr->width;
 | 
			
		||||
                  context->Height=info_ptr->height;
 | 
			
		||||
                  context->Width=png_get_image_width(png_ptr,info_ptr);
 | 
			
		||||
                  context->Height=png_get_image_height(png_ptr,info_ptr);
 | 
			
		||||
                  
 | 
			
		||||
                  png_set_interlace_handling(png_ptr);
 | 
			
		||||
                  png_read_update_info(png_ptr, info_ptr);
 | 
			
		||||
@ -3556,7 +3817,7 @@ void Load_PNG(T_IO_Context * context)
 | 
			
		||||
                      // 8bpp
 | 
			
		||||
                      
 | 
			
		||||
                      for (y=0; y<context->Height; y++)
 | 
			
		||||
                        Row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes);
 | 
			
		||||
                        Row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
 | 
			
		||||
                      row_pointers_allocated = 1;
 | 
			
		||||
                      
 | 
			
		||||
                      png_read_image(png_ptr, Row_pointers);
 | 
			
		||||
@ -3575,7 +3836,7 @@ void Load_PNG(T_IO_Context * context)
 | 
			
		||||
                          // It's a preview
 | 
			
		||||
                          // Unfortunately we need to allocate loads of memory
 | 
			
		||||
                          for (y=0; y<context->Height; y++)
 | 
			
		||||
                            Row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes);
 | 
			
		||||
                            Row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
 | 
			
		||||
                          row_pointers_allocated = 1;
 | 
			
		||||
                          
 | 
			
		||||
                          png_read_image(png_ptr, Row_pointers);
 | 
			
		||||
@ -3646,6 +3907,8 @@ void Save_PNG(T_IO_Context * context)
 | 
			
		||||
  byte * pixel_ptr;
 | 
			
		||||
  png_structp png_ptr;
 | 
			
		||||
  png_infop info_ptr;
 | 
			
		||||
  png_unknown_chunk crng_chunk;
 | 
			
		||||
  byte cycle_data[16*6]; // Storage for color-cycling data, referenced by crng_chunk
 | 
			
		||||
  
 | 
			
		||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
			
		||||
  File_error=0;
 | 
			
		||||
@ -3674,9 +3937,15 @@ void Save_PNG(T_IO_Context * context)
 | 
			
		||||
          {
 | 
			
		||||
            // Commentaires texte PNG
 | 
			
		||||
            // Cette partie est optionnelle
 | 
			
		||||
            #ifdef PNG_iTXt_SUPPORTED
 | 
			
		||||
              png_text text_ptr[2] = {
 | 
			
		||||
                {-1, "Software", "Grafx2", 6, 0, NULL, NULL},
 | 
			
		||||
                {-1, "Title", NULL, 0, 0, NULL, NULL}
 | 
			
		||||
            #else
 | 
			
		||||
            png_text text_ptr[2] = {
 | 
			
		||||
              {-1, "Software", "Grafx2", 6},
 | 
			
		||||
              {-1, "Title", NULL, 0}
 | 
			
		||||
            #endif
 | 
			
		||||
            };
 | 
			
		||||
            int nb_text_chunks=1;
 | 
			
		||||
            if (context->Comment[0])
 | 
			
		||||
@ -3710,7 +3979,58 @@ void Save_PNG(T_IO_Context * context)
 | 
			
		||||
              break;
 | 
			
		||||
            default:
 | 
			
		||||
              break;
 | 
			
		||||
          }          
 | 
			
		||||
          }
 | 
			
		||||
          // Write cycling colors
 | 
			
		||||
          if (context->Color_cycles)
 | 
			
		||||
          {
 | 
			
		||||
            // Save a chunk called 'crNg'
 | 
			
		||||
            // The case is selected by the following rules from PNG standard:
 | 
			
		||||
            // char 1: non-mandatory = lowercase
 | 
			
		||||
            // char 2: private (not standard) = lowercase
 | 
			
		||||
            // char 3: reserved = always uppercase
 | 
			
		||||
            // char 4: can be copied by editors = lowercase
 | 
			
		||||
 | 
			
		||||
            // First, turn our nice structure into byte array
 | 
			
		||||
            // (just to avoid padding in structures)
 | 
			
		||||
            
 | 
			
		||||
            byte *chunk_ptr = cycle_data;
 | 
			
		||||
            int i;
 | 
			
		||||
            
 | 
			
		||||
            for (i=0; i<context->Color_cycles; i++)
 | 
			
		||||
            {
 | 
			
		||||
              word flags=0;
 | 
			
		||||
              flags|= context->Cycle_range[i].Speed?1:0; // Cycling or not
 | 
			
		||||
              flags|= context->Cycle_range[i].Inverse?2:0; // Inverted
 | 
			
		||||
              
 | 
			
		||||
              // Big end of Rate
 | 
			
		||||
              *(chunk_ptr++) = (context->Cycle_range[i].Speed*78) >> 8;
 | 
			
		||||
              // Low end of Rate
 | 
			
		||||
              *(chunk_ptr++) = (context->Cycle_range[i].Speed*78) & 0xFF;
 | 
			
		||||
              
 | 
			
		||||
              // Big end of Flags
 | 
			
		||||
              *(chunk_ptr++) = (flags) >> 8;
 | 
			
		||||
              // Low end of Flags
 | 
			
		||||
              *(chunk_ptr++) = (flags) & 0xFF;
 | 
			
		||||
              
 | 
			
		||||
              // Min color
 | 
			
		||||
              *(chunk_ptr++) = context->Cycle_range[i].Start;
 | 
			
		||||
              // Max color
 | 
			
		||||
              *(chunk_ptr++) = context->Cycle_range[i].End;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Build one unknown_chuck structure        
 | 
			
		||||
            memcpy(crng_chunk.name, "crNg",5);
 | 
			
		||||
            crng_chunk.data=cycle_data;
 | 
			
		||||
            crng_chunk.size=context->Color_cycles*6;
 | 
			
		||||
            crng_chunk.location=PNG_HAVE_PLTE;
 | 
			
		||||
            
 | 
			
		||||
            // Give it to libpng
 | 
			
		||||
            png_set_unknown_chunks(png_ptr, info_ptr, &crng_chunk, 1);
 | 
			
		||||
            // libpng seems to ignore the location I provided earlier.
 | 
			
		||||
	          png_set_unknown_chunk_location(png_ptr, info_ptr, 0, PNG_HAVE_PLTE);
 | 
			
		||||
          }
 | 
			
		||||
          
 | 
			
		||||
          
 | 
			
		||||
          png_write_info(png_ptr, info_ptr);
 | 
			
		||||
 | 
			
		||||
          /* ecriture des pixels de l'image */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										502
									
								
								src/filesel.c
									
									
									
									
									
								
							
							
						
						
									
										502
									
								
								src/filesel.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2009 Franck Charlet
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
@ -22,14 +23,22 @@
 | 
			
		||||
    along with Grafx2; if not, see <http://www.gnu.org/licenses/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <SDL_syswm.h>
 | 
			
		||||
 | 
			
		||||
#if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__)
 | 
			
		||||
    #include <proto/dos.h>
 | 
			
		||||
    #include <sys/types.h>
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #define isHidden(x) (0)
 | 
			
		||||
 | 
			
		||||
#elif defined (__MINT__)
 | 
			
		||||
    #include <mint/sysbind.h>
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #define isHidden(x) (0)
 | 
			
		||||
#elif defined(__WIN32__)
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #include <windows.h>
 | 
			
		||||
    #include <commdlg.h>
 | 
			
		||||
    #define isHidden(x) (GetFileAttributesA((x)->d_name)&FILE_ATTRIBUTE_HIDDEN)
 | 
			
		||||
#else
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
@ -62,12 +71,66 @@
 | 
			
		||||
#include "help.h"
 | 
			
		||||
#include "filesel.h"
 | 
			
		||||
 | 
			
		||||
#define NORMAL_FILE_COLOR    MC_Light // color du texte pour une ligne de fichier non sélectionné
 | 
			
		||||
#define NORMAL_DIRECTORY_COLOR MC_Dark // color du texte pour une ligne de répertoire non sélectionné
 | 
			
		||||
#define NORMAL_BACKGROUND_COLOR       MC_Black  // color du fond  pour une ligne non sélectionnée
 | 
			
		||||
#define SELECTED_FILE_COLOR    MC_White // color du texte pour une ligne de fichier    sélectionnée
 | 
			
		||||
#define SELECTED_DIRECTORY_COLOR MC_Light // color du texte pour une ligne de repértoire sélectionnée
 | 
			
		||||
#define SELECTED_BACKGROUND_COLOR       MC_Dark // color du fond  pour une ligne sélectionnée
 | 
			
		||||
#define NORMAL_FILE_COLOR    MC_Light // color du texte pour une ligne de
 | 
			
		||||
	// fichier non sélectionné
 | 
			
		||||
#define NORMAL_DIRECTORY_COLOR MC_Dark // color du texte pour une ligne de
 | 
			
		||||
	// répertoire non sélectionné
 | 
			
		||||
#define NORMAL_BACKGROUND_COLOR       MC_Black  // color du fond  pour une ligne
 | 
			
		||||
	// non sélectionnée
 | 
			
		||||
#define SELECTED_FILE_COLOR    MC_White // color du texte pour une ligne de
 | 
			
		||||
	// fichier sélectionnée
 | 
			
		||||
#define SELECTED_DIRECTORY_COLOR MC_Light // color du texte pour une ligne de
 | 
			
		||||
	// repértoire sélectionnée
 | 
			
		||||
#define SELECTED_BACKGROUND_COLOR       MC_Dark // color du fond  pour une ligne
 | 
			
		||||
	// sélectionnée
 | 
			
		||||
 | 
			
		||||
// -- Native fileselector for WIN32
 | 
			
		||||
 | 
			
		||||
// Returns 0 if all ok, something else if failed
 | 
			
		||||
byte Native_filesel(byte load)
 | 
			
		||||
{
 | 
			
		||||
	//load = load;
 | 
			
		||||
#ifdef __WIN32__
 | 
			
		||||
  OPENFILENAME ofn;
 | 
			
		||||
  char szFileName[MAX_PATH] = "";
 | 
			
		||||
	SDL_SysWMinfo wminfo;
 | 
			
		||||
	HWND hwnd;
 | 
			
		||||
	
 | 
			
		||||
	SDL_VERSION(&wminfo.version);
 | 
			
		||||
	SDL_GetWMInfo(&wminfo);
 | 
			
		||||
	hwnd = wminfo.window;
 | 
			
		||||
 | 
			
		||||
  ZeroMemory(&ofn, sizeof(ofn));
 | 
			
		||||
 | 
			
		||||
  ofn.lStructSize = sizeof(ofn);
 | 
			
		||||
  ofn.hwndOwner = hwnd;
 | 
			
		||||
  ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
 | 
			
		||||
  ofn.lpstrFile = szFileName;
 | 
			
		||||
  ofn.nMaxFile = MAX_PATH;
 | 
			
		||||
  ofn.Flags = OFN_EXPLORER;
 | 
			
		||||
  if(load) ofn.Flags |= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
 | 
			
		||||
  ofn.lpstrDefExt = "txt";
 | 
			
		||||
 | 
			
		||||
  if(load)
 | 
			
		||||
  {
 | 
			
		||||
    if (GetOpenFileName(&ofn))
 | 
			
		||||
      // Do something usefull with the filename stored in szFileName 
 | 
			
		||||
      return 0;
 | 
			
		||||
    else
 | 
			
		||||
      // error - check if its just user pressing cancel or something else
 | 
			
		||||
      return CommDlgExtendedError();
 | 
			
		||||
  } else if(GetSaveFileName(&ofn)) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Check if cancel
 | 
			
		||||
    return CommDlgExtendedError();
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  return 255; // fail !
 | 
			
		||||
#endif
 | 
			
		||||
}  
 | 
			
		||||
 | 
			
		||||
// -- "Standard" fileselector for other platforms
 | 
			
		||||
 | 
			
		||||
// -- Fileselector data
 | 
			
		||||
 | 
			
		||||
@ -86,7 +149,7 @@ static char Selector_filename[256];
 | 
			
		||||
void Recount_files(T_Fileselector *list)
 | 
			
		||||
{
 | 
			
		||||
  T_Fileselector_item *item;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  list->Nb_files=0;
 | 
			
		||||
  list->Nb_directories=0;
 | 
			
		||||
  list->Nb_elements=0;
 | 
			
		||||
@ -146,30 +209,48 @@ void Free_fileselector_list(T_Fileselector *list)
 | 
			
		||||
  Recount_files(list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char * Format_filename(const char * fname, int type)
 | 
			
		||||
char * Format_filename(const char * fname, word max_length, int type)
 | 
			
		||||
{
 | 
			
		||||
  static char result[19];
 | 
			
		||||
  static char result[40];
 | 
			
		||||
  int         c;
 | 
			
		||||
  int         other_cursor;
 | 
			
		||||
  int         pos_last_dot;
 | 
			
		||||
 | 
			
		||||
  // safety
 | 
			
		||||
  if (max_length>40)
 | 
			
		||||
    max_length=40;
 | 
			
		||||
  
 | 
			
		||||
  if (strcmp(fname,PARENT_DIR)==0)
 | 
			
		||||
  {
 | 
			
		||||
    strcpy(result,"<-PARENT DIRECTORY");
 | 
			
		||||
    // Append spaces
 | 
			
		||||
    for (c=18; c<max_length-1; c++)
 | 
			
		||||
      result[c]=' ';
 | 
			
		||||
    result[c]='\0';
 | 
			
		||||
  }
 | 
			
		||||
  else if (fname[0]=='.' || type==1 || type==2)
 | 
			
		||||
  {
 | 
			
		||||
    // Files ".something" or drives or directories: Aligned left on 18 chars max
 | 
			
		||||
    strcpy(result,"                  ");
 | 
			
		||||
    for (c=0;fname[c]!='\0' && c < 18;c++)
 | 
			
		||||
    // Files ".something" or drives or directories: Aligned left on (max_length-1) chars max
 | 
			
		||||
    // Initialize as all spaces
 | 
			
		||||
    for (c=0; c<max_length-1; c++)
 | 
			
		||||
      result[c]=' ';
 | 
			
		||||
    result[c]='\0';
 | 
			
		||||
    
 | 
			
		||||
    for (c=0;fname[c]!='\0' && c < max_length-1;c++)
 | 
			
		||||
      result[c]=fname[c];
 | 
			
		||||
    // A special character indicates the filename is truncated
 | 
			
		||||
    if (c >= 18)
 | 
			
		||||
      result[17]=ELLIPSIS_CHARACTER;
 | 
			
		||||
    if (c >= max_length-1)
 | 
			
		||||
      result[max_length-2]=ELLIPSIS_CHARACTER;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    strcpy(result,"              .   ");
 | 
			
		||||
    // Initialize as all spaces
 | 
			
		||||
    for (c = 0; c<max_length-1; c++)
 | 
			
		||||
      result[c]=' ';
 | 
			
		||||
    result[c]='\0';
 | 
			
		||||
       
 | 
			
		||||
    result[max_length-5]='.';
 | 
			
		||||
    
 | 
			
		||||
    // Look for the last dot in filename
 | 
			
		||||
    pos_last_dot = -1;
 | 
			
		||||
    for (c = 0; fname[c]!='\0'; c++)
 | 
			
		||||
@ -179,9 +260,9 @@ char * Format_filename(const char * fname, int type)
 | 
			
		||||
    // Copy the part before the dot
 | 
			
		||||
    for (c=0; c!=pos_last_dot && fname[c]!='\0'; c++)
 | 
			
		||||
    {
 | 
			
		||||
      if (c > 13)
 | 
			
		||||
      if (c > max_length-6)
 | 
			
		||||
      {
 | 
			
		||||
        result[13]=ELLIPSIS_CHARACTER;
 | 
			
		||||
        result[max_length-6]=ELLIPSIS_CHARACTER;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      result[c]=fname[c];
 | 
			
		||||
@ -190,7 +271,7 @@ char * Format_filename(const char * fname, int type)
 | 
			
		||||
    // Ensuite on recopie la partie qui suit le point (si nécessaire):
 | 
			
		||||
    if (pos_last_dot != -1)
 | 
			
		||||
    {
 | 
			
		||||
      for (c = pos_last_dot+1,other_cursor=15;fname[c]!='\0' && other_cursor < 18;c++,other_cursor++)
 | 
			
		||||
      for (c = pos_last_dot+1,other_cursor=max_length-4;fname[c]!='\0' && other_cursor < max_length-1;c++,other_cursor++)
 | 
			
		||||
        result[other_cursor]=fname[c];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -199,25 +280,29 @@ char * Format_filename(const char * fname, int type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -- Rajouter a la liste des elements de la liste un element ---------------
 | 
			
		||||
void Add_element_to_list(T_Fileselector *list, const char * fname, int type)
 | 
			
		||||
void Add_element_to_list(T_Fileselector *list, const char * full_name, const char *short_name, int type, byte icon)
 | 
			
		||||
//  Cette procedure ajoute a la liste chainee un fichier passé en argument.
 | 
			
		||||
{
 | 
			
		||||
  // Pointeur temporaire d'insertion
 | 
			
		||||
  // Working element
 | 
			
		||||
  T_Fileselector_item * temp_item;
 | 
			
		||||
 | 
			
		||||
  // On alloue de la place pour un nouvel element
 | 
			
		||||
  temp_item=(T_Fileselector_item *)malloc(sizeof(T_Fileselector_item));
 | 
			
		||||
  // Allocate enough room for one struct + the visible label
 | 
			
		||||
  temp_item=(T_Fileselector_item *)malloc(sizeof(T_Fileselector_item)+strlen(short_name));
 | 
			
		||||
 | 
			
		||||
  // On met a jour le nouvel emplacement:
 | 
			
		||||
  strcpy(temp_item->Short_name,Format_filename(fname, type));
 | 
			
		||||
  strcpy(temp_item->Full_name,fname);
 | 
			
		||||
  // Initialize element
 | 
			
		||||
  strcpy(temp_item->Short_name,short_name);
 | 
			
		||||
  strcpy(temp_item->Full_name,full_name);
 | 
			
		||||
  temp_item->Type = type;
 | 
			
		||||
  temp_item->Icon = icon;
 | 
			
		||||
 | 
			
		||||
  // Doubly-linked
 | 
			
		||||
  temp_item->Next    =list->First;
 | 
			
		||||
  temp_item->Previous=NULL;
 | 
			
		||||
 | 
			
		||||
  if (list->First!=NULL)
 | 
			
		||||
    list->First->Previous=temp_item;
 | 
			
		||||
    
 | 
			
		||||
  // Put new element at the beginning
 | 
			
		||||
  list->First=temp_item;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -275,8 +360,25 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format)
 | 
			
		||||
  // Après effacement, il ne reste ni fichier ni répertoire dans la liste
 | 
			
		||||
 | 
			
		||||
  // On lit tous les répertoires:
 | 
			
		||||
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  static char path[1024];
 | 
			
		||||
  static char path2[1024];
 | 
			
		||||
  path[0]='\0';
 | 
			
		||||
  path2[0]='\0';
 | 
			
		||||
  
 | 
			
		||||
  char currentDrive='A';
 | 
			
		||||
  currentDrive=currentDrive+Dgetdrv(); 
 | 
			
		||||
  
 | 
			
		||||
  Dgetpath(path,0);
 | 
			
		||||
  sprintf(path2,"%c:\%s",currentDrive,path);
 | 
			
		||||
 
 | 
			
		||||
  strcat(path2,PATH_SEPARATOR);
 | 
			
		||||
  current_directory=opendir(path2);
 | 
			
		||||
#else  
 | 
			
		||||
  current_path=getcwd(NULL,0);
 | 
			
		||||
  current_directory=opendir(current_path);
 | 
			
		||||
#endif
 | 
			
		||||
  while ((entry=readdir(current_directory)))
 | 
			
		||||
  {
 | 
			
		||||
    // On ignore le répertoire courant
 | 
			
		||||
@ -294,7 +396,7 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format)
 | 
			
		||||
     !isHidden(entry)))
 | 
			
		||||
    {
 | 
			
		||||
      // On rajoute le répertoire à la liste
 | 
			
		||||
      Add_element_to_list(list, entry->d_name, 1);
 | 
			
		||||
      Add_element_to_list(list, entry->d_name, Format_filename(entry->d_name, 19, 1), 1, ICON_NONE);
 | 
			
		||||
      list->Nb_directories++;
 | 
			
		||||
    }
 | 
			
		||||
    else if (S_ISREG(Infos_enreg.st_mode) && //Il s'agit d'un fichier
 | 
			
		||||
@ -307,7 +409,7 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format)
 | 
			
		||||
        if (Check_extension(entry->d_name, ext))
 | 
			
		||||
        {
 | 
			
		||||
          // On rajoute le fichier à la liste
 | 
			
		||||
          Add_element_to_list(list, entry->d_name, 0);
 | 
			
		||||
          Add_element_to_list(list, entry->d_name, Format_filename(entry->d_name, 19, 0), 0, ICON_NONE);
 | 
			
		||||
          list->Nb_files++;
 | 
			
		||||
          // Stop searching
 | 
			
		||||
          ext=NULL;
 | 
			
		||||
@ -323,12 +425,35 @@ void Read_list_of_files(T_Fileselector *list, byte selected_format)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if defined(__MORPHOS__) || defined(__AROS__) || defined (__amigaos4__) || defined(__amigaos__)
 | 
			
		||||
  Add_element_to_list(list, "/",1); // on amiga systems, / means parent. And there is no ..
 | 
			
		||||
  Add_element_to_list(list, "/", Format_filename("/",19,1), 1, ICON_NONE); // on amiga systems, / means parent. And there is no ..
 | 
			
		||||
  list->Nb_directories ++;
 | 
			
		||||
#elif defined (__MINT__)
 | 
			
		||||
  T_Fileselector_item *item=NULL;
 | 
			
		||||
  // check if ".." exists if not add it
 | 
			
		||||
  // FreeMinT lists ".." already, but this is not so for TOS 
 | 
			
		||||
  // simply adding it will cause double PARENT_DIR under FreeMiNT
 | 
			
		||||
  
 | 
			
		||||
  bool bFound= false;
 | 
			
		||||
  
 | 
			
		||||
  for (item = list->First; (((item != NULL) && (bFound==false))); item = item->Next){
 | 
			
		||||
    if (item->Type == 1){
 | 
			
		||||
	if(strncmp(item->Full_name,"..",(sizeof(char)*2))==0) bFound=true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if(!bFound){
 | 
			
		||||
    Add_element_to_list(list, "..",1,Format_filename("/",19,1),ICON_NONE); // add if not present
 | 
			
		||||
    list->Nb_directories ++;  
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  closedir(current_directory);
 | 
			
		||||
#if defined (__MINT__)  
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  free(current_path);
 | 
			
		||||
#endif
 | 
			
		||||
  current_path = NULL;
 | 
			
		||||
 | 
			
		||||
  Recount_files(list);
 | 
			
		||||
@ -375,7 +500,7 @@ void Read_list_of_drives(T_Fileselector *list)
 | 
			
		||||
      {
 | 
			
		||||
        bstrtostr( dl->dol_Name, tmp, 254 );
 | 
			
		||||
        strcat( tmp, ":" );
 | 
			
		||||
        Add_element_to_list(list, tmp, 2 );
 | 
			
		||||
        Add_element_to_list(list, tmp, Format_filename(tmp, 19, 2), 2, ICON_NONE );
 | 
			
		||||
        list->Nb_directories++;
 | 
			
		||||
      }
 | 
			
		||||
      UnLockDosList( LDF_VOLUMES | LDF_READ );
 | 
			
		||||
@ -387,6 +512,8 @@ void Read_list_of_drives(T_Fileselector *list)
 | 
			
		||||
    int drive_bits = GetLogicalDrives();
 | 
			
		||||
    int drive_index;
 | 
			
		||||
    int bit_index;
 | 
			
		||||
    byte icon;
 | 
			
		||||
    
 | 
			
		||||
    // Sous Windows, on a la totale, presque aussi bien que sous DOS:
 | 
			
		||||
    drive_index = 0;
 | 
			
		||||
    for (bit_index=0; bit_index<26 && drive_index<23; bit_index++)
 | 
			
		||||
@ -395,35 +522,51 @@ void Read_list_of_drives(T_Fileselector *list)
 | 
			
		||||
      {
 | 
			
		||||
        // On a ce lecteur, il faut maintenant déterminer son type "physique".
 | 
			
		||||
        // pour profiter des jolies icones de X-man.
 | 
			
		||||
        int drive_type;
 | 
			
		||||
        char drive_path[]="A:\\";
 | 
			
		||||
        // Cette API Windows est étrange, je dois m'y faire...
 | 
			
		||||
        drive_path[0]='A'+bit_index;
 | 
			
		||||
        switch (GetDriveType(drive_path))
 | 
			
		||||
        {
 | 
			
		||||
          case DRIVE_CDROM:
 | 
			
		||||
            drive_type=ICON_CDROM;
 | 
			
		||||
            icon=ICON_CDROM;
 | 
			
		||||
            break;
 | 
			
		||||
          case DRIVE_REMOTE:
 | 
			
		||||
            drive_type=ICON_NETWORK;
 | 
			
		||||
            icon=ICON_NETWORK;
 | 
			
		||||
            break;
 | 
			
		||||
          case DRIVE_REMOVABLE:
 | 
			
		||||
            drive_type=ICON_FLOPPY_3_5;
 | 
			
		||||
            icon=ICON_FLOPPY_3_5;
 | 
			
		||||
            break;
 | 
			
		||||
          case DRIVE_FIXED:
 | 
			
		||||
            drive_type=ICON_HDD;
 | 
			
		||||
            icon=ICON_HDD;
 | 
			
		||||
            break;
 | 
			
		||||
          default:
 | 
			
		||||
            drive_type=ICON_NETWORK;
 | 
			
		||||
            icon=ICON_NETWORK;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        drive_name[0]='A'+bit_index;
 | 
			
		||||
        Add_element_to_list(list, drive_name,2);
 | 
			
		||||
        Add_element_to_list(list, drive_name, Format_filename(drive_name,18,2), 2, icon);
 | 
			
		||||
        list->Nb_directories++;
 | 
			
		||||
        drive_index++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  #elif defined(__MINT__)
 | 
			
		||||
    char drive_name[]="A:\\";
 | 
			
		||||
    unsigned long drive_bits = Drvmap(); //get drive map bitfield
 | 
			
		||||
    int drive_index;
 | 
			
		||||
    int bit_index;
 | 
			
		||||
    drive_index = 0;
 | 
			
		||||
    for (bit_index=0; bit_index<32; bit_index++)
 | 
			
		||||
    {
 | 
			
		||||
      if ( (1 << bit_index) & drive_bits )
 | 
			
		||||
      {
 | 
			
		||||
        drive_name[0]='A'+bit_index;
 | 
			
		||||
        Add_element_to_list(list, drive_name,Format_filename(drive_name,19,2),2,ICON_NONE);
 | 
			
		||||
        list->Nb_directories++;
 | 
			
		||||
        drive_index++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  #else
 | 
			
		||||
  {
 | 
			
		||||
    //Sous les différents unix, on va mettre
 | 
			
		||||
@ -440,11 +583,11 @@ void Read_list_of_drives(T_Fileselector *list)
 | 
			
		||||
    #else
 | 
			
		||||
        char * home_dir = getenv("HOME");
 | 
			
		||||
    #endif
 | 
			
		||||
    Add_element_to_list(list, "/", 2);
 | 
			
		||||
    Add_element_to_list(list, "/", Format_filename("/",19,2), 2, ICON_NONE);
 | 
			
		||||
    list->Nb_directories++;
 | 
			
		||||
    if(home_dir)
 | 
			
		||||
    {
 | 
			
		||||
        Add_element_to_list(list, home_dir, 2);
 | 
			
		||||
        Add_element_to_list(list, home_dir, Format_filename(home_dir, 19, 2), 2, ICON_NONE);
 | 
			
		||||
        list->Nb_directories++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -454,7 +597,7 @@ void Read_list_of_drives(T_Fileselector *list)
 | 
			
		||||
    {
 | 
			
		||||
        if(mount_points_list->me_dummy == 0 && strcmp(mount_points_list->me_mountdir,"/") && strcmp(mount_points_list->me_mountdir,"/home"))
 | 
			
		||||
        {
 | 
			
		||||
            Add_element_to_list(list, mount_points_list->me_mountdir,2);
 | 
			
		||||
            Add_element_to_list(list, mount_points_list->me_mountdir, Format_filename(mount_points_list->me_mountdir, 19, 2), 2, ICON_NONE);
 | 
			
		||||
            list->Nb_directories++;
 | 
			
		||||
        }
 | 
			
		||||
        next = mount_points_list -> me_next;
 | 
			
		||||
@ -473,6 +616,15 @@ void Read_list_of_drives(T_Fileselector *list)
 | 
			
		||||
  Recount_files(list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Comparison of file names:
 | 
			
		||||
#ifdef WIN32
 | 
			
		||||
// case-insensitive
 | 
			
		||||
  #define FILENAME_COMPARE strcasecmp
 | 
			
		||||
#else
 | 
			
		||||
// case-sensitive
 | 
			
		||||
  #define FILENAME_COMPARE strcmp
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -- Tri de la liste des fichiers et répertoires ---------------------------
 | 
			
		||||
void Sort_list_of_files(T_Fileselector *list)
 | 
			
		||||
@ -514,7 +666,7 @@ void Sort_list_of_files(T_Fileselector *list)
 | 
			
		||||
          // Si les deux éléments sont de même type et que le nom du suivant
 | 
			
		||||
          // est plus petit que celui du courant -> need_swap
 | 
			
		||||
        else if ( (current_item->Type==next_item->Type) &&
 | 
			
		||||
                  (strcmp(current_item->Full_name,next_item->Full_name)>0) )
 | 
			
		||||
                  (FILENAME_COMPARE(current_item->Full_name,next_item->Full_name)>0) )
 | 
			
		||||
          need_swap=1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -640,7 +792,14 @@ void Display_file_list(T_Fileselector *list, short offset_first,short selector_o
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // On affiche l'élément
 | 
			
		||||
      Print_in_window(8,95+index*8,current_item->Short_name,text_color,background_color);
 | 
			
		||||
      if (current_item->Icon != ICON_NONE)
 | 
			
		||||
      {
 | 
			
		||||
        // Name preceded by an icon
 | 
			
		||||
        Print_in_window(16,95+index*8,current_item->Short_name,text_color,background_color);
 | 
			
		||||
        Window_display_icon_sprite(8,95+index*8,current_item->Icon);
 | 
			
		||||
      } else
 | 
			
		||||
        // Name without icon
 | 
			
		||||
        Print_in_window(8,95+index*8,current_item->Short_name,text_color,background_color);
 | 
			
		||||
 | 
			
		||||
      // On passe à la ligne suivante
 | 
			
		||||
      selector_offset--;
 | 
			
		||||
@ -889,7 +1048,7 @@ void Prepare_and_display_filelist(short Position, short offset, T_Scroller_butto
 | 
			
		||||
{
 | 
			
		||||
  button->Nb_elements=Filelist.Nb_elements;
 | 
			
		||||
  button->Position=Position;
 | 
			
		||||
  Compute_slider_cursor_height(button);
 | 
			
		||||
  Compute_slider_cursor_length(button);
 | 
			
		||||
  Window_draw_slider(button);
 | 
			
		||||
  // On efface les anciens noms de fichier:
 | 
			
		||||
  Window_rectangle(8-1,95-1,144+2,80+2,MC_Black);
 | 
			
		||||
@ -984,12 +1143,8 @@ short Find_file_in_fileselector(T_Fileselector *list, const char * fname)
 | 
			
		||||
  return close_match;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Highlight_file(char * fname)
 | 
			
		||||
void Highlight_file(short index)
 | 
			
		||||
{
 | 
			
		||||
  short index;
 | 
			
		||||
 | 
			
		||||
  index=Find_file_in_fileselector(&Filelist, fname);
 | 
			
		||||
 | 
			
		||||
  if ((Filelist.Nb_elements<=10) || (index<5))
 | 
			
		||||
  {
 | 
			
		||||
@ -1012,15 +1167,17 @@ void Highlight_file(char * fname)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char * Find_filename_match(T_Fileselector *list, char * fname)
 | 
			
		||||
short Find_filename_match(T_Fileselector *list, char * fname)
 | 
			
		||||
{
 | 
			
		||||
  char * best_name_ptr;
 | 
			
		||||
  short best_match;
 | 
			
		||||
  T_Fileselector_item * current_item;
 | 
			
		||||
  byte   matching_letters=0;
 | 
			
		||||
  byte   counter;
 | 
			
		||||
 | 
			
		||||
  best_name_ptr=NULL;
 | 
			
		||||
  short item_number;
 | 
			
		||||
  byte matching_letters=0;
 | 
			
		||||
  byte counter;
 | 
			
		||||
 | 
			
		||||
  best_match=-1;
 | 
			
		||||
  item_number=0;
 | 
			
		||||
  
 | 
			
		||||
  for (current_item=list->First; current_item!=NULL; current_item=current_item->Next)
 | 
			
		||||
  {
 | 
			
		||||
    if ( (!Config.Find_file_fast)
 | 
			
		||||
@ -1031,12 +1188,96 @@ char * Find_filename_match(T_Fileselector *list, char * fname)
 | 
			
		||||
      if (counter>matching_letters)
 | 
			
		||||
      {
 | 
			
		||||
        matching_letters=counter;
 | 
			
		||||
        best_name_ptr=current_item->Full_name;
 | 
			
		||||
        best_match=item_number;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    item_number++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return best_name_ptr;
 | 
			
		||||
  return best_match;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Quicksearch system
 | 
			
		||||
char  quicksearch_filename[MAX_PATH_CHARACTERS]="";
 | 
			
		||||
 | 
			
		||||
void Reset_quicksearch(void)
 | 
			
		||||
{
 | 
			
		||||
  quicksearch_filename[0]='\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
short Quicksearch(T_Fileselector *selector)
 | 
			
		||||
{
 | 
			
		||||
  int len;
 | 
			
		||||
  short most_matching_item;
 | 
			
		||||
  
 | 
			
		||||
  // Autre => On se place sur le nom de fichier qui correspond
 | 
			
		||||
  len=strlen(quicksearch_filename);
 | 
			
		||||
  if (Key_ANSI>= ' ' && Key_ANSI < 255 && len<50)
 | 
			
		||||
  {
 | 
			
		||||
    quicksearch_filename[len]=Key_ANSI;
 | 
			
		||||
    quicksearch_filename[len+1]='\0';
 | 
			
		||||
    most_matching_item=Find_filename_match(selector, quicksearch_filename);
 | 
			
		||||
    if ( most_matching_item >= 0 )
 | 
			
		||||
    {
 | 
			
		||||
      return most_matching_item;
 | 
			
		||||
    }
 | 
			
		||||
    *quicksearch_filename=0;
 | 
			
		||||
  }
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Translated from Highlight_file
 | 
			
		||||
void Locate_list_item(T_List_button * list, T_Fileselector * selector, short selected_item)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  // Safety bounds
 | 
			
		||||
  if (selected_item<0)
 | 
			
		||||
    selected_item=0;
 | 
			
		||||
  else if (selected_item>=list->Scroller->Nb_elements)
 | 
			
		||||
    selected_item=list->Scroller->Nb_elements-1;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
  if ((list->Scroller->Nb_elements<=list->Scroller->Nb_visibles) || (selected_item<(list->Scroller->Nb_visibles/2)))
 | 
			
		||||
  {
 | 
			
		||||
    list->List_start=0;
 | 
			
		||||
    list->Cursor_position=selected_item;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if (selected_item>=list->Scroller->Nb_elements-(list->Scroller->Nb_visibles/2))
 | 
			
		||||
    {
 | 
			
		||||
      list->List_start=list->Scroller->Nb_elements-list->Scroller->Nb_visibles;
 | 
			
		||||
      list->Cursor_position=selected_item-list->List_start;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      list->List_start=selected_item-(list->Scroller->Nb_visibles/2-1);
 | 
			
		||||
      list->Cursor_position=(list->Scroller->Nb_visibles/2-1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Quicksearch_list(T_List_button * list, T_Fileselector * selector)
 | 
			
		||||
{
 | 
			
		||||
  // Try Quicksearch
 | 
			
		||||
  short selected_item=Quicksearch(selector);
 | 
			
		||||
  if (selected_item>=0 && selected_item!=list->Cursor_position+list->List_start)
 | 
			
		||||
  {
 | 
			
		||||
    Locate_list_item(list, selector, selected_item);
 | 
			
		||||
    
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
    // Mise à jour du scroller
 | 
			
		||||
    list->Scroller->Position=list->List_start;
 | 
			
		||||
    Window_draw_slider(list->Scroller);
 | 
			
		||||
    
 | 
			
		||||
    Window_redraw_list(list);
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    // Store the selected value as attribute2
 | 
			
		||||
    Window_attribute2=list->List_start + list->Cursor_position;
 | 
			
		||||
    // Return the control ID of the list.
 | 
			
		||||
    return list->Number;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
@ -1048,17 +1289,20 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
  T_Dropdown_button * formats_dropdown;
 | 
			
		||||
  T_Dropdown_button * bookmark_dropdown[4];
 | 
			
		||||
  short temp;
 | 
			
		||||
  unsigned int format;
 | 
			
		||||
  int dummy=0;       // Sert à appeler SDL_GetKeyState
 | 
			
		||||
  byte  save_or_load_image=0;
 | 
			
		||||
  byte  has_clicked_ok=0;// Indique si on a clické sur Load ou Save ou sur
 | 
			
		||||
                             //un bouton enclenchant Load ou Save juste après.
 | 
			
		||||
  byte  initial_back_color;             // |  fout en l'air (c'te conne).
 | 
			
		||||
  char  previous_directory[MAX_PATH_CHARACTERS]; // Répertoire d'où l'on vient après un CHDIR
 | 
			
		||||
  char  quicksearch_filename[MAX_PATH_CHARACTERS]="";
 | 
			
		||||
  char  save_filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
  char  initial_comment[COMMENT_SIZE+1];
 | 
			
		||||
  char * most_matching_filename;
 | 
			
		||||
  short window_shortcut;
 | 
			
		||||
 | 
			
		||||
  Reset_quicksearch();
 | 
			
		||||
  
 | 
			
		||||
  // if (Native_filesel(load) != 0); // TODO : handle this
 | 
			
		||||
  
 | 
			
		||||
  if (context->Type == CONTEXT_MAIN_IMAGE)
 | 
			
		||||
    window_shortcut = load?(0x100+BUTTON_LOAD):(0x100+BUTTON_SAVE);
 | 
			
		||||
@ -1099,7 +1343,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
    }
 | 
			
		||||
    // Affichage du commentaire
 | 
			
		||||
    if (Get_fileformat(Main_format)->Comment)
 | 
			
		||||
      Print_in_window(47,70,context->Comment,MC_Black,MC_Light);      
 | 
			
		||||
      Print_in_window(45,70,context->Comment,MC_Black,MC_Light);      
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Window_set_normal_button(253,180,51,14,"Cancel",0,1,KEY_ESC); // 2
 | 
			
		||||
@ -1124,11 +1368,11 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
      Get_fileformat(Main_format)->Label,
 | 
			
		||||
      1,0,1,RIGHT_SIDE|LEFT_SIDE,0); // 6
 | 
			
		||||
 | 
			
		||||
  for (temp=0; temp < NB_KNOWN_FORMATS; temp++)
 | 
			
		||||
  for (format=0; format < Nb_known_formats(); format++)
 | 
			
		||||
  {
 | 
			
		||||
    if ((load && (File_formats[temp].Identifier <= FORMAT_ALL_FILES || File_formats[temp].Load)) || 
 | 
			
		||||
      (!load && File_formats[temp].Save))
 | 
			
		||||
        Window_dropdown_add_item(formats_dropdown,File_formats[temp].Identifier,File_formats[temp].Label);
 | 
			
		||||
    if ((load && (File_formats[format].Identifier <= FORMAT_ALL_FILES || File_formats[format].Load)) || 
 | 
			
		||||
      (!load && File_formats[format].Save))
 | 
			
		||||
        Window_dropdown_add_item(formats_dropdown,File_formats[format].Identifier,File_formats[format].Label);
 | 
			
		||||
  }
 | 
			
		||||
  Print_in_window(70,18,"Format",MC_Dark,MC_Light);
 | 
			
		||||
  
 | 
			
		||||
@ -1161,13 +1405,30 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
  // On prend bien soin de passer dans le répertoire courant (le bon qui faut! Oui madame!)
 | 
			
		||||
  if (load)
 | 
			
		||||
  {
 | 
			
		||||
  #if defined(__MINT__)    
 | 
			
		||||
    chdir(Main_current_directory);
 | 
			
		||||
    static char path[1024]={0};
 | 
			
		||||
    Dgetpath(path,0);
 | 
			
		||||
    strcat(path,PATH_SEPARATOR);
 | 
			
		||||
    strcpy(Main_current_directory,path);  
 | 
			
		||||
  #else
 | 
			
		||||
    chdir(Main_current_directory);
 | 
			
		||||
    getcwd(Main_current_directory,256);
 | 
			
		||||
  #endif
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    #if defined(__MINT__)    
 | 
			
		||||
    chdir(context->File_directory);
 | 
			
		||||
    static char path[1024]={0};
 | 
			
		||||
    Dgetpath(path,0);
 | 
			
		||||
    strcat(path,PATH_SEPARATOR);
 | 
			
		||||
    strcpy(Main_current_directory,path);  
 | 
			
		||||
 #else
 | 
			
		||||
    getcwd(Main_current_directory,256);
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Affichage des premiers fichiers visibles:
 | 
			
		||||
@ -1181,7 +1442,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
    // On affiche le nouveau nom de fichier
 | 
			
		||||
    Print_filename_in_fileselector();
 | 
			
		||||
 | 
			
		||||
    Highlight_file(context->File_name);
 | 
			
		||||
    Highlight_file(Find_file_in_fileselector(&Filelist, context->File_name));
 | 
			
		||||
    Prepare_and_display_filelist(Main_fileselector_position,Main_fileselector_offset,file_scroller);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1309,7 +1570,8 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
            // On vient de changer de nom de fichier, donc on doit s'appreter
 | 
			
		||||
            // a rafficher une preview
 | 
			
		||||
            New_preview_is_needed=1;
 | 
			
		||||
            *quicksearch_filename=0;
 | 
			
		||||
            Reset_quicksearch();
 | 
			
		||||
            
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
@ -1322,7 +1584,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
 | 
			
		||||
            has_clicked_ok=1;
 | 
			
		||||
            New_preview_is_needed=1;
 | 
			
		||||
            *quicksearch_filename=0;
 | 
			
		||||
            Reset_quicksearch();
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        Display_cursor();
 | 
			
		||||
@ -1340,26 +1602,40 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
        Display_file_list(&Filelist, Main_fileselector_position,Main_fileselector_offset);
 | 
			
		||||
        Display_cursor();
 | 
			
		||||
        New_preview_is_needed=1;
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case  6 : // Scroller des formats
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        // On met à jour le format de browsing du fileselect:
 | 
			
		||||
        Main_format=Window_attribute2;
 | 
			
		||||
        // Comme on change de liste, on se place en début de liste:
 | 
			
		||||
        Main_fileselector_position=0;
 | 
			
		||||
        Main_fileselector_offset=0;
 | 
			
		||||
        // Affichage des premiers fichiers visibles:
 | 
			
		||||
        Reload_list_of_files(Main_format,file_scroller);
 | 
			
		||||
        Display_cursor();
 | 
			
		||||
        New_preview_is_needed=1;
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
	  case  6 : // Scroller des formats
 | 
			
		||||
		// On met à jour le format de browsing du fileselect:
 | 
			
		||||
		if (Main_format != Window_attribute2) {
 | 
			
		||||
			char* savename = (char *)strdup(Selector_filename);
 | 
			
		||||
			int nameLength = strlen(savename);
 | 
			
		||||
			DEBUG(Selector_filename, 42);
 | 
			
		||||
			Main_format = Window_attribute2;
 | 
			
		||||
			// Comme on change de liste, on se place en début de liste:
 | 
			
		||||
			Main_fileselector_position = 0;
 | 
			
		||||
			Main_fileselector_offset = 0;
 | 
			
		||||
			// Affichage des premiers fichiers visibles:
 | 
			
		||||
			Hide_cursor();
 | 
			
		||||
			Reload_list_of_files(Main_format, file_scroller);
 | 
			
		||||
			New_preview_is_needed = 1;
 | 
			
		||||
			Reset_quicksearch();
 | 
			
		||||
			strcpy(Selector_filename, savename);
 | 
			
		||||
			if (Get_fileformat(Main_format)->Default_extension[0] != '\0' &&
 | 
			
		||||
				Selector_filename[nameLength - 4] == '.')
 | 
			
		||||
			{
 | 
			
		||||
				strcpy(Selector_filename + nameLength - 3,
 | 
			
		||||
					Get_fileformat(Main_format)->Default_extension);
 | 
			
		||||
			}
 | 
			
		||||
			free(savename);
 | 
			
		||||
			Print_filename_in_fileselector();
 | 
			
		||||
        	Display_cursor();
 | 
			
		||||
		}
 | 
			
		||||
        break;
 | 
			
		||||
      case  7 : // Saisie d'un commentaire pour la sauvegarde
 | 
			
		||||
        if ( (!load) && (Get_fileformat(Main_format)->Comment) )
 | 
			
		||||
        {
 | 
			
		||||
          Readline(45,70,context->Comment,32,0);
 | 
			
		||||
          Readline(45, 70, context->Comment, 32, INPUT_TYPE_STRING);
 | 
			
		||||
          Display_cursor();
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
@ -1368,7 +1644,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
        // Save the filename
 | 
			
		||||
        strcpy(save_filename, Selector_filename);
 | 
			
		||||
 | 
			
		||||
        if (Readline(82,48,Selector_filename,27,2))
 | 
			
		||||
        if (Readline(82,48,Selector_filename,27,INPUT_TYPE_FILENAME))
 | 
			
		||||
        {
 | 
			
		||||
          //   On regarde s'il faut rajouter une extension. C'est-à-dire s'il
 | 
			
		||||
          // n'y a pas de '.' dans le nom du fichier.
 | 
			
		||||
@ -1382,7 +1658,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
              if(!Directory_exists(Selector_filename))
 | 
			
		||||
              {
 | 
			
		||||
                 strcat(Selector_filename, ".");
 | 
			
		||||
                 strcat(Selector_filename,Get_fileformat(Main_format)->Default_extension);
 | 
			
		||||
                strcat(Selector_filename, Get_fileformat(Main_format)->Default_extension);
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
@ -1438,7 +1714,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
          Prepare_and_display_filelist(Main_fileselector_position,Main_fileselector_offset,file_scroller);
 | 
			
		||||
          Display_cursor();
 | 
			
		||||
          New_preview_is_needed=1;
 | 
			
		||||
          *quicksearch_filename=0;
 | 
			
		||||
          Reset_quicksearch();
 | 
			
		||||
          break;
 | 
			
		||||
      default:
 | 
			
		||||
          if (clicked_button>=10 && clicked_button<10+NB_BOOKMARKS)
 | 
			
		||||
@ -1451,11 +1727,10 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
              case -1: // bouton lui-même: aller au répertoire mémorisé
 | 
			
		||||
                if (Config.Bookmark_directory[clicked_button-10])
 | 
			
		||||
                {
 | 
			
		||||
                  *quicksearch_filename=0;
 | 
			
		||||
                  strcpy(Selector_filename,Config.Bookmark_directory[clicked_button-10]);
 | 
			
		||||
                  Selected_type=1;
 | 
			
		||||
                  has_clicked_ok=1;
 | 
			
		||||
                  *quicksearch_filename=0;
 | 
			
		||||
                  Reset_quicksearch();
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
                
 | 
			
		||||
@ -1490,7 +1765,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
                  strcpy(bookmark_label, Config.Bookmark_label[clicked_button-10]);
 | 
			
		||||
                  if (bookmark_label[7]==ELLIPSIS_CHARACTER)
 | 
			
		||||
                    bookmark_label[7]='\0';
 | 
			
		||||
                  if (Readline_ex(bookmark_dropdown[clicked_button-10]->Pos_X+3+10,bookmark_dropdown[clicked_button-10]->Pos_Y+2,bookmark_label,8,8,0,0))
 | 
			
		||||
                  if (Readline_ex(bookmark_dropdown[clicked_button-10]->Pos_X+3+10,bookmark_dropdown[clicked_button-10]->Pos_Y+2,bookmark_label,8,8,INPUT_TYPE_STRING,0))
 | 
			
		||||
                    strcpy(Config.Bookmark_label[clicked_button-10],bookmark_label);
 | 
			
		||||
                  Display_bookmark(bookmark_dropdown[clicked_button-10],clicked_button-10);
 | 
			
		||||
                  Display_cursor();
 | 
			
		||||
@ -1515,63 +1790,63 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
    {
 | 
			
		||||
      case SDLK_UNKNOWN : break;
 | 
			
		||||
      case SDLK_DOWN : // Bas
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_scroll_down(&Main_fileselector_position,&Main_fileselector_offset);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case SDLK_UP : // Haut
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_scroll_up(&Main_fileselector_position,&Main_fileselector_offset);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case SDLK_PAGEDOWN : // PageDown
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_page_down(&Main_fileselector_position,&Main_fileselector_offset,9);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case SDLK_PAGEUP : // PageUp
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_page_up(&Main_fileselector_position,&Main_fileselector_offset,9);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case SDLK_END : // End
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_end(&Main_fileselector_position,&Main_fileselector_offset);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case SDLK_HOME : // Home
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_home(&Main_fileselector_position,&Main_fileselector_offset);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case KEY_MOUSEWHEELDOWN :
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_page_down(&Main_fileselector_position,&Main_fileselector_offset,3);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case KEY_MOUSEWHEELUP :
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        Hide_cursor();
 | 
			
		||||
        Selector_page_up(&Main_fileselector_position,&Main_fileselector_offset,3);
 | 
			
		||||
        Scroll_fileselector(file_scroller);
 | 
			
		||||
        Key=0;
 | 
			
		||||
        break;
 | 
			
		||||
      case SDLK_BACKSPACE : // Backspace
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
        // Si le choix ".." est bien en tête des propositions...
 | 
			
		||||
        if (!strcmp(Filelist.First->Full_name,PARENT_DIR))
 | 
			
		||||
        {                              
 | 
			
		||||
@ -1585,6 +1860,8 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
      default:
 | 
			
		||||
        if (clicked_button<=0)
 | 
			
		||||
        {
 | 
			
		||||
          short selected_item;
 | 
			
		||||
          
 | 
			
		||||
          if (Is_shortcut(Key,0x100+BUTTON_HELP))
 | 
			
		||||
          {
 | 
			
		||||
            Window_help(load?BUTTON_LOAD:BUTTON_SAVE, NULL);
 | 
			
		||||
@ -1595,30 +1872,22 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
            clicked_button=2;
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          // Autre => On se place sur le nom de fichier qui correspond
 | 
			
		||||
          temp=strlen(quicksearch_filename);
 | 
			
		||||
          if (Key_ANSI>= ' ' && Key_ANSI < 255 && temp<50)
 | 
			
		||||
          
 | 
			
		||||
          selected_item=Quicksearch(&Filelist);
 | 
			
		||||
          if (selected_item>=0)
 | 
			
		||||
          {
 | 
			
		||||
            quicksearch_filename[temp]=Key_ANSI;
 | 
			
		||||
            quicksearch_filename[temp+1]='\0';
 | 
			
		||||
            most_matching_filename=Find_filename_match(&Filelist, quicksearch_filename);
 | 
			
		||||
            if ( (most_matching_filename) )
 | 
			
		||||
            {
 | 
			
		||||
              temp=Main_fileselector_position+Main_fileselector_offset;
 | 
			
		||||
              Hide_cursor();
 | 
			
		||||
              Highlight_file(most_matching_filename);
 | 
			
		||||
              Highlight_file(selected_item);
 | 
			
		||||
              Prepare_and_display_filelist(Main_fileselector_position,Main_fileselector_offset,file_scroller);
 | 
			
		||||
              Display_cursor();
 | 
			
		||||
              if (temp!=Main_fileselector_position+Main_fileselector_offset)
 | 
			
		||||
                New_preview_is_needed=1;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
              *quicksearch_filename=0;
 | 
			
		||||
            Key=0;
 | 
			
		||||
          }
 | 
			
		||||
          // Key=0; ?
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          *quicksearch_filename=0;
 | 
			
		||||
          Reset_quicksearch();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (has_clicked_ok)
 | 
			
		||||
@ -1643,13 +1912,20 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
        // On doit rentrer dans le répertoire:
 | 
			
		||||
        if (!chdir(Selector_filename))
 | 
			
		||||
        {
 | 
			
		||||
        #if defined (__MINT__)          
 | 
			
		||||
          static char path[1024]={0};
 | 
			
		||||
          char currentDrive='A';
 | 
			
		||||
          currentDrive=currentDrive+Dgetdrv();
 | 
			
		||||
          Dgetpath(path,0);
 | 
			
		||||
         sprintf(Main_current_directory,"%c:\%s",currentDrive,path);
 | 
			
		||||
        #else
 | 
			
		||||
          getcwd(Main_current_directory,256);
 | 
			
		||||
  
 | 
			
		||||
        #endif
 | 
			
		||||
          // On lit le nouveau répertoire
 | 
			
		||||
          Read_list_of_files(&Filelist, Main_format);
 | 
			
		||||
          Sort_list_of_files(&Filelist);
 | 
			
		||||
          // On place la barre de sélection sur le répertoire d'où l'on vient
 | 
			
		||||
          Highlight_file(previous_directory);
 | 
			
		||||
          Highlight_file(Find_file_in_fileselector(&Filelist, previous_directory));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          Error(0);
 | 
			
		||||
@ -1659,7 +1935,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
        New_preview_is_needed=1;
 | 
			
		||||
 | 
			
		||||
        // On est dans un nouveau répertoire, donc on remet le quicksearch à 0
 | 
			
		||||
        *quicksearch_filename=0;
 | 
			
		||||
        Reset_quicksearch();
 | 
			
		||||
      }
 | 
			
		||||
      else  // Sinon on essaye de charger ou sauver le fichier
 | 
			
		||||
      {
 | 
			
		||||
@ -1681,7 +1957,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
        // On efface le commentaire précédent
 | 
			
		||||
        Window_rectangle(45,70,32*8,8,MC_Light);
 | 
			
		||||
        // On nettoie la zone où va s'afficher la preview:
 | 
			
		||||
        Window_rectangle(183,95,120,80,MC_Light);
 | 
			
		||||
        Window_rectangle(183,95,PREVIEW_WIDTH,PREVIEW_HEIGHT,MC_Light);
 | 
			
		||||
        // On efface les dimensions de l'image
 | 
			
		||||
        Window_rectangle(143,59,72,8,MC_Light);
 | 
			
		||||
        // On efface la taille du fichier
 | 
			
		||||
@ -1697,7 +1973,7 @@ byte Button_Load_or_Save(byte load, T_IO_Context *context)
 | 
			
		||||
        // Un update pour couvrir les 4 zones: 3 libellés plus le commentaire
 | 
			
		||||
        Update_window_area(45,48,256,30);
 | 
			
		||||
        // Zone de preview
 | 
			
		||||
        Update_window_area(183,95,120,80);
 | 
			
		||||
        Update_window_area(183,95,PREVIEW_WIDTH,PREVIEW_HEIGHT);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      New_preview_is_needed=0;
 | 
			
		||||
 | 
			
		||||
@ -31,12 +31,12 @@
 | 
			
		||||
 | 
			
		||||
byte Button_Load_or_Save(byte load, T_IO_Context *context);
 | 
			
		||||
 | 
			
		||||
void Add_element_to_list(T_Fileselector *list, const char * fname, int type);
 | 
			
		||||
void Add_element_to_list(T_Fileselector *list, const char * full_name, const char *short_name, int type, byte icon);
 | 
			
		||||
///
 | 
			
		||||
/// Formats a display name for a file, directory, or similar name (drive, volume).
 | 
			
		||||
/// The returned value is a pointer to a single static buffer of 19 characters
 | 
			
		||||
/// The returned value is a pointer to a single static buffer of maximum 40 characters
 | 
			
		||||
/// including the '\\0'.
 | 
			
		||||
char * Format_filename(const char * fname, int type);
 | 
			
		||||
char * Format_filename(const char * fname, word max_length, int type);
 | 
			
		||||
 | 
			
		||||
void Free_fileselector_list(T_Fileselector *list);
 | 
			
		||||
 | 
			
		||||
@ -48,4 +48,10 @@ T_Fileselector_item * Get_item_by_index(T_Fileselector *list, short index);
 | 
			
		||||
 | 
			
		||||
short Find_file_in_fileselector(T_Fileselector *list, const char * fname);
 | 
			
		||||
 | 
			
		||||
void Locate_list_item(T_List_button * list, T_Fileselector * selector, short selected_item);
 | 
			
		||||
 | 
			
		||||
int Quicksearch_list(T_List_button * list, T_Fileselector * selector);
 | 
			
		||||
 | 
			
		||||
void Reset_quicksearch(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										182
									
								
								src/global.h
									
									
									
									
									
								
							
							
						
						
									
										182
									
								
								src/global.h
									
									
									
									
									
								
							@ -73,6 +73,12 @@ GFX2_GLOBAL byte MC_Light; ///< Index of color to use as "light grey" in the GUI
 | 
			
		||||
GFX2_GLOBAL byte MC_White; ///< Index of color to use as "white" in the GUI menus.
 | 
			
		||||
GFX2_GLOBAL byte MC_Trans; ///< Index of color to use as "transparent" while loading the GUI file.
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL byte MC_OnBlack; ///< Index of color immediately lighter than "black" in the GUI menus.
 | 
			
		||||
GFX2_GLOBAL byte MC_Window; ///< Index of color to use as window background in the GUI menus.
 | 
			
		||||
GFX2_GLOBAL byte MC_Lighter; ///< Index of color lighter than window in the GUI menus.
 | 
			
		||||
GFX2_GLOBAL byte MC_Darker; ///< Index of color darker than window in the GUI menus.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Input state
 | 
			
		||||
GFX2_GLOBAL word Mouse_X; ///< Current mouse cursor position.
 | 
			
		||||
GFX2_GLOBAL word Mouse_Y; ///< Current mouse cursor position.
 | 
			
		||||
@ -294,10 +300,6 @@ GFX2_GLOBAL short Main_image_height;
 | 
			
		||||
GFX2_GLOBAL short Main_offset_X;
 | 
			
		||||
/// Y position (in image space) of the pixel to display in the top left corner of screen.
 | 
			
		||||
GFX2_GLOBAL short Main_offset_Y;
 | 
			
		||||
/// Backup of ::Main_offset_X, used to store it while the magnifier is open.
 | 
			
		||||
GFX2_GLOBAL short Old_main_offset_X;
 | 
			
		||||
/// Backup of ::Main_offset_Y, used to store it while the magnifier is open.
 | 
			
		||||
GFX2_GLOBAL short Old_main_offset_Y;
 | 
			
		||||
/// Name of the directory that holds the image currently edited.
 | 
			
		||||
GFX2_GLOBAL char  Main_file_directory[1024];
 | 
			
		||||
/// Filename (without directory) of the image currently edited.
 | 
			
		||||
@ -364,10 +366,6 @@ GFX2_GLOBAL short Spare_image_height;
 | 
			
		||||
GFX2_GLOBAL short Spare_offset_X;
 | 
			
		||||
/// Y position (in image space) of the pixel to display in the top left corner of screen.
 | 
			
		||||
GFX2_GLOBAL short Spare_offset_Y;
 | 
			
		||||
/// Backup of ::Main_offset_X, used to store it while the magnifier is open.
 | 
			
		||||
GFX2_GLOBAL short Old_spare_offset_X;
 | 
			
		||||
/// Backup of ::Main_offset_Y, used to store it while the magnifier is open.
 | 
			
		||||
GFX2_GLOBAL short Old_spare_offset_Y;
 | 
			
		||||
/// Name of the directory that holds the image currently edited as spare page.
 | 
			
		||||
GFX2_GLOBAL char  Spare_file_directory[MAX_PATH_CHARACTERS];
 | 
			
		||||
/// Filename (without directory) of the image currently edited as spare page.
 | 
			
		||||
@ -432,8 +430,16 @@ GFX2_GLOBAL T_List_of_pages * Spare_backups;
 | 
			
		||||
 | 
			
		||||
// -- Brush data
 | 
			
		||||
 | 
			
		||||
/// Pixel data of the current brush.
 | 
			
		||||
/// Pixel data of the current brush (remapped).
 | 
			
		||||
GFX2_GLOBAL byte * Brush;
 | 
			
		||||
/// Pixel data of the current brush (before remap).
 | 
			
		||||
GFX2_GLOBAL byte * Brush_original_pixels;
 | 
			
		||||
/// Palette of the brush, from when it was grabbed.
 | 
			
		||||
GFX2_GLOBAL T_Palette Brush_original_palette;
 | 
			
		||||
/// Back_color used when the brush was grabbed
 | 
			
		||||
GFX2_GLOBAL byte Brush_original_back_color;
 | 
			
		||||
/// Color mapping from ::Brush_original_pixels to ::Brush
 | 
			
		||||
GFX2_GLOBAL byte Brush_colormap[256];
 | 
			
		||||
/// X coordinate of the brush's "hot spot". It is < ::Brush_width
 | 
			
		||||
GFX2_GLOBAL word Brush_offset_X;
 | 
			
		||||
/// Y coordinate of the brush's "hot spot". It is < ::Brush_height
 | 
			
		||||
@ -492,9 +498,9 @@ GFX2_GLOBAL word  Menu_palette_cell_width;
 | 
			
		||||
GFX2_GLOBAL T_Menu_Bar Menu_bars[MENUBAR_COUNT] 
 | 
			
		||||
#ifdef GLOBAL_VARIABLES
 | 
			
		||||
  = 
 | 
			
		||||
{{MENU_WIDTH,  9, 1, 45, NULL,  20, BUTTON_HIDE }, // Status
 | 
			
		||||
 {MENU_WIDTH, 10, 1, 35, NULL, 144, BUTTON_LAYER_SELECT }, // Layers
 | 
			
		||||
 {MENU_WIDTH, 35, 1,  0, NULL, 254, BUTTON_CHOOSE_COL }} // Main
 | 
			
		||||
{{MENU_WIDTH,  9, 1, 45, {NULL,NULL,NULL},  20, BUTTON_HIDE }, // Status
 | 
			
		||||
 {MENU_WIDTH, 10, 1, 35, {NULL,NULL,NULL}, 144, BUTTON_LAYER_SELECT }, // Layers
 | 
			
		||||
 {MENU_WIDTH, 35, 1,  0, {NULL,NULL,NULL}, 254, BUTTON_CHOOSE_COL }} // Main
 | 
			
		||||
#endif
 | 
			
		||||
 ;
 | 
			
		||||
 | 
			
		||||
@ -510,71 +516,59 @@ GFX2_GLOBAL word Menu_Y_before_window;
 | 
			
		||||
/// Backup of ::Paintbrush_hidden, used to store it while a window is open.
 | 
			
		||||
GFX2_GLOBAL byte Paintbrush_hidden_before_window;
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL word Window_stack_pos_X[8];
 | 
			
		||||
/// The global stack of editor screens.
 | 
			
		||||
GFX2_GLOBAL T_Window Window_stack[8];
 | 
			
		||||
 | 
			
		||||
/// Position of the left border of the topmost window (in screen coordinates)
 | 
			
		||||
#define Window_pos_X Window_stack_pos_X[Windows_open-1]
 | 
			
		||||
#define Window_pos_X Window_stack[Windows_open-1].Pos_X
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL word Window_stack_pos_Y[8];
 | 
			
		||||
/// Position of the top border of the topmost window (in screen coordinates)
 | 
			
		||||
#define Window_pos_Y Window_stack_pos_Y[Windows_open-1]
 | 
			
		||||
#define Window_pos_Y Window_stack[Windows_open-1].Pos_Y
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL word Window_stack_width[8];
 | 
			
		||||
///
 | 
			
		||||
/// Width of the topmost window, in "window pixels"
 | 
			
		||||
/// (multiply by ::Menu_factor_X to get screen pixels)
 | 
			
		||||
#define Window_width Window_stack_width[Windows_open-1]
 | 
			
		||||
#define Window_width Window_stack[Windows_open-1].Width
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL word Window_stack_height[8];
 | 
			
		||||
///
 | 
			
		||||
/// Height of the topmost window, in "window pixels"
 | 
			
		||||
/// (multiply by ::Menu_factor_Y to get screen pixels)
 | 
			
		||||
#define Window_height Window_stack_height[Windows_open-1]
 | 
			
		||||
#define Window_height Window_stack[Windows_open-1].Height
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL word Window_stack_nb_buttons[8];
 | 
			
		||||
/// Total number of buttons/controls in the topmost window.
 | 
			
		||||
#define Window_nb_buttons Window_stack_nb_buttons[Windows_open-1]
 | 
			
		||||
#define Window_nb_buttons Window_stack[Windows_open-1].Nb_buttons
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL T_Normal_button   * Window_stack_normal_button_list[8];
 | 
			
		||||
/// List of normal buttons in the topmost window.
 | 
			
		||||
#define Window_normal_button_list Window_stack_normal_button_list[Windows_open-1]
 | 
			
		||||
#define Window_normal_button_list Window_stack[Windows_open-1].Normal_button_list
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL T_Palette_button  * Window_stack_palette_button_list[8];
 | 
			
		||||
/// List of "palette" buttons in the topmost window.
 | 
			
		||||
#define Window_palette_button_list Window_stack_palette_button_list[Windows_open-1]
 | 
			
		||||
#define Window_palette_button_list Window_stack[Windows_open-1].Palette_button_list
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL T_Scroller_button * Window_stack_scroller_button_list[8];
 | 
			
		||||
/// List of sliders (scrollers) in the topmost window.
 | 
			
		||||
#define Window_scroller_button_list Window_stack_scroller_button_list[Windows_open-1]
 | 
			
		||||
#define Window_scroller_button_list Window_stack[Windows_open-1].Scroller_button_list
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL T_Special_button  * Window_stack_special_button_list[8];
 | 
			
		||||
/// List of special buttons in the topmost window.
 | 
			
		||||
#define Window_special_button_list Window_stack_special_button_list[Windows_open-1]
 | 
			
		||||
#define Window_special_button_list Window_stack[Windows_open-1].Special_button_list
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL T_Dropdown_button  * Window_stack_dropdown_button_list[8];
 | 
			
		||||
/// List of dropdown buttons in the topmost window.
 | 
			
		||||
#define Window_dropdown_button_list Window_stack_dropdown_button_list[Windows_open-1]
 | 
			
		||||
#define Window_dropdown_button_list Window_stack[Windows_open-1].Dropdown_button_list
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL T_List_button  * Window_stack_list_button_list[8];
 | 
			
		||||
/// List of list buttons in the topmost window.
 | 
			
		||||
#define Window_list_button_list Window_stack_list_button_list[Windows_open-1]
 | 
			
		||||
#define Window_list_button_list Window_stack[Windows_open-1].List_button_list
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL int Window_stack_attribute1[8];
 | 
			
		||||
///
 | 
			
		||||
/// The function ::Window_clicked_button() set this to ::LEFT_SIDE or ::RIGHT_SIDE
 | 
			
		||||
/// after a button is activated through left or right mouse click.
 | 
			
		||||
#define Window_attribute1 Window_stack_attribute1[Windows_open-1]
 | 
			
		||||
#define Window_attribute1 Window_stack[Windows_open-1].Attribute1
 | 
			
		||||
 | 
			
		||||
GFX2_GLOBAL int Window_stack_attribute2[8];
 | 
			
		||||
///
 | 
			
		||||
/// The function ::Window_clicked_button() set this to return extra information:
 | 
			
		||||
/// - When a scroller was clicked: the scroller position (0-n)
 | 
			
		||||
/// - When a palette was clicked: the color index (0-255)
 | 
			
		||||
/// - When a dropdown was used: the selected item's number T_Dropdown_choice::Number
 | 
			
		||||
#define Window_attribute2 Window_stack_attribute2[Windows_open-1]
 | 
			
		||||
 | 
			
		||||
#define Window_attribute2 Window_stack[Windows_open-1].Attribute2
 | 
			
		||||
 | 
			
		||||
#define Window_draggable Window_stack[Windows_open-1].Draggable
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Definition of the menu (toolbox)
 | 
			
		||||
@ -587,6 +581,7 @@ GFX2_GLOBAL struct
 | 
			
		||||
  word            Height;           ///< Button's active heigth
 | 
			
		||||
  byte            Pressed;          ///< Button is currently pressed
 | 
			
		||||
  byte            Shape;            ///< Shape, listed in enum ::BUTTON_SHAPES
 | 
			
		||||
  char            Icon;             ///< Which icon to display: Either the one from the toolbar (-1) or one of ::MENU_SPRITE
 | 
			
		||||
 | 
			
		||||
  // Triggers on mouse/keyboard
 | 
			
		||||
  Func_action     Left_action;      ///< Action triggered by a left mouseclick on the button
 | 
			
		||||
@ -765,6 +760,8 @@ GFX2_GLOBAL long  Gradient_bounds_range;
 | 
			
		||||
GFX2_GLOBAL long  Gradient_total_range;
 | 
			
		||||
/// Amount of randomness to use in gradient (1-256+)
 | 
			
		||||
GFX2_GLOBAL long  Gradient_random_factor;
 | 
			
		||||
/// Gradient speed of cycling (0-64)
 | 
			
		||||
GFX2_GLOBAL byte  Gradient_speed;
 | 
			
		||||
/// Pointer to a gradient function, depending on the selected method.
 | 
			
		||||
GFX2_GLOBAL Func_gradient Gradient_function;
 | 
			
		||||
///
 | 
			
		||||
@ -772,10 +769,10 @@ GFX2_GLOBAL Func_gradient Gradient_function;
 | 
			
		||||
/// either ::Pixel (if the gradient must be drawn on menus only)
 | 
			
		||||
/// or ::Display_pixel (if the gradient must be drawn on the image)
 | 
			
		||||
GFX2_GLOBAL Func_pixel Gradient_pixel;
 | 
			
		||||
/// Settings for all gradients
 | 
			
		||||
GFX2_GLOBAL T_Gradient_array Gradient_array[16];
 | 
			
		||||
/// Index in ::Gradient_array of the currently selected gradient.
 | 
			
		||||
GFX2_GLOBAL byte Current_gradient;
 | 
			
		||||
/// Boolean, true when the color cycling is active.
 | 
			
		||||
GFX2_GLOBAL byte Cycling_mode;
 | 
			
		||||
 | 
			
		||||
// -- Airbrush data
 | 
			
		||||
 | 
			
		||||
@ -823,6 +820,9 @@ GFX2_GLOBAL byte * Menu_font;
 | 
			
		||||
/// Pointer to the current active skin.
 | 
			
		||||
GFX2_GLOBAL T_Gui_skin * Gfx;
 | 
			
		||||
 | 
			
		||||
/// Pointer to the current active skin.
 | 
			
		||||
GFX2_GLOBAL T_Paintbrush Paintbrush[NB_PAINTBRUSH_SPRITES];
 | 
			
		||||
 | 
			
		||||
// -- Help data
 | 
			
		||||
 | 
			
		||||
/// Index of the ::Help_section shown by the Help screen.
 | 
			
		||||
@ -894,6 +894,7 @@ GFX2_GLOBAL T_Brush_template Brush_container[BRUSH_CONTAINER_COLUMNS*BRUSH_CONTA
 | 
			
		||||
    CURSOR_SHAPE_XOR_TARGET        , // Stretch brush
 | 
			
		||||
    CURSOR_SHAPE_TARGET            , // Distort brush
 | 
			
		||||
    CURSOR_SHAPE_XOR_TARGET        , // Gradient-filled rectangle
 | 
			
		||||
    CURSOR_SHAPE_COLORPICKER       , // Colorpick on right mouse button
 | 
			
		||||
  };
 | 
			
		||||
#else
 | 
			
		||||
  /// ::Cursor_shape to use for each operation.
 | 
			
		||||
@ -950,34 +951,83 @@ GFX2_GLOBAL SDL_Joystick* Joystick;
 | 
			
		||||
/// It was chosen to not conflict with any SDL key number.
 | 
			
		||||
#define KEY_JOYBUTTON       (SDLK_LAST+4)
 | 
			
		||||
 | 
			
		||||
/// Button definitions for the gp2x
 | 
			
		||||
#define GP2X_BUTTON_UP              (0)
 | 
			
		||||
#define GP2X_BUTTON_DOWN            (4)
 | 
			
		||||
#define GP2X_BUTTON_LEFT            (2)
 | 
			
		||||
#define GP2X_BUTTON_RIGHT           (6)
 | 
			
		||||
#define GP2X_BUTTON_UPLEFT          (1)
 | 
			
		||||
#define GP2X_BUTTON_UPRIGHT         (7)
 | 
			
		||||
#define GP2X_BUTTON_DOWNLEFT        (3)
 | 
			
		||||
#define GP2X_BUTTON_DOWNRIGHT       (5)
 | 
			
		||||
#define GP2X_BUTTON_CLICK           (18)
 | 
			
		||||
#define GP2X_BUTTON_A               (12)
 | 
			
		||||
#define GP2X_BUTTON_B               (13)
 | 
			
		||||
#define GP2X_BUTTON_Y               (14)
 | 
			
		||||
#define GP2X_BUTTON_X               (15)
 | 
			
		||||
#define GP2X_BUTTON_L               (10)
 | 
			
		||||
#define GP2X_BUTTON_R               (11)
 | 
			
		||||
#define GP2X_BUTTON_START           (8)
 | 
			
		||||
#define GP2X_BUTTON_SELECT          (9)
 | 
			
		||||
#define GP2X_BUTTON_VOLUP           (16)
 | 
			
		||||
#define GP2X_BUTTON_VOLDOWN         (17)
 | 
			
		||||
/// The joystick axis are {X,Y} - on all platforms so far.
 | 
			
		||||
/// If there is ever a platform where they are reversed, put
 | 
			
		||||
/// these lines in each platform "case" below.
 | 
			
		||||
#define JOYSTICK_AXIS_X             (0)
 | 
			
		||||
#define JOYSTICK_AXIS_Y             (1)
 | 
			
		||||
 | 
			
		||||
#ifdef __gp2x__
 | 
			
		||||
  #define KEY_ESC (KEY_JOYBUTTON+GP2X_BUTTON_X)
 | 
			
		||||
#ifdef __GP2X__
 | 
			
		||||
 | 
			
		||||
    #define JOYSTICK_THRESHOLD  (4096)
 | 
			
		||||
 | 
			
		||||
    /// Button definitions for the gp2x
 | 
			
		||||
    #define JOY_BUTTON_UP              (0)
 | 
			
		||||
    #define JOY_BUTTON_DOWN            (4)
 | 
			
		||||
    #define JOY_BUTTON_LEFT            (2)
 | 
			
		||||
    #define JOY_BUTTON_RIGHT           (6)
 | 
			
		||||
    #define JOY_BUTTON_UPLEFT          (1)
 | 
			
		||||
    #define JOY_BUTTON_UPRIGHT         (7)
 | 
			
		||||
    #define JOY_BUTTON_DOWNLEFT        (3)
 | 
			
		||||
    #define JOY_BUTTON_DOWNRIGHT       (5)
 | 
			
		||||
    #define JOY_BUTTON_CLICK           (18)
 | 
			
		||||
    #define JOY_BUTTON_A               (12)
 | 
			
		||||
    #define JOY_BUTTON_B               (13)
 | 
			
		||||
    #define JOY_BUTTON_Y               (14)
 | 
			
		||||
    #define JOY_BUTTON_X               (15)
 | 
			
		||||
    #define JOY_BUTTON_L               (10)
 | 
			
		||||
    #define JOY_BUTTON_R               (11)
 | 
			
		||||
    #define JOY_BUTTON_START           (8)
 | 
			
		||||
    #define JOY_BUTTON_SELECT          (9)
 | 
			
		||||
    #define JOY_BUTTON_VOLUP           (16)
 | 
			
		||||
    #define JOY_BUTTON_VOLDOWN         (17)
 | 
			
		||||
    
 | 
			
		||||
    #define KEY_ESC (KEY_JOYBUTTON+JOY_BUTTON_X)
 | 
			
		||||
#elif defined(__WIZ__)
 | 
			
		||||
    /// Button definitions for the Wiz
 | 
			
		||||
    #define JOY_BUTTON_UP               (0)
 | 
			
		||||
    #define JOY_BUTTON_DOWN             (4)
 | 
			
		||||
    #define JOY_BUTTON_LEFT             (2)
 | 
			
		||||
    #define JOY_BUTTON_RIGHT            (6)
 | 
			
		||||
    #define JOY_BUTTON_UPLEFT           (1)
 | 
			
		||||
    #define JOY_BUTTON_UPRIGHT          (7)
 | 
			
		||||
    #define JOY_BUTTON_DOWNLEFT         (3)
 | 
			
		||||
    #define JOY_BUTTON_DOWNRIGHT        (5)
 | 
			
		||||
    #define JOY_BUTTON_L                (10)
 | 
			
		||||
    #define JOY_BUTTON_R                (11)
 | 
			
		||||
    #define JOY_BUTTON_A                (12)
 | 
			
		||||
    #define JOY_BUTTON_B                (13)
 | 
			
		||||
    #define JOY_BUTTON_X                (14)
 | 
			
		||||
    #define JOY_BUTTON_Y                (15)
 | 
			
		||||
    #define JOY_BUTTON_MENU             (8)
 | 
			
		||||
    #define JOY_BUTTON_SELECT           (9)
 | 
			
		||||
    #define JOY_BUTTON_VOLUP            (16)
 | 
			
		||||
    #define JOY_BUTTON_VOLDOWN          (17)
 | 
			
		||||
 | 
			
		||||
    #define KEY_ESC (KEY_JOYBUTTON+JOY_BUTTON_X)
 | 
			
		||||
#elif defined (__CAANOO__)
 | 
			
		||||
 | 
			
		||||
    #define JOYSTICK_THRESHOLD  (4096)
 | 
			
		||||
 | 
			
		||||
    /// Button definitions for the Caanoo
 | 
			
		||||
    #define JOY_BUTTON_A             (0)
 | 
			
		||||
    #define JOY_BUTTON_X             (1)
 | 
			
		||||
    #define JOY_BUTTON_B             (2)
 | 
			
		||||
    #define JOY_BUTTON_Y             (3)
 | 
			
		||||
    #define JOY_BUTTON_L             (4)
 | 
			
		||||
    #define JOY_BUTTON_R             (5)
 | 
			
		||||
    #define JOY_BUTTON_HOME          (6)
 | 
			
		||||
    #define JOY_BUTTON_HOLD          (7)
 | 
			
		||||
    #define JOY_BUTTON_I             (8)
 | 
			
		||||
    #define JOY_BUTTON_II            (9)
 | 
			
		||||
    #define JOY_BUTTON_JOY           (10)
 | 
			
		||||
 | 
			
		||||
    #define KEY_ESC (KEY_JOYBUTTON+JOY_BUTTON_HOME)
 | 
			
		||||
#else
 | 
			
		||||
  ///
 | 
			
		||||
  /// This is the key identifier for ESC. When hard-coding keyboard shortcuts
 | 
			
		||||
  /// for buttons, etc. we use this instead of SDLK_ESCAPE,
 | 
			
		||||
  /// so the GP2X port can get a joybutton equivalent of it.
 | 
			
		||||
  /// so the console ports can get a joybutton equivalent of it.
 | 
			
		||||
  #define KEY_ESC SDLK_ESCAPE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										124
									
								
								src/graph.c
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								src/graph.c
									
									
									
									
									
								
							@ -48,12 +48,13 @@
 | 
			
		||||
#include "pxquad.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
#include "brush.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __VBCC__
 | 
			
		||||
    #define __attribute__(x)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__VBCC__)||defined(__GP2X__)
 | 
			
		||||
#if defined(__VBCC__) || defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
    #define M_PI 3.141592653589793238462643
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -522,6 +523,8 @@ try_again:
 | 
			
		||||
      Menu_factor_Y=1;
 | 
			
		||||
      break;
 | 
			
		||||
    default: // Stay below some reasonable size
 | 
			
		||||
      if (factor>Max(Pixel_width,Pixel_height))
 | 
			
		||||
        factor/=Max(Pixel_width,Pixel_height);
 | 
			
		||||
      Menu_factor_X=Min(factor,abs(Config.Ratio));
 | 
			
		||||
      Menu_factor_Y=Min(factor,abs(Config.Ratio));
 | 
			
		||||
  }
 | 
			
		||||
@ -617,7 +620,8 @@ void Resize_image(word chosen_width,word chosen_height)
 | 
			
		||||
  // |B| |    C   = Nouvelle image
 | 
			
		||||
  // +-+-+
 | 
			
		||||
 | 
			
		||||
  if (Backup_with_new_dimensions(1,Main_backups->Pages->Nb_layers,chosen_width,chosen_height))
 | 
			
		||||
  Upload_infos_page_main(Main_backups->Pages);
 | 
			
		||||
  if (Backup_with_new_dimensions(chosen_width,chosen_height))
 | 
			
		||||
  {
 | 
			
		||||
    // La nouvelle page a pu être allouée, elle est pour l'instant pleine de
 | 
			
		||||
    // 0s. Elle fait Main_image_width de large.
 | 
			
		||||
@ -672,13 +676,16 @@ void Remap_spare(void)
 | 
			
		||||
  //       ne seront pas utilisées par Remap_general_lowlevel.
 | 
			
		||||
  for (color=0;color<=255;color++)
 | 
			
		||||
    if (used[color])
 | 
			
		||||
      used[color]=Best_color(Spare_palette[color].R,Spare_palette[color].G,Spare_palette[color].B);
 | 
			
		||||
      used[color]=Best_color_perceptual(Spare_palette[color].R,Spare_palette[color].G,Spare_palette[color].B);
 | 
			
		||||
 | 
			
		||||
  //   Maintenant qu'on a une super table de conversion qui n'a que le nom
 | 
			
		||||
  // qui craint un peu, on peut faire l'échange dans la brosse de toutes les
 | 
			
		||||
  // teintes.
 | 
			
		||||
  for (layer=0; layer<Spare_backups->Pages->Nb_layers; layer++)
 | 
			
		||||
    Remap_general_lowlevel(used,Spare_backups->Pages->Image[layer],Spare_image_width,Spare_image_height,Spare_image_width);
 | 
			
		||||
    Remap_general_lowlevel(used,Spare_backups->Pages->Image[layer],Spare_backups->Pages->Image[layer],Spare_image_width,Spare_image_height,Spare_image_width);
 | 
			
		||||
    
 | 
			
		||||
  // Change transparent color index
 | 
			
		||||
  Spare_backups->Pages->Transparent_color=used[Spare_backups->Pages->Transparent_color];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -687,43 +694,89 @@ void Get_colors_from_brush(void)
 | 
			
		||||
{
 | 
			
		||||
  short x_pos; // Variable de balayage de la brosse
 | 
			
		||||
  short y_pos; // Variable de balayage de la brosse
 | 
			
		||||
  byte  used[256]; // Tableau de booléens "La couleur est utilisée"
 | 
			
		||||
  byte  brush_used[256]; // Tableau de booléens "La couleur est utilisée"
 | 
			
		||||
  dword usage[256];
 | 
			
		||||
  int   color;
 | 
			
		||||
  int   image_color;
 | 
			
		||||
 | 
			
		||||
  if (Confirmation_box("Modify current palette ?"))
 | 
			
		||||
  //if (Confirmation_box("Modify current palette ?"))
 | 
			
		||||
  
 | 
			
		||||
  // Backup with unchanged layers, only palette is modified
 | 
			
		||||
  Backup_layers(0);
 | 
			
		||||
 | 
			
		||||
  // Init array of new colors  
 | 
			
		||||
  for (color=0;color<=255;color++)
 | 
			
		||||
    brush_used[color]=0;
 | 
			
		||||
 | 
			
		||||
  // Tag used colors
 | 
			
		||||
  for (y_pos=0;y_pos<Brush_height;y_pos++)
 | 
			
		||||
    for (x_pos=0;x_pos<Brush_width;x_pos++)
 | 
			
		||||
      brush_used[*(Brush_original_pixels + y_pos * Brush_width + x_pos)]=1;
 | 
			
		||||
 | 
			
		||||
  // Check used colors in picture (to know which palette entries are free)
 | 
			
		||||
  Count_used_colors(usage);
 | 
			
		||||
  
 | 
			
		||||
  // First pass : omit colors that are already in palette
 | 
			
		||||
  for (color=0; color<256; color++)
 | 
			
		||||
  {
 | 
			
		||||
    // Backup with unchanged layers, only palette is modified
 | 
			
		||||
    Backup_layers(0);
 | 
			
		||||
 | 
			
		||||
    // On commence par initialiser le tableau de booléen à faux
 | 
			
		||||
    for (color=0;color<=255;color++)
 | 
			
		||||
      used[color]=0;
 | 
			
		||||
 | 
			
		||||
    // On calcule la table d'utilisation des couleurs
 | 
			
		||||
    for (y_pos=0;y_pos<Brush_height;y_pos++)
 | 
			
		||||
      for (x_pos=0;x_pos<Brush_width;x_pos++)
 | 
			
		||||
        used[Read_pixel_from_brush(x_pos,y_pos)]=1;
 | 
			
		||||
 | 
			
		||||
    // On recopie dans la palette principale les teintes des couleurs utilisées
 | 
			
		||||
    // dans la palette du brouillon
 | 
			
		||||
    for (color=0;color<=255;color++)
 | 
			
		||||
      if (used[color])
 | 
			
		||||
    // For each color used in brush (to add in palette)
 | 
			
		||||
    if (brush_used[color])
 | 
			
		||||
    {
 | 
			
		||||
      // Try locate it in current palette
 | 
			
		||||
      for (image_color=0; image_color<256; image_color++)
 | 
			
		||||
      {
 | 
			
		||||
        Main_palette[color].R=Spare_palette[color].R;
 | 
			
		||||
        Main_palette[color].G=Spare_palette[color].G;
 | 
			
		||||
        Main_palette[color].B=Spare_palette[color].B;
 | 
			
		||||
        if (Brush_original_palette[color].R==Main_palette[image_color].R
 | 
			
		||||
         && Brush_original_palette[color].G==Main_palette[image_color].G
 | 
			
		||||
         && Brush_original_palette[color].B==Main_palette[image_color].B)
 | 
			
		||||
        {
 | 
			
		||||
          // Color already in main palette:
 | 
			
		||||
          
 | 
			
		||||
          // Tag as used, so that no new color will overwrite it
 | 
			
		||||
          usage[image_color]=1;
 | 
			
		||||
 | 
			
		||||
          // Tag as non-new, to avoid it in pass 2
 | 
			
		||||
          brush_used[color]=0;
 | 
			
		||||
          
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    Set_palette(Main_palette);
 | 
			
		||||
    Compute_optimal_menu_colors(Main_palette);
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
    Display_all_screen();
 | 
			
		||||
    Display_menu();
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    End_of_modification();
 | 
			
		||||
 | 
			
		||||
    Main_image_is_modified=1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Second pass : For each color to add, find an empty slot in 
 | 
			
		||||
  // main palette to add it
 | 
			
		||||
  image_color=0;
 | 
			
		||||
  for (color=0; color<256 && image_color<256; color++)
 | 
			
		||||
  {
 | 
			
		||||
    // For each color used in brush
 | 
			
		||||
    if (brush_used[color])
 | 
			
		||||
    {
 | 
			
		||||
      for (; image_color<256; image_color++)
 | 
			
		||||
      {
 | 
			
		||||
        if (!usage[image_color])
 | 
			
		||||
        {
 | 
			
		||||
          // Copy from color to image_color
 | 
			
		||||
          Main_palette[image_color].R=Brush_original_palette[color].R;
 | 
			
		||||
          Main_palette[image_color].G=Brush_original_palette[color].G;
 | 
			
		||||
          Main_palette[image_color].B=Brush_original_palette[color].B;
 | 
			
		||||
          
 | 
			
		||||
          image_color++;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  Remap_brush();
 | 
			
		||||
 | 
			
		||||
  Set_palette(Main_palette);
 | 
			
		||||
  Compute_optimal_menu_colors(Main_palette);
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
  Display_all_screen();
 | 
			
		||||
  Display_menu();
 | 
			
		||||
  Display_cursor();
 | 
			
		||||
  End_of_modification();
 | 
			
		||||
 | 
			
		||||
  Main_image_is_modified=1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1082,6 +1135,7 @@ void Fill_general(byte fill_color)
 | 
			
		||||
    if (! (Permanent_draw_count&7))
 | 
			
		||||
    {
 | 
			
		||||
      Uint32 now = SDL_GetTicks();
 | 
			
		||||
      SDL_PumpEvents();
 | 
			
		||||
      if (now>= Permanent_draw_next_refresh)
 | 
			
		||||
      {
 | 
			
		||||
        Permanent_draw_next_refresh = now+100;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										256
									
								
								src/help.c
									
									
									
									
									
								
							
							
						
						
									
										256
									
								
								src/help.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -31,6 +32,10 @@
 | 
			
		||||
    #include <sys/mount.h>
 | 
			
		||||
#elif defined (__linux__)
 | 
			
		||||
    #include <sys/vfs.h>
 | 
			
		||||
#elif defined (__MINT__)
 | 
			
		||||
    #include <mint/sysbind.h>
 | 
			
		||||
    #include <mint/osbind.h>
 | 
			
		||||
    #include <mint/ostruct.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "const.h"
 | 
			
		||||
@ -92,7 +97,7 @@ void Redefine_control(word *shortcut, int x_pos, int y_pos)
 | 
			
		||||
  Display_cursor();
 | 
			
		||||
  while (1)
 | 
			
		||||
  {
 | 
			
		||||
    while(!Get_input())SDL_Delay(20);
 | 
			
		||||
    Get_input(20);
 | 
			
		||||
    if (Key==KEY_ESC)
 | 
			
		||||
      return;
 | 
			
		||||
    if (Key!=0)
 | 
			
		||||
@ -231,22 +236,102 @@ void Window_set_shortcut(int action_id)
 | 
			
		||||
  Display_cursor();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// -- Menu d'aide -----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
void Display_help(void)
 | 
			
		||||
///
 | 
			
		||||
/// Print a line with the 'help' (6x8) font.
 | 
			
		||||
short Print_help(short x_pos, short y_pos, const char *line, char line_type, short link_position, short link_size)
 | 
			
		||||
{
 | 
			
		||||
  short  width;             // Largeur physique d'une ligne de texte
 | 
			
		||||
  short  x;                   // Indices d'affichage d'un caractère
 | 
			
		||||
  short  y;
 | 
			
		||||
  short  x_position;          // Parcours de remplissage du buffer de ligne
 | 
			
		||||
  short  line_index;     // 0-15 (16 lignes de textes)
 | 
			
		||||
  short  char_index; // Parcours des caractères d'une ligne
 | 
			
		||||
  short  start_line=Help_position;
 | 
			
		||||
  byte * char_pixel;
 | 
			
		||||
  short  repeat_menu_x_factor;
 | 
			
		||||
  short  repeat_menu_y_factor;
 | 
			
		||||
  short  real_x_pos;
 | 
			
		||||
  short  real_y_pos;
 | 
			
		||||
  byte * char_pixel;
 | 
			
		||||
  short  width;             // Largeur physique d'une ligne de texte
 | 
			
		||||
 | 
			
		||||
  real_x_pos=ToWinX(x_pos);
 | 
			
		||||
  real_y_pos=ToWinY(y_pos);
 | 
			
		||||
  
 | 
			
		||||
  // Calcul de la taille
 | 
			
		||||
  width=strlen(line);
 | 
			
		||||
  // Les lignes de titres prennent plus de place
 | 
			
		||||
  if (line_type == 'T' || line_type == '-')
 | 
			
		||||
    width = width*2;
 | 
			
		||||
 | 
			
		||||
  // Pour chaque ligne dans la fenêtre:
 | 
			
		||||
  for (y=0;y<8;y++)
 | 
			
		||||
  {
 | 
			
		||||
    x_position=0;
 | 
			
		||||
    // On crée une nouvelle ligne à splotcher
 | 
			
		||||
    for (char_index=0;char_index<width;char_index++)
 | 
			
		||||
    {
 | 
			
		||||
      // Recherche du caractère dans les fontes de l'aide.
 | 
			
		||||
      // Ligne titre : Si l'indice est impair on dessine le quart de caractère
 | 
			
		||||
      // qui va a gauche, sinon celui qui va a droite.
 | 
			
		||||
      if (line_type=='T')
 | 
			
		||||
      {
 | 
			
		||||
        if (line[char_index/2]>'_' || line[char_index/2]<' ')
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré
 | 
			
		||||
        else if (char_index & 1)
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_t2[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
        else
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_t1[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
      }
 | 
			
		||||
      else if (line_type=='-')
 | 
			
		||||
      {
 | 
			
		||||
        if (line[char_index/2]>'_' || line[char_index/2]<' ')
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré
 | 
			
		||||
        else if (char_index & 1)
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_t4[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
        else
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_t3[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
      }
 | 
			
		||||
      else if (line_type=='S')
 | 
			
		||||
        char_pixel=&(Gfx->Bold_font[(unsigned char)(line[char_index])][0][0]);
 | 
			
		||||
      else if (line_type=='N' || line_type=='K')
 | 
			
		||||
        char_pixel=&(Gfx->Help_font_norm[(unsigned char)(line[char_index])][0][0]);
 | 
			
		||||
      else
 | 
			
		||||
        char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Un garde-fou en cas de probleme
 | 
			
		||||
        
 | 
			
		||||
      for (x=0;x<6;x++)
 | 
			
		||||
        for (repeat_menu_x_factor=0;repeat_menu_x_factor<Menu_factor_X;repeat_menu_x_factor++)
 | 
			
		||||
        {
 | 
			
		||||
          byte color = *(char_pixel+x+y*6);
 | 
			
		||||
          byte repetition = Pixel_width-1;
 | 
			
		||||
          // Surlignement pour liens
 | 
			
		||||
          if (line_type=='K' && char_index>=link_position
 | 
			
		||||
            && char_index<(link_position+link_size))
 | 
			
		||||
          {
 | 
			
		||||
            if (color == MC_Light)
 | 
			
		||||
              color=MC_White;
 | 
			
		||||
            else if (color == MC_Dark)
 | 
			
		||||
              color=MC_Light;
 | 
			
		||||
            else if (y<7)
 | 
			
		||||
              color=MC_Dark;
 | 
			
		||||
          }
 | 
			
		||||
          Horizontal_line_buffer[x_position++]=color;
 | 
			
		||||
          while (repetition--)
 | 
			
		||||
            Horizontal_line_buffer[x_position++]=color;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // On la splotche
 | 
			
		||||
    for (repeat_menu_y_factor=0;repeat_menu_y_factor<Menu_factor_Y;repeat_menu_y_factor++)
 | 
			
		||||
      Display_line_fast(real_x_pos,real_y_pos++,width*Menu_factor_X*6,Horizontal_line_buffer);
 | 
			
		||||
  }
 | 
			
		||||
  return width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// -- Menu d'aide -----------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
void Display_help(void)
 | 
			
		||||
{
 | 
			
		||||
  short  line_index;     // 0-15 (16 lignes de textes)
 | 
			
		||||
  short  start_line=Help_position;
 | 
			
		||||
  const short  x_pos=13;
 | 
			
		||||
  const short  y_pos=19;
 | 
			
		||||
  char   line_type;           // N: Normale, T: Titre, S: Sous-titre
 | 
			
		||||
                              // -: Ligne inférieur de sous-titre
 | 
			
		||||
  const char * line;
 | 
			
		||||
@ -254,21 +339,19 @@ void Display_help(void)
 | 
			
		||||
                              // raccourcis clavier
 | 
			
		||||
  short  link_position=0;     // Position du premier caractère "variable"
 | 
			
		||||
  short  link_size=0;       // Taille de la partie variable
 | 
			
		||||
 | 
			
		||||
  real_x_pos=Window_pos_X+(13*Menu_factor_X);
 | 
			
		||||
  real_y_pos=Window_pos_Y+(19*Menu_factor_Y);
 | 
			
		||||
 | 
			
		||||
  short width;
 | 
			
		||||
  
 | 
			
		||||
  for (line_index=0;line_index<16;line_index++)
 | 
			
		||||
  {
 | 
			
		||||
    // Shortcut au cas ou la section fait moins de 16 lignes
 | 
			
		||||
    if (line_index >= Help_section[Current_help_section].Length)
 | 
			
		||||
    {
 | 
			
		||||
      Block (real_x_pos,
 | 
			
		||||
           real_y_pos,
 | 
			
		||||
           44*6*Menu_factor_X,
 | 
			
		||||
      Window_rectangle (x_pos,
 | 
			
		||||
           y_pos + line_index*8,
 | 
			
		||||
           44*6,
 | 
			
		||||
           // 44 = Nb max de char (+1 pour éviter les plantages en mode X
 | 
			
		||||
           // causés par une largeur = 0)
 | 
			
		||||
           (Menu_factor_Y<<3) * (16 - line_index),
 | 
			
		||||
           (16 - line_index)*8,
 | 
			
		||||
           MC_Black);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
@ -307,83 +390,16 @@ void Display_help(void)
 | 
			
		||||
      line = buffer;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Calcul de la taille
 | 
			
		||||
    width=strlen(line);
 | 
			
		||||
    // Les lignes de titres prennent plus de place
 | 
			
		||||
    if (line_type == 'T' || line_type == '-')
 | 
			
		||||
      width = width*2;
 | 
			
		||||
 | 
			
		||||
    // Pour chaque ligne dans la fenêtre:
 | 
			
		||||
    for (y=0;y<8;y++)
 | 
			
		||||
    {
 | 
			
		||||
      x_position=0;
 | 
			
		||||
      // On crée une nouvelle ligne à splotcher
 | 
			
		||||
      for (char_index=0;char_index<width;char_index++)
 | 
			
		||||
      {
 | 
			
		||||
        // Recherche du caractère dans les fontes de l'aide.
 | 
			
		||||
        // Ligne titre : Si l'indice est impair on dessine le quart de caractère
 | 
			
		||||
        // qui va a gauche, sinon celui qui va a droite.
 | 
			
		||||
        if (line_type=='T')
 | 
			
		||||
        {
 | 
			
		||||
          if (line[char_index/2]>'_' || line[char_index/2]<' ')
 | 
			
		||||
            char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré
 | 
			
		||||
          else if (char_index & 1)
 | 
			
		||||
            char_pixel=&(Gfx->Help_font_t2[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
          else
 | 
			
		||||
            char_pixel=&(Gfx->Help_font_t1[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
        }
 | 
			
		||||
        else if (line_type=='-')
 | 
			
		||||
        {
 | 
			
		||||
          if (line[char_index/2]>'_' || line[char_index/2]<' ')
 | 
			
		||||
            char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Caractère pas géré
 | 
			
		||||
          else if (char_index & 1)
 | 
			
		||||
            char_pixel=&(Gfx->Help_font_t4[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
          else
 | 
			
		||||
            char_pixel=&(Gfx->Help_font_t3[(unsigned char)(line[char_index/2])-' '][0][0]);
 | 
			
		||||
        }
 | 
			
		||||
        else if (line_type=='S')
 | 
			
		||||
          char_pixel=&(Gfx->Bold_font[(unsigned char)(line[char_index])][0][0]);
 | 
			
		||||
        else if (line_type=='N' || line_type=='K')
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_norm[(unsigned char)(line[char_index])][0][0]);
 | 
			
		||||
        else
 | 
			
		||||
          char_pixel=&(Gfx->Help_font_norm['!'][0][0]); // Un garde-fou en cas de probleme
 | 
			
		||||
          
 | 
			
		||||
        for (x=0;x<6;x++)
 | 
			
		||||
          for (repeat_menu_x_factor=0;repeat_menu_x_factor<Menu_factor_X;repeat_menu_x_factor++)
 | 
			
		||||
          {
 | 
			
		||||
            byte color = *(char_pixel+x+y*6);
 | 
			
		||||
            byte repetition = Pixel_width-1;
 | 
			
		||||
            // Surlignement pour liens
 | 
			
		||||
            if (line_type=='K' && char_index>=link_position
 | 
			
		||||
              && char_index<(link_position+link_size))
 | 
			
		||||
            {
 | 
			
		||||
              if (color == MC_Light)
 | 
			
		||||
                color=MC_White;
 | 
			
		||||
              else if (color == MC_Dark)
 | 
			
		||||
                color=MC_Light;
 | 
			
		||||
              else if (y<7)
 | 
			
		||||
                color=MC_Dark;
 | 
			
		||||
            }
 | 
			
		||||
            Horizontal_line_buffer[x_position++]=color;
 | 
			
		||||
            while (repetition--)
 | 
			
		||||
              Horizontal_line_buffer[x_position++]=color;
 | 
			
		||||
          }
 | 
			
		||||
      }
 | 
			
		||||
      // On la splotche
 | 
			
		||||
      for (repeat_menu_y_factor=0;repeat_menu_y_factor<Menu_factor_Y;repeat_menu_y_factor++)
 | 
			
		||||
        Display_line_fast(real_x_pos,real_y_pos++,width*Menu_factor_X*6,Horizontal_line_buffer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    width=Print_help(x_pos, y_pos+(line_index<<3), line, line_type, link_position, link_size);
 | 
			
		||||
    // On efface la fin de la ligne:
 | 
			
		||||
    Block (real_x_pos+width*Menu_factor_X*6,
 | 
			
		||||
           real_y_pos-(8*Menu_factor_Y),
 | 
			
		||||
           ((44*6*Menu_factor_X)-width*Menu_factor_X*6)+1,
 | 
			
		||||
           // 44 = Nb max de char (+1 pour éviter les plantages en mode X
 | 
			
		||||
           // causés par une largeur = 0)
 | 
			
		||||
           Menu_factor_Y<<3,
 | 
			
		||||
    if (width<44)
 | 
			
		||||
      Window_rectangle (x_pos+width*6,
 | 
			
		||||
           y_pos+(line_index<<3),
 | 
			
		||||
           (44-width)*6,
 | 
			
		||||
           8,
 | 
			
		||||
           MC_Black);
 | 
			
		||||
  }
 | 
			
		||||
  Update_rect(Window_pos_X+13*Menu_factor_X,Window_pos_Y+19*Menu_factor_Y,44*6*Menu_factor_X,16*8*Menu_factor_Y);
 | 
			
		||||
  Update_window_area(x_pos,y_pos,44*6,16*8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -391,7 +407,7 @@ void Scroll_help(T_Scroller_button * scroller)
 | 
			
		||||
{
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
  scroller->Position=Help_position;
 | 
			
		||||
  Compute_slider_cursor_height(scroller);
 | 
			
		||||
  Compute_slider_cursor_length(scroller);
 | 
			
		||||
  Window_draw_slider(scroller);
 | 
			
		||||
  Display_help();
 | 
			
		||||
  Display_cursor();
 | 
			
		||||
@ -510,7 +526,7 @@ void Window_help(int section, const char *sub_section)
 | 
			
		||||
          nb_lines=Help_section[Current_help_section].Length;
 | 
			
		||||
          scroller->Position=0;
 | 
			
		||||
          scroller->Nb_elements=nb_lines;
 | 
			
		||||
          Compute_slider_cursor_height(scroller);
 | 
			
		||||
          Compute_slider_cursor_length(scroller);
 | 
			
		||||
          Window_draw_slider(scroller);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
@ -627,7 +643,51 @@ void Button_Stats(void)
 | 
			
		||||
  Print_in_window(10,35,"Build options:",STATS_TITLE_COLOR,MC_Black);
 | 
			
		||||
  Print_in_window(146,35,TrueType_is_supported()?"TTF fonts":"no TTF fonts",STATS_DATA_COLOR,MC_Black);
 | 
			
		||||
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  // Affichage de la mémoire restante
 | 
			
		||||
  Print_in_window(10,43,"Free memory: ",STATS_TITLE_COLOR,MC_Black);
 | 
			
		||||
 | 
			
		||||
  freeRam=0;
 | 
			
		||||
  char helpBuf[64];
 | 
			
		||||
  
 | 
			
		||||
  unsigned long STRAM,TTRAM;
 | 
			
		||||
  Atari_Memory_free(&STRAM,&TTRAM);
 | 
			
		||||
  freeRam=STRAM+TTRAM;
 | 
			
		||||
  buffer[0]='\0';
 | 
			
		||||
  
 | 
			
		||||
  if(STRAM > (100*1024*1024))
 | 
			
		||||
        sprintf(helpBuf,"ST:%u Mb ",(unsigned int)(STRAM/(1024*1024)));
 | 
			
		||||
  else if(freeRam > 100*1024)
 | 
			
		||||
        sprintf(helpBuf,"ST:%u Kb ",(unsigned int)(STRAM/1024));
 | 
			
		||||
  else
 | 
			
		||||
        sprintf(helpBuf,"ST:%u b ",(unsigned int)STRAM);
 | 
			
		||||
 | 
			
		||||
  strncat(buffer,helpBuf,sizeof(char)*37);
 | 
			
		||||
  
 | 
			
		||||
  if(TTRAM > (100ULL*1024*1024*1024))
 | 
			
		||||
        sprintf(helpBuf,"TT:%u Gb",(unsigned int)(TTRAM/(1024*1024*1024)));
 | 
			
		||||
  else if(TTRAM > (100*1024*1024))
 | 
			
		||||
        sprintf(helpBuf,"TT:%u Mb",(unsigned int)(TTRAM/(1024*1024)));
 | 
			
		||||
  else if(freeRam > 100*1024)
 | 
			
		||||
        sprintf(helpBuf,"TT:%u Kb",(unsigned int)(TTRAM/1024));
 | 
			
		||||
  else
 | 
			
		||||
        sprintf(helpBuf,"TT:%u b",(unsigned int)TTRAM);
 | 
			
		||||
 | 
			
		||||
  strncat(buffer,helpBuf,sizeof(char)*37);
 | 
			
		||||
 | 
			
		||||
  if(freeRam > (100ULL*1024*1024*1024))
 | 
			
		||||
        sprintf(helpBuf,"(%u Gb)",(unsigned int)(freeRam/(1024*1024*1024)));
 | 
			
		||||
  else if(freeRam > (100*1024*1024))
 | 
			
		||||
        sprintf(helpBuf,"(%u Mb)",(unsigned int)(freeRam/(1024*1024)));
 | 
			
		||||
  else if(freeRam > 100*1024)
 | 
			
		||||
        sprintf(helpBuf,"(%u Kb)",(unsigned int)(freeRam/1024));
 | 
			
		||||
  else
 | 
			
		||||
        sprintf(helpBuf,"(%u b)",(unsigned int)freeRam);
 | 
			
		||||
    strncat(buffer,helpBuf,sizeof(char)*37);
 | 
			
		||||
 
 | 
			
		||||
   Print_in_window(18,51,buffer,STATS_DATA_COLOR,MC_Black);
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  // Affichage de la mémoire restante
 | 
			
		||||
  Print_in_window(10,51,"Free memory: ",STATS_TITLE_COLOR,MC_Black);
 | 
			
		||||
 | 
			
		||||
@ -641,8 +701,12 @@ void Button_Stats(void)
 | 
			
		||||
        sprintf(buffer,"%u Kilobytes",(unsigned int)(freeRam/1024));
 | 
			
		||||
  else
 | 
			
		||||
        sprintf(buffer,"%u bytes",(unsigned int)freeRam);
 | 
			
		||||
  
 | 
			
		||||
  Print_in_window(114,51,buffer,STATS_DATA_COLOR,MC_Black);
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  // Used memory
 | 
			
		||||
  Print_in_window(10,59,"Used memory pages: ",STATS_TITLE_COLOR,MC_Black);
 | 
			
		||||
  if(Stats_pages_memory > (100LL*1024*1024*1024))
 | 
			
		||||
@ -670,6 +734,14 @@ void Button_Stats(void)
 | 
			
		||||
      statfs(Main_current_directory,&disk_info);
 | 
			
		||||
      mem_size=(qword) disk_info.f_bfree * (qword) disk_info.f_bsize;
 | 
			
		||||
    }
 | 
			
		||||
#elif defined (__MINT__)
 | 
			
		||||
   _DISKINFO drvInfo;
 | 
			
		||||
   mem_size=0;
 | 
			
		||||
   Dfree(&drvInfo,0);
 | 
			
		||||
   //number of free clusters*sectors per cluster*bytes per sector;
 | 
			
		||||
   // reports current drive
 | 
			
		||||
   mem_size=drvInfo.b_free*drvInfo.b_clsiz*drvInfo.b_secsiz;
 | 
			
		||||
   
 | 
			
		||||
#else
 | 
			
		||||
    // Free disk space is only for shows. Other platforms can display 0.
 | 
			
		||||
    #warning "Missing code for your platform !!! Check and correct please :)"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/help.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/help.h
									
									
									
									
									
								
							@ -46,5 +46,17 @@ void Button_Stats(void);
 | 
			
		||||
*/
 | 
			
		||||
void Window_help(int section, const char * sub_section);
 | 
			
		||||
 | 
			
		||||
/// Opens a window where you can change a shortcut key(s).
 | 
			
		||||
void Window_set_shortcut(int action_id);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Print a line with the 'help' (6x8) font.
 | 
			
		||||
short Print_help(short x_pos, short y_pos, const char *line, char line_type, short link_position, short link_size);
 | 
			
		||||
 | 
			
		||||
// 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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										155
									
								
								src/helpfile.h
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								src/helpfile.h
									
									
									
									
									
								
							@ -62,7 +62,11 @@ static const T_Help_table helptable_about[] =
 | 
			
		||||
  HELP_BOLD ("         \"Dragon's Layers\" Edition")
 | 
			
		||||
  HELP_BOLD ("  THE ULTIMATE MULTI-RESOLUTION GFX EDITOR")
 | 
			
		||||
  HELP_TEXT ("       http://grafx2.googlecode.com")
 | 
			
		||||
#if defined(__MINT__)
 | 
			
		||||
  HELP_TEXT ("                atari build                ")
 | 
			
		||||
#else
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
#endif
 | 
			
		||||
  HELP_TEXT ("Copyright 2007-2010, the Grafx2 project team")
 | 
			
		||||
  HELP_TEXT ("    Copyright 1996-2001, SUNSET DESIGN")
 | 
			
		||||
};
 | 
			
		||||
@ -156,6 +160,7 @@ static const T_Help_table helptable_help[] =
 | 
			
		||||
  HELP_LINK ("Filled polyform:     %s",   0x200+BUTTON_POLYFILL)
 | 
			
		||||
  HELP_LINK ("Gradient rectangle:  %s",   0x100+BUTTON_GRADRECT)
 | 
			
		||||
  HELP_LINK ("Gradation menu:      %s",   0x200+BUTTON_GRADRECT)
 | 
			
		||||
  HELP_LINK ("Toggle color cycling:%s",   SPECIAL_CYCLE_MODE)
 | 
			
		||||
  HELP_LINK ("Spheres:             %s",   0x100+BUTTON_SPHERES)
 | 
			
		||||
  HELP_LINK ("Gradient ellipses:   %s",   0x200+BUTTON_SPHERES)
 | 
			
		||||
  HELP_LINK ("Adjust picture:      %s",   0x100+BUTTON_ADJUST)
 | 
			
		||||
@ -204,6 +209,10 @@ static const T_Help_table helptable_help[] =
 | 
			
		||||
  HELP_LINK ("Distort brush:       %s",   SPECIAL_DISTORT)
 | 
			
		||||
  HELP_LINK ("Outline brush:       %s",   SPECIAL_OUTLINE)
 | 
			
		||||
  HELP_LINK ("Nibble brush:        %s",   SPECIAL_NIBBLE)
 | 
			
		||||
  HELP_LINK ("Double brush size:   %s",   SPECIAL_BRUSH_DOUBLE)
 | 
			
		||||
  HELP_LINK ("Halve brush size:    %s",   SPECIAL_BRUSH_HALVE)
 | 
			
		||||
  HELP_LINK ("Double brush width:  %s",   SPECIAL_BRUSH_DOUBLE_WIDTH)
 | 
			
		||||
  HELP_LINK ("Double brush height: %s",   SPECIAL_BRUSH_DOUBLE_HEIGHT)
 | 
			
		||||
  HELP_LINK ("Get brush colors:    %s",   SPECIAL_GET_BRUSH_COLORS)
 | 
			
		||||
  HELP_LINK ("Recolorize brush:    %s",   SPECIAL_RECOLORIZE_BRUSH)
 | 
			
		||||
  HELP_LINK ("Rotate brush:        %s",   SPECIAL_ROTATE_ANY_ANGLE)
 | 
			
		||||
@ -228,6 +237,18 @@ static const T_Help_table helptable_help[] =
 | 
			
		||||
  HELP_LINK ("  18:1               %s",   SPECIAL_ZOOM_18)
 | 
			
		||||
  HELP_LINK ("  20:1               %s",   SPECIAL_ZOOM_20)
 | 
			
		||||
  HELP_LINK ("Brush effects menu:  %s",   0x100+BUTTON_BRUSH_EFFECTS)
 | 
			
		||||
  HELP_LINK ("Brush factory:       %s",   0x200+BUTTON_BRUSH_EFFECTS)
 | 
			
		||||
  HELP_LINK ("Repeat last script:  %s",   SPECIAL_REPEAT_SCRIPT)
 | 
			
		||||
  HELP_LINK ("Run script #1:       %s",   SPECIAL_RUN_SCRIPT_1)
 | 
			
		||||
  HELP_LINK ("Run script #2:       %s",   SPECIAL_RUN_SCRIPT_2)
 | 
			
		||||
  HELP_LINK ("Run script #3:       %s",   SPECIAL_RUN_SCRIPT_3)
 | 
			
		||||
  HELP_LINK ("Run script #4:       %s",   SPECIAL_RUN_SCRIPT_4)
 | 
			
		||||
  HELP_LINK ("Run script #5:       %s",   SPECIAL_RUN_SCRIPT_5)
 | 
			
		||||
  HELP_LINK ("Run script #6:       %s",   SPECIAL_RUN_SCRIPT_6)
 | 
			
		||||
  HELP_LINK ("Run script #7:       %s",   SPECIAL_RUN_SCRIPT_7)
 | 
			
		||||
  HELP_LINK ("Run script #8:       %s",   SPECIAL_RUN_SCRIPT_8)
 | 
			
		||||
  HELP_LINK ("Run script #9:       %s",   SPECIAL_RUN_SCRIPT_9)
 | 
			
		||||
  HELP_LINK ("Run script #10:      %s",   SPECIAL_RUN_SCRIPT_10)
 | 
			
		||||
  HELP_LINK ("Text:                %s",   0x100+BUTTON_TEXT)
 | 
			
		||||
  HELP_LINK ("Resolution menu:     %s",   0x100+BUTTON_RESOL)
 | 
			
		||||
  HELP_LINK ("Safety resolution:   %s",   0x200+BUTTON_RESOL)
 | 
			
		||||
@ -424,6 +445,14 @@ static const T_Help_table helptable_credits[] =
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("  Luc Schrijvers (Begasus)")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_BOLD ("              WIZ & CAANOO PORT")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("  Alexander Filyanov (PheeL)")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_BOLD ("                 ATARI PORT")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("  Pawel Goralski (Saulot)")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("  ... made it work on your favourite toaster")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
@ -432,17 +461,18 @@ static const T_Help_table helptable_credits[] =
 | 
			
		||||
//HELP_TEXT ("0----5----0----5----0----5----0----5----0--X")
 | 
			
		||||
  HELP_TEXT ("  anibiqme      blumunkee     BDCIron       ")
 | 
			
		||||
  HELP_TEXT ("  Ced           DawnBringer   El Topo       ")
 | 
			
		||||
  HELP_TEXT ("  falenblood    fano          fogbot121     ")
 | 
			
		||||
  HELP_TEXT ("  Frost         Grimmy        grknsngn      ")
 | 
			
		||||
  HELP_TEXT ("  falenblood    fanickbux     fano          ")
 | 
			
		||||
  HELP_TEXT ("  fogbot121     Frost         Grimmy        ")
 | 
			
		||||
  HELP_TEXT ("  Gürkan Sengün Hatch         HoraK-FDF     ")
 | 
			
		||||
  HELP_TEXT ("  iLKke         Iw2evk        Jamon         ")
 | 
			
		||||
  HELP_TEXT ("  keito         kusma         Lord Graga    ")
 | 
			
		||||
  HELP_TEXT ("  Lorenzo Gatti MagerValp     maymunbeyin   ")
 | 
			
		||||
  HELP_TEXT ("  mind          MooZ          Pasi Kallinen ")
 | 
			
		||||
  HELP_TEXT ("  the Peach     petter        richienyhus   ")
 | 
			
		||||
  HELP_TEXT ("  tape.wyrm     TeeEmCee      tempest       ")
 | 
			
		||||
  HELP_TEXT ("  the Peach     petter        PheeL         ")
 | 
			
		||||
  HELP_TEXT ("  richienyhus   sm4tik        spratek       ")
 | 
			
		||||
  HELP_TEXT ("  tape.yrm      TeeEmCee      tempest       ")
 | 
			
		||||
  HELP_TEXT ("  Timo Kurrpa   titus^Rab     Tobé          ")
 | 
			
		||||
  HELP_TEXT ("  yakumo9275    00ai99")
 | 
			
		||||
  HELP_TEXT ("  yakumo2975    00ai99")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("  ... posted the annoying bug reports.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
@ -631,9 +661,25 @@ static const T_Help_table helptable_paintbrush[] =
 | 
			
		||||
  HELP_TEXT ("brush size by using the keys:")
 | 
			
		||||
  HELP_LINK ("Reduce   : %s",   SPECIAL_SMALLER_PAINTBRUSH)
 | 
			
		||||
  HELP_LINK ("Increase : %s",   SPECIAL_BIGGER_PAINTBRUSH)
 | 
			
		||||
  HELP_TEXT ("The last 3 paintbrushes in the menu belong")
 | 
			
		||||
  HELP_TEXT ("to the \"miscellaneous\" family and their size")
 | 
			
		||||
  HELP_TEXT ("cannot be modified.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("Other brushes are bitmaps, their size can't")
 | 
			
		||||
  HELP_TEXT ("be adjusted.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("Click with left mouse button to choose a ")
 | 
			
		||||
  HELP_TEXT ("paintbrush, and right mouse button to store")
 | 
			
		||||
  HELP_TEXT ("your current brush in the slot. If your")
 | 
			
		||||
  HELP_TEXT ("current brush is a grabbed brush, it will")
 | 
			
		||||
  HELP_TEXT ("store a monochrome version of it, maximum")
 | 
			
		||||
  HELP_TEXT ("15x15. (See below 'Brush container' to store")
 | 
			
		||||
  HELP_TEXT ("backups of a big brush)")
 | 
			
		||||
  HELP_TEXT ("The stored brushes are saved when you exit")
 | 
			
		||||
  HELP_TEXT ("the program.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("The 'Preset' button allows you to pick a")
 | 
			
		||||
  HELP_TEXT ("brush from any family. It's useful if you've")
 | 
			
		||||
  HELP_TEXT ("overwritten all normal slots with brushes")
 | 
			
		||||
  HELP_TEXT ("that you use more often.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_BOLD ("BRUSH CONTAINER")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
@ -1123,6 +1169,27 @@ static const T_Help_table helptable_grad_rect[] =
 | 
			
		||||
  HELP_TEXT ("- Index scroller: Defines the current")
 | 
			
		||||
  HELP_TEXT ("gradation among a set of 16 that will be")
 | 
			
		||||
  HELP_TEXT ("memorised.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_BOLD ("COLOR CYCLING")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("These options allow you to use animation of")
 | 
			
		||||
  HELP_TEXT ("colors: Grafx2 will shift palette entries")
 | 
			
		||||
  HELP_TEXT ("at real-time. Note that only the LBM file")
 | 
			
		||||
  HELP_TEXT ("format can record these settings, and very")
 | 
			
		||||
  HELP_TEXT ("few image viewers will play it back.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Cycling: Activates or desactivates the")
 | 
			
		||||
  HELP_TEXT ("cycling of colors when you're in the editor.")
 | 
			
		||||
  HELP_LINK ("Key: %s",   SPECIAL_CYCLE_MODE)
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Speed: Sets the speed for the cycling of")
 | 
			
		||||
  HELP_TEXT ("this range. Zero means this range doesn't")
 | 
			
		||||
  HELP_TEXT ("cycle. With 1, the range shifts 0.2856 times")
 | 
			
		||||
  HELP_TEXT ("per second; at speed 64 it's 18.28 times")
 | 
			
		||||
  HELP_TEXT ("per second. The program activates cycling")
 | 
			
		||||
  HELP_TEXT ("while you hold the speed slider, so you can")
 | 
			
		||||
  HELP_TEXT ("preview the speed.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
};
 | 
			
		||||
static const T_Help_table helptable_spheres[] =
 | 
			
		||||
{
 | 
			
		||||
@ -1253,15 +1320,17 @@ static const T_Help_table helptable_brush_fx[] =
 | 
			
		||||
  HELP_TEXT ("point at coordinates inferior to the ones of")
 | 
			
		||||
  HELP_TEXT ("the first point, the brush will be inverted.")
 | 
			
		||||
  HELP_TEXT ("Meanwhile, you can press the following keys")
 | 
			
		||||
  HELP_TEXT ("whose effects are:   'D'      : double the")
 | 
			
		||||
  HELP_TEXT ("brush in X and Y   'H'      : reduce the")
 | 
			
		||||
  HELP_TEXT ("brush by half in X and Y   'X'      : double")
 | 
			
		||||
  HELP_TEXT ("the brush in X   'Shift+X': reduce the brush")
 | 
			
		||||
  HELP_TEXT ("by half in X   'Y'      : double the brush")
 | 
			
		||||
  HELP_TEXT ("in Y   'Shift+Y': reduce the brush by half")
 | 
			
		||||
  HELP_TEXT ("in Y   'N'      : restore the normal size of")
 | 
			
		||||
  HELP_TEXT ("the brush (can be useful")
 | 
			
		||||
  HELP_TEXT ("because it's the only way for cancelling)")
 | 
			
		||||
  HELP_TEXT ("whose effects are:")
 | 
			
		||||
  HELP_TEXT ("  'D'      : Double the brush")
 | 
			
		||||
  HELP_TEXT ("  'H'      : Reduce the brush by half")
 | 
			
		||||
  HELP_TEXT ("  'X'      : Double the brush in X")
 | 
			
		||||
  HELP_TEXT ("  'Shift+X': Reduce the brush by half in X")
 | 
			
		||||
  HELP_TEXT ("  'Y'      : Double the brush in Y")
 | 
			
		||||
  HELP_TEXT ("  'Shift+Y': Reduce the brush by half in Y")
 | 
			
		||||
  HELP_TEXT ("  'N'      : Restore the normal size of the")
 | 
			
		||||
  HELP_TEXT ("             brush (can be useful because")
 | 
			
		||||
  HELP_TEXT ("             it's the only way for")
 | 
			
		||||
  HELP_TEXT ("             cancelling)")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_LINK ("- Distort: (Key:%s)",SPECIAL_DISTORT)
 | 
			
		||||
  HELP_TEXT ("Triggers an interactive operation")
 | 
			
		||||
@ -1312,6 +1381,8 @@ static const T_Help_table helptable_brush_fx[] =
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TITLE("BRUSH FACTORY")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_LINK ("(Key:%s)",0x200+BUTTON_BRUSH_EFFECTS)
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("This menu allows you to run scripts. Scripts")
 | 
			
		||||
  HELP_TEXT ("are written in the Lua language, and allow")
 | 
			
		||||
  HELP_TEXT ("you to modify the brush (hence the name")
 | 
			
		||||
@ -1331,6 +1402,8 @@ static const T_Help_table helptable_brush_fx[] =
 | 
			
		||||
  HELP_TEXT ("time you open the window. Scripts are loaded")
 | 
			
		||||
  HELP_TEXT ("from disk when you run them.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_LINK ("- Repeat last script: %s", SPECIAL_REPEAT_SCRIPT)
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
};
 | 
			
		||||
static const T_Help_table helptable_effects[] =
 | 
			
		||||
{
 | 
			
		||||
@ -2273,6 +2346,13 @@ static const T_Help_table helptable_settings_details[] =
 | 
			
		||||
  HELP_TEXT ("variants of your original palette, resulting")
 | 
			
		||||
  HELP_TEXT ("in a pretty grid !")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_BOLD ("  Sync views")
 | 
			
		||||
  HELP_TEXT ("When this mode is active, scrolling the view")
 | 
			
		||||
  HELP_TEXT ("(and the magnifier view) affects both the")
 | 
			
		||||
  HELP_TEXT ("main image and the spare page - as long as")
 | 
			
		||||
  HELP_TEXT ("they have the same dimensions.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TITLE("INPUT")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
@ -2323,6 +2403,14 @@ static const T_Help_table helptable_settings_details[] =
 | 
			
		||||
  HELP_TEXT ("GrafX2 to recognize them as a combo.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_BOLD ("  Swap buttons")
 | 
			
		||||
  HELP_TEXT ("This setting determines which key inverts")
 | 
			
		||||
  HELP_TEXT ("the mouse buttons when it's held : A left")
 | 
			
		||||
  HELP_TEXT ("click is then interpreted as a right-click.")
 | 
			
		||||
  HELP_TEXT ("It's especially useful for one-button")
 | 
			
		||||
  HELP_TEXT ("controllers, such as touchscreens and")
 | 
			
		||||
  HELP_TEXT ("tablets.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TITLE("EDITING")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
@ -2359,7 +2447,14 @@ static const T_Help_table helptable_settings_details[] =
 | 
			
		||||
  HELP_TEXT ("window. (Set it to 'no' if you have a slow")
 | 
			
		||||
  HELP_TEXT ("computer or if you edit huge pictures)")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("")  
 | 
			
		||||
  HELP_BOLD ("  Right click colorpick")  
 | 
			
		||||
  HELP_TEXT ("This enables a mode where the right mouse")
 | 
			
		||||
  HELP_TEXT ("buttons acts as a color picker until")
 | 
			
		||||
  HELP_TEXT ("it's released, and selects Foreground color.")  
 | 
			
		||||
  HELP_TEXT ("This mode prevents you from painting with")  
 | 
			
		||||
  HELP_TEXT ("Background color.")
 | 
			
		||||
  HELP_TEXT ("This option is ignored when the Shade,")
 | 
			
		||||
  HELP_TEXT ("Quick-shade, or Tiling mode is used.")    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const T_Help_table helptable_clear[] =
 | 
			
		||||
@ -2474,16 +2569,28 @@ static const T_Help_table helptable_palette[] =
 | 
			
		||||
  HELP_TEXT ("- Gauges: Allow you to modify the")
 | 
			
		||||
  HELP_TEXT ("current selection.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- RGB or HSL above the gauges: Switches")
 | 
			
		||||
  HELP_TEXT ("between RGB and HSL color spaces. In HSL")
 | 
			
		||||
  HELP_TEXT ("mode, the three sliders allow you to set the")
 | 
			
		||||
  HELP_TEXT ("Hue (tint), Saturation (from grayscale to")
 | 
			
		||||
  HELP_TEXT ("pure color) and Lightness (from black to")
 | 
			
		||||
  HELP_TEXT ("white).")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- numbers below the gauges: Allows you to")
 | 
			
		||||
  HELP_TEXT ("type in a new color in hexadecimal RRGGBB")
 | 
			
		||||
  HELP_TEXT ("or RGB: ie. to get blue, you can type either")
 | 
			
		||||
  HELP_TEXT ("0000ff or 00f.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- \"+\" and \"-\": Allow you to lighten or")
 | 
			
		||||
  HELP_TEXT ("darken the current selection.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Default: Restores the predifined GrafX2")
 | 
			
		||||
  HELP_TEXT ("- Preset: Restores the predefined GrafX2")
 | 
			
		||||
  HELP_TEXT ("palette.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Gray: Transforms the current selection")
 | 
			
		||||
  HELP_TEXT ("into its gray-scaled equivalent.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Negative: Transforms the current selection")
 | 
			
		||||
  HELP_TEXT ("- Neg: Transforms the current selection")
 | 
			
		||||
  HELP_TEXT ("into its reverse video equivalent.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Invert: Swaps the colors of the current")
 | 
			
		||||
@ -2520,18 +2627,12 @@ static const T_Help_table helptable_palette[] =
 | 
			
		||||
  HELP_TEXT ("whole palette it will sort this range.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Used: Indicates the number of colors used")
 | 
			
		||||
  HELP_TEXT ("in the picture.")
 | 
			
		||||
  HELP_TEXT ("in the picture and opens a histogram screen.")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Zap unused: Erases the unused colors with")
 | 
			
		||||
  HELP_TEXT ("copies of the current selection. (The")
 | 
			
		||||
  HELP_TEXT ("keyboard shortcut for this button is <Del>).")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- HSL: Switches between RGB and HSL color")
 | 
			
		||||
  HELP_TEXT ("spaces. In HSL mode, the three sliders")
 | 
			
		||||
  HELP_TEXT ("allow you to set the Hue (tint), Saturation")
 | 
			
		||||
  HELP_TEXT ("(from grayscale to pure color) and")
 | 
			
		||||
  HELP_TEXT ("Lightness (from black to white).")
 | 
			
		||||
  HELP_TEXT ("")
 | 
			
		||||
  HELP_TEXT ("- Reduce: Allows you to reduce the palette")
 | 
			
		||||
  HELP_TEXT ("to the number of colors you want (and")
 | 
			
		||||
  HELP_TEXT ("modifies the picture).")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										189
									
								
								src/hotkeys.c
									
									
									
									
									
								
							
							
						
						
									
										189
									
								
								src/hotkeys.c
									
									
									
									
									
								
							@ -884,7 +884,16 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_u, // U
 | 
			
		||||
  0},
 | 
			
		||||
  // Secondary shortcut is button I on the Caanoo, L on the Wiz, unset on others
 | 
			
		||||
  #if defined (__CAANOO__)
 | 
			
		||||
    (KEY_JOYBUTTON+JOY_BUTTON_I)
 | 
			
		||||
  #elif defined (__WIZ__)
 | 
			
		||||
    (KEY_JOYBUTTON+JOY_BUTTON_L)
 | 
			
		||||
  #else
 | 
			
		||||
    0
 | 
			
		||||
  #endif
 | 
			
		||||
  // --
 | 
			
		||||
  },
 | 
			
		||||
  {103,
 | 
			
		||||
  "Redo",
 | 
			
		||||
  "Redo the last undone action.",
 | 
			
		||||
@ -892,7 +901,16 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_u|MOD_SHIFT, // Shift + U
 | 
			
		||||
  0},
 | 
			
		||||
  // Secondary shortcut is button II on the Caanoo, R on the Wiz, unset on others
 | 
			
		||||
  #if defined (__CAANOO__)
 | 
			
		||||
    (KEY_JOYBUTTON+JOY_BUTTON_II)
 | 
			
		||||
  #elif defined (__WIZ__)
 | 
			
		||||
    (KEY_JOYBUTTON+JOY_BUTTON_R)
 | 
			
		||||
  #else
 | 
			
		||||
    0
 | 
			
		||||
  #endif
 | 
			
		||||
  // --
 | 
			
		||||
  },
 | 
			
		||||
  {133,
 | 
			
		||||
  "Kill",
 | 
			
		||||
  "Kills the current page. It actually",
 | 
			
		||||
@ -924,7 +942,17 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
 | 
			
		||||
  "confirmation is asked.",
 | 
			
		||||
  false,
 | 
			
		||||
  SDLK_q, // Q (A en AZERTY)
 | 
			
		||||
  0},
 | 
			
		||||
  // Secondary shortcut is button Home on the Caanoo, Menu on the Wiz, unset on others
 | 
			
		||||
  #if defined (__CAANOO__)
 | 
			
		||||
    (KEY_JOYBUTTON+JOY_BUTTON_HOME)
 | 
			
		||||
  #elif defined (__WIZ__)
 | 
			
		||||
    (KEY_JOYBUTTON+JOY_BUTTON_MENU)
 | 
			
		||||
  #else
 | 
			
		||||
    0
 | 
			
		||||
  #endif
 | 
			
		||||
  // --
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  {107,
 | 
			
		||||
  "Palette menu",
 | 
			
		||||
  "Opens a menu which allows you to",
 | 
			
		||||
@ -1478,13 +1506,149 @@ T_Key_config ConfigKey[NB_SHORTCUTS] = {
 | 
			
		||||
  SDLK_HOME|MOD_ALT, // Alt + Home
 | 
			
		||||
  0},
 | 
			
		||||
  {181,
 | 
			
		||||
  "Brush factory",
 | 
			
		||||
  "Opens a window where you can run a",
 | 
			
		||||
  "Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {182,
 | 
			
		||||
  "Repeat script",
 | 
			
		||||
  "Re-run the last script selected",
 | 
			
		||||
  "in the Brush factory window.",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {183,
 | 
			
		||||
  "Double brush size",
 | 
			
		||||
  "Resizes the current user brush",
 | 
			
		||||
  "by doubling width and height.",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_h|MOD_SHIFT, // Shift+H
 | 
			
		||||
  0},
 | 
			
		||||
  {184,
 | 
			
		||||
  "Double brush width",
 | 
			
		||||
  "Resizes the current user brush",
 | 
			
		||||
  "by doubling its width.",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_x|MOD_SHIFT, // Shift+X
 | 
			
		||||
  0},
 | 
			
		||||
  {185,
 | 
			
		||||
  "Double brush height",
 | 
			
		||||
  "Resizes the current user brush",
 | 
			
		||||
  "by doubling its height.",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_y|MOD_SHIFT, // Shift+Y
 | 
			
		||||
  0},
 | 
			
		||||
  {186,
 | 
			
		||||
  "Halve brush size",
 | 
			
		||||
  "Resizes the current user brush",
 | 
			
		||||
  "by halving its width and height",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_h, // H
 | 
			
		||||
  0},
 | 
			
		||||
  {187,
 | 
			
		||||
  "Run script #1",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {188,
 | 
			
		||||
  "Run script #2",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {189,
 | 
			
		||||
  "Run script #3",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {190,
 | 
			
		||||
  "Run script #4",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {191,
 | 
			
		||||
  "Run script #5",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {192,
 | 
			
		||||
  "Run script #6",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {193,
 | 
			
		||||
  "Run script #7",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {194,
 | 
			
		||||
  "Run script #8",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {195,
 | 
			
		||||
  "Run script #9",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {196,
 | 
			
		||||
  "Run script #10",
 | 
			
		||||
  "Runs a recorded Lua script.",
 | 
			
		||||
  "",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0, // No shortcut
 | 
			
		||||
  0},
 | 
			
		||||
  {197,
 | 
			
		||||
  "Toggle color cycling",
 | 
			
		||||
  "Activates or desactivates color",
 | 
			
		||||
  "cycling, if the current image has",
 | 
			
		||||
  "cycling colors. (See gradient menu)",
 | 
			
		||||
  true,
 | 
			
		||||
  SDLK_BACKQUOTE|MOD_CTRL, // Ctrl + `~
 | 
			
		||||
  0},
 | 
			
		||||
  {198,
 | 
			
		||||
  "Format checker",
 | 
			
		||||
  "Performs a format check on the",
 | 
			
		||||
  "current image.",
 | 
			
		||||
  "",
 | 
			
		||||
  true,
 | 
			
		||||
  0,
 | 
			
		||||
  0},
 | 
			
		||||
  0}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
word Ordering[NB_SHORTCUTS]=
 | 
			
		||||
@ -1670,6 +1834,23 @@ word Ordering[NB_SHORTCUTS]=
 | 
			
		||||
  0x100+BUTTON_LAYER_UP,
 | 
			
		||||
  0x100+BUTTON_LAYER_DOWN,
 | 
			
		||||
  0x100+BUTTON_LAYER_MENU,
 | 
			
		||||
  0x200+BUTTON_BRUSH_EFFECTS,
 | 
			
		||||
  SPECIAL_REPEAT_SCRIPT,
 | 
			
		||||
  SPECIAL_BRUSH_DOUBLE,
 | 
			
		||||
  SPECIAL_BRUSH_DOUBLE_WIDTH,
 | 
			
		||||
  SPECIAL_BRUSH_DOUBLE_HEIGHT,
 | 
			
		||||
  SPECIAL_BRUSH_HALVE,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_1,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_2,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_3,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_4,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_5,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_6,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_7,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_8,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_9,
 | 
			
		||||
  SPECIAL_RUN_SCRIPT_10,
 | 
			
		||||
  SPECIAL_CYCLE_MODE,
 | 
			
		||||
  SPECIAL_FORMAT_CHECKER,
 | 
			
		||||
  SPECIAL_FORMAT_CHECKER_MENU,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,8 @@
 | 
			
		||||
#endif
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
 | 
			
		||||
#define NB_SHORTCUTS 199   ///< Number of actions that can have a key combination associated to it.
 | 
			
		||||
 | 
			
		||||
/*** Types definitions and structs ***/
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										847
									
								
								src/init.c
									
									
									
									
									
								
							
							
						
						
									
										847
									
								
								src/init.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -24,7 +24,7 @@
 | 
			
		||||
/// Initialization (and some de-initialization) functions.
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  
 | 
			
		||||
T_Gui_skin *Load_graphics(const char * skin_file);
 | 
			
		||||
T_Gui_skin *Load_graphics(const char * skin_file, T_Gradient_array *gradients);
 | 
			
		||||
void Set_current_skin(const char *skinfile, T_Gui_skin *gfx);
 | 
			
		||||
void Init_buttons(void);
 | 
			
		||||
void Init_operations(void);
 | 
			
		||||
@ -34,6 +34,10 @@ int  Save_CFG(void);
 | 
			
		||||
void Set_all_video_modes(void);
 | 
			
		||||
void Set_config_defaults(void);
 | 
			
		||||
void Init_sighandler(void);
 | 
			
		||||
void Init_paintbrushes(void);
 | 
			
		||||
 | 
			
		||||
/// Set application icon(s)
 | 
			
		||||
void Define_icon(void);
 | 
			
		||||
 | 
			
		||||
extern char Gui_loading_error_message[512];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										658
									
								
								src/input.c
									
									
									
									
									
								
							
							
						
						
									
										658
									
								
								src/input.c
									
									
									
									
									
								
							@ -21,6 +21,12 @@
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
#include <SDL_syswm.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __WIN32__
 | 
			
		||||
  #include <windows.h>
 | 
			
		||||
  #include <ShellApi.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "keyboard.h"
 | 
			
		||||
@ -28,7 +34,9 @@
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "buttons.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
#include "loadsave.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __VBCC__
 | 
			
		||||
  #define __attribute__(x)
 | 
			
		||||
@ -36,6 +44,7 @@
 | 
			
		||||
 | 
			
		||||
void Handle_window_resize(SDL_ResizeEvent event);
 | 
			
		||||
void Handle_window_exit(SDL_QuitEvent event);
 | 
			
		||||
int Color_cycling(__attribute__((unused)) void* useless);
 | 
			
		||||
 | 
			
		||||
// public Globals (available as extern)
 | 
			
		||||
 | 
			
		||||
@ -44,8 +53,11 @@ int Snap_axis = 0;
 | 
			
		||||
int Snap_axis_origin_X;
 | 
			
		||||
int Snap_axis_origin_Y;
 | 
			
		||||
 | 
			
		||||
char * Drop_file_name = NULL;
 | 
			
		||||
 | 
			
		||||
// --
 | 
			
		||||
 | 
			
		||||
// Digital joystick state
 | 
			
		||||
byte Directional_up;
 | 
			
		||||
byte Directional_up_right;
 | 
			
		||||
byte Directional_right;
 | 
			
		||||
@ -56,14 +68,22 @@ byte Directional_left;
 | 
			
		||||
byte Directional_up_left;
 | 
			
		||||
byte Directional_click;
 | 
			
		||||
 | 
			
		||||
long Directional_delay;
 | 
			
		||||
// Emulated directional controller.
 | 
			
		||||
// This has a distinct state from Directional_, because some joysticks send
 | 
			
		||||
// "I'm not moving" SDL events when idle, thus stopping the emulated one.
 | 
			
		||||
byte Directional_emulated_up;
 | 
			
		||||
byte Directional_emulated_right;
 | 
			
		||||
byte Directional_emulated_down;
 | 
			
		||||
byte Directional_emulated_left;
 | 
			
		||||
 | 
			
		||||
long Directional_first_move;
 | 
			
		||||
long Directional_last_move;
 | 
			
		||||
long Directional_step;
 | 
			
		||||
int  Mouse_moved; ///< Boolean, Set to true if any cursor movement occurs.
 | 
			
		||||
 | 
			
		||||
word Input_new_mouse_X;
 | 
			
		||||
word Input_new_mouse_Y;
 | 
			
		||||
byte Input_new_mouse_K;
 | 
			
		||||
byte Button_inverter=0; // State of the key that swaps mouse buttons.
 | 
			
		||||
 | 
			
		||||
byte Mouse_mode = 0; ///< Mouse mode = 0:normal, 1:emulated with custom sensitivity.
 | 
			
		||||
short Mouse_virtual_x_position;
 | 
			
		||||
@ -71,21 +91,84 @@ short Mouse_virtual_y_position;
 | 
			
		||||
short Mouse_virtual_width;
 | 
			
		||||
short Mouse_virtual_height;
 | 
			
		||||
 | 
			
		||||
// TODO: move to config
 | 
			
		||||
#ifdef __GP2X__
 | 
			
		||||
short Joybutton_shift=GP2X_BUTTON_L; // Button number that serves as a "shift" modifier
 | 
			
		||||
short Joybutton_control=GP2X_BUTTON_R; // Button number that serves as a "ctrl" modifier
 | 
			
		||||
short Joybutton_alt=GP2X_BUTTON_CLICK; // Button number that serves as a "alt" modifier
 | 
			
		||||
short Joybutton_left_click=GP2X_BUTTON_B; // Button number that serves as left click
 | 
			
		||||
short Joybutton_right_click=GP2X_BUTTON_Y; // Button number that serves as right-click
 | 
			
		||||
#else
 | 
			
		||||
short Joybutton_shift=-1; // Button number that serves as a "shift" modifier
 | 
			
		||||
short Joybutton_control=-1; // Button number that serves as a "ctrl" modifier
 | 
			
		||||
short Joybutton_alt=-1; // Button number that serves as a "alt" modifier
 | 
			
		||||
short Joybutton_left_click=0; // Button number that serves as left click
 | 
			
		||||
short Joybutton_right_click=0; // Button number that serves as right-click
 | 
			
		||||
// Joystick/pad configurations for the various console ports.
 | 
			
		||||
// See the #else for the documentation of fields.
 | 
			
		||||
// TODO: Make these user-settable somehow.
 | 
			
		||||
#if defined(__GP2X__)
 | 
			
		||||
 | 
			
		||||
  #define JOYSTICK_THRESHOLD  (4096)
 | 
			
		||||
  short Joybutton_shift=      JOY_BUTTON_L;
 | 
			
		||||
  short Joybutton_control=    JOY_BUTTON_R;
 | 
			
		||||
  short Joybutton_alt=        JOY_BUTTON_CLICK;
 | 
			
		||||
  short Joybutton_left_click= JOY_BUTTON_B;
 | 
			
		||||
  short Joybutton_right_click=JOY_BUTTON_Y;
 | 
			
		||||
 | 
			
		||||
#elif defined(__WIZ__)
 | 
			
		||||
 | 
			
		||||
  #define JOYSTICK_THRESHOLD  (4096)
 | 
			
		||||
  short Joybutton_shift=      JOY_BUTTON_X;
 | 
			
		||||
  short Joybutton_control=    JOY_BUTTON_SELECT;
 | 
			
		||||
  short Joybutton_alt=        JOY_BUTTON_Y;
 | 
			
		||||
  short Joybutton_left_click= JOY_BUTTON_A;
 | 
			
		||||
  short Joybutton_right_click=JOY_BUTTON_B;
 | 
			
		||||
 | 
			
		||||
#elif defined(__CAANOO__)
 | 
			
		||||
 | 
			
		||||
  #define JOYSTICK_THRESHOLD  (4096)
 | 
			
		||||
  short Joybutton_shift=      JOY_BUTTON_L;
 | 
			
		||||
  short Joybutton_control=    JOY_BUTTON_R;
 | 
			
		||||
  short Joybutton_alt=        JOY_BUTTON_Y;
 | 
			
		||||
  short Joybutton_left_click= JOY_BUTTON_A;
 | 
			
		||||
  short Joybutton_right_click=JOY_BUTTON_B;
 | 
			
		||||
 | 
			
		||||
#else // Default : Any joystick on a computer platform
 | 
			
		||||
  ///
 | 
			
		||||
  /// This is the sensitivity threshold for the directional
 | 
			
		||||
  /// pad of a cheap digital joypad on the PC. It has been set through
 | 
			
		||||
  /// trial and error : If value is too large then the movement is
 | 
			
		||||
  /// randomly interrupted; if the value is too low the cursor will
 | 
			
		||||
  /// move by itself, controlled by parasits.
 | 
			
		||||
  /// YR 04/11/2010: I just observed a -8700 when joystick is idle.
 | 
			
		||||
  #define JOYSTICK_THRESHOLD  (10000)
 | 
			
		||||
  
 | 
			
		||||
  /// A button that is marked as "modifier" will 
 | 
			
		||||
  short Joybutton_shift=-1; ///< Button number that serves as a "shift" modifier; -1 for none
 | 
			
		||||
  short Joybutton_control=-1; ///< Button number that serves as a "ctrl" modifier; -1 for none
 | 
			
		||||
  short Joybutton_alt=-1; ///< Button number that serves as a "alt" modifier; -1 for none
 | 
			
		||||
  
 | 
			
		||||
  short Joybutton_left_click=0; ///< Button number that serves as left click; -1 for none
 | 
			
		||||
  short Joybutton_right_click=1; ///< Button number that serves as right-click; -1 for none
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int Has_shortcut(word function)
 | 
			
		||||
{
 | 
			
		||||
  if (function == 0xFFFF)
 | 
			
		||||
    return 0;
 | 
			
		||||
    
 | 
			
		||||
  if (function & 0x100)
 | 
			
		||||
  {
 | 
			
		||||
    if (Buttons_Pool[function&0xFF].Left_shortcut[0]!=KEY_NONE)
 | 
			
		||||
      return 1;
 | 
			
		||||
    if (Buttons_Pool[function&0xFF].Left_shortcut[1]!=KEY_NONE)
 | 
			
		||||
      return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  if (function & 0x200)
 | 
			
		||||
  {
 | 
			
		||||
    if (Buttons_Pool[function&0xFF].Right_shortcut[0]!=KEY_NONE)
 | 
			
		||||
      return 1;
 | 
			
		||||
    if (Buttons_Pool[function&0xFF].Right_shortcut[1]!=KEY_NONE)
 | 
			
		||||
      return 1;
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  if(Config_Key[function][0]!=KEY_NONE)
 | 
			
		||||
    return 1;
 | 
			
		||||
  if(Config_Key[function][1]!=KEY_NONE)
 | 
			
		||||
    return 1;
 | 
			
		||||
  return 0; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Is_shortcut(word key, word function)
 | 
			
		||||
{
 | 
			
		||||
  if (key == 0 || function == 0xFFFF)
 | 
			
		||||
@ -177,16 +260,18 @@ int Move_cursor_with_constraints()
 | 
			
		||||
      feedback=1;
 | 
			
		||||
      
 | 
			
		||||
      if (Input_new_mouse_K == 0)
 | 
			
		||||
      {
 | 
			
		||||
        Input_sticky_control = 0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Hide cursor, because even just a click change needs it
 | 
			
		||||
    if (!Mouse_moved)
 | 
			
		||||
    {
 | 
			
		||||
      Mouse_moved++;
 | 
			
		||||
      // Hide cursor (erasing icon and brush on screen
 | 
			
		||||
      // before changing the coordinates.
 | 
			
		||||
      Hide_cursor();
 | 
			
		||||
    }
 | 
			
		||||
    Mouse_moved++;
 | 
			
		||||
    if (Input_new_mouse_X != Mouse_X || Input_new_mouse_Y != Mouse_Y)
 | 
			
		||||
    {
 | 
			
		||||
      Mouse_X=Input_new_mouse_X;
 | 
			
		||||
@ -194,8 +279,8 @@ int Move_cursor_with_constraints()
 | 
			
		||||
    }
 | 
			
		||||
    Mouse_K=Input_new_mouse_K;
 | 
			
		||||
    
 | 
			
		||||
    if (Mouse_moved > Config.Mouse_merge_movement)
 | 
			
		||||
      if (! Operation[Current_operation][Mouse_K_unique]
 | 
			
		||||
    if (Mouse_moved > Config.Mouse_merge_movement
 | 
			
		||||
      && !Operation[Current_operation][Mouse_K_unique]
 | 
			
		||||
          [Operation_stack_size].Fast_mouse)
 | 
			
		||||
        feedback=1;
 | 
			
		||||
  }
 | 
			
		||||
@ -254,11 +339,19 @@ int Handle_mouse_click(SDL_MouseButtonEvent event)
 | 
			
		||||
    switch(event.button)
 | 
			
		||||
    {
 | 
			
		||||
        case SDL_BUTTON_LEFT:
 | 
			
		||||
            Input_new_mouse_K |= 1;
 | 
			
		||||
            if (Button_inverter)
 | 
			
		||||
              Input_new_mouse_K |= 2;
 | 
			
		||||
            else
 | 
			
		||||
              Input_new_mouse_K |= 1;
 | 
			
		||||
            break;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case SDL_BUTTON_RIGHT:
 | 
			
		||||
            Input_new_mouse_K |= 2;
 | 
			
		||||
            if (Button_inverter)
 | 
			
		||||
              Input_new_mouse_K |= 1;
 | 
			
		||||
            else
 | 
			
		||||
              Input_new_mouse_K |= 2;
 | 
			
		||||
            break;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case SDL_BUTTON_MIDDLE:
 | 
			
		||||
@ -284,11 +377,17 @@ int Handle_mouse_release(SDL_MouseButtonEvent event)
 | 
			
		||||
    switch(event.button)
 | 
			
		||||
    {
 | 
			
		||||
        case SDL_BUTTON_LEFT:
 | 
			
		||||
            Input_new_mouse_K &= ~1;
 | 
			
		||||
            if (Button_inverter)
 | 
			
		||||
              Input_new_mouse_K &= ~2;
 | 
			
		||||
            else
 | 
			
		||||
              Input_new_mouse_K &= ~1;
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case SDL_BUTTON_RIGHT:
 | 
			
		||||
            Input_new_mouse_K &= ~2;
 | 
			
		||||
            if (Button_inverter)
 | 
			
		||||
              Input_new_mouse_K &= ~1;
 | 
			
		||||
            else
 | 
			
		||||
              Input_new_mouse_K &= ~2;
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@ -300,27 +399,64 @@ int Handle_mouse_release(SDL_MouseButtonEvent event)
 | 
			
		||||
int Handle_key_press(SDL_KeyboardEvent event)
 | 
			
		||||
{
 | 
			
		||||
    //Appui sur une touche du clavier
 | 
			
		||||
    int modifier;
 | 
			
		||||
  
 | 
			
		||||
    Key = Keysym_to_keycode(event.keysym);
 | 
			
		||||
    Key_ANSI = Keysym_to_ANSI(event.keysym);
 | 
			
		||||
    switch(event.keysym.sym)
 | 
			
		||||
    {
 | 
			
		||||
      case SDLK_RSHIFT:
 | 
			
		||||
      case SDLK_LSHIFT:
 | 
			
		||||
        modifier=MOD_SHIFT;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case SDLK_RCTRL:
 | 
			
		||||
      case SDLK_LCTRL:
 | 
			
		||||
        modifier=MOD_CTRL;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case SDLK_RALT:
 | 
			
		||||
      case SDLK_LALT:
 | 
			
		||||
      case SDLK_MODE:
 | 
			
		||||
        modifier=MOD_ALT;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      case SDLK_RMETA:
 | 
			
		||||
      case SDLK_LMETA:
 | 
			
		||||
        modifier=MOD_META;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        modifier=0;
 | 
			
		||||
    }
 | 
			
		||||
    if (Config.Swap_buttons && modifier == Config.Swap_buttons && Button_inverter==0)
 | 
			
		||||
    {
 | 
			
		||||
      Button_inverter=1;
 | 
			
		||||
      if (Input_new_mouse_K)
 | 
			
		||||
      {
 | 
			
		||||
        Input_new_mouse_K ^= 3; // Flip bits 0 and 1
 | 
			
		||||
        return Move_cursor_with_constraints();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(Is_shortcut(Key,SPECIAL_MOUSE_UP))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_up=1;
 | 
			
		||||
      Directional_emulated_up=1;
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if(Is_shortcut(Key,SPECIAL_MOUSE_DOWN))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_down=1;
 | 
			
		||||
      Directional_emulated_down=1;
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if(Is_shortcut(Key,SPECIAL_MOUSE_LEFT))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_left=1;
 | 
			
		||||
      Directional_emulated_left=1;
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if(Is_shortcut(Key,SPECIAL_MOUSE_RIGHT))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_right=1;
 | 
			
		||||
      Directional_emulated_right=1;
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if(Is_shortcut(Key,SPECIAL_CLICK_LEFT) && Keyboard_click_allowed > 0)
 | 
			
		||||
@ -349,26 +485,35 @@ int Release_control(int key_code, int modifier)
 | 
			
		||||
      Snap_axis = 0;
 | 
			
		||||
      need_feedback = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (Config.Swap_buttons && modifier == Config.Swap_buttons && Button_inverter==1)
 | 
			
		||||
    {
 | 
			
		||||
      Button_inverter=0;
 | 
			
		||||
      if (Input_new_mouse_K)
 | 
			
		||||
      {      
 | 
			
		||||
        Input_new_mouse_K ^= 3; // Flip bits 0 and 1
 | 
			
		||||
        return Move_cursor_with_constraints();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if((key_code && key_code == (Config_Key[SPECIAL_MOUSE_UP][0]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_UP][0]&modifier) ||
 | 
			
		||||
      (key_code && key_code == (Config_Key[SPECIAL_MOUSE_UP][1]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_UP][1]&modifier))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_up=0;
 | 
			
		||||
      Directional_emulated_up=0;
 | 
			
		||||
    }
 | 
			
		||||
    if((key_code && key_code == (Config_Key[SPECIAL_MOUSE_DOWN][0]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_DOWN][0]&modifier) ||
 | 
			
		||||
      (key_code && key_code == (Config_Key[SPECIAL_MOUSE_DOWN][1]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_DOWN][1]&modifier))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_down=0;
 | 
			
		||||
      Directional_emulated_down=0;
 | 
			
		||||
    }
 | 
			
		||||
    if((key_code && key_code == (Config_Key[SPECIAL_MOUSE_LEFT][0]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_LEFT][0]&modifier) ||
 | 
			
		||||
      (key_code && key_code == (Config_Key[SPECIAL_MOUSE_LEFT][1]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_LEFT][1]&modifier))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_left=0;
 | 
			
		||||
      Directional_emulated_left=0;
 | 
			
		||||
    }
 | 
			
		||||
    if((key_code && key_code == (Config_Key[SPECIAL_MOUSE_RIGHT][0]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_RIGHT][0]&modifier) ||
 | 
			
		||||
      (key_code && key_code == (Config_Key[SPECIAL_MOUSE_RIGHT][1]&0x0FFF)) || (Config_Key[SPECIAL_MOUSE_RIGHT][1]&modifier))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_right=0;
 | 
			
		||||
      Directional_emulated_right=0;
 | 
			
		||||
    }
 | 
			
		||||
    if((key_code && key_code == (Config_Key[SPECIAL_CLICK_LEFT][0]&0x0FFF)) || (Config_Key[SPECIAL_CLICK_LEFT][0]&modifier) ||
 | 
			
		||||
      (key_code && key_code == (Config_Key[SPECIAL_CLICK_LEFT][1]&0x0FFF)) || (Config_Key[SPECIAL_CLICK_LEFT][1]&modifier))
 | 
			
		||||
@ -445,54 +590,88 @@ int Handle_joystick_press(SDL_JoyButtonEvent event)
 | 
			
		||||
    if (event.button == Joybutton_control)
 | 
			
		||||
    {
 | 
			
		||||
      SDL_SetModState(SDL_GetModState() | KMOD_CTRL);
 | 
			
		||||
      if (Config.Swap_buttons == MOD_CTRL && Button_inverter==0)
 | 
			
		||||
      {
 | 
			
		||||
        Button_inverter=1;
 | 
			
		||||
        if (Input_new_mouse_K)
 | 
			
		||||
        {
 | 
			
		||||
          Input_new_mouse_K ^= 3; // Flip bits 0 and 1
 | 
			
		||||
          return Move_cursor_with_constraints();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (event.button == Joybutton_alt)
 | 
			
		||||
    {
 | 
			
		||||
      SDL_SetModState(SDL_GetModState() | (KMOD_ALT|KMOD_META));
 | 
			
		||||
      if (Config.Swap_buttons == MOD_ALT && Button_inverter==0)
 | 
			
		||||
      {
 | 
			
		||||
        Button_inverter=1;
 | 
			
		||||
        if (Input_new_mouse_K)
 | 
			
		||||
        {
 | 
			
		||||
          Input_new_mouse_K ^= 3; // Flip bits 0 and 1
 | 
			
		||||
          return Move_cursor_with_constraints();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    if (event.button == Joybutton_left_click)
 | 
			
		||||
    {
 | 
			
		||||
      Input_new_mouse_K=1;
 | 
			
		||||
      Input_new_mouse_K = Button_inverter ? 2 : 1;
 | 
			
		||||
      return Move_cursor_with_constraints();
 | 
			
		||||
    }
 | 
			
		||||
    if (event.button == Joybutton_right_click)
 | 
			
		||||
    {
 | 
			
		||||
      Input_new_mouse_K=2;
 | 
			
		||||
      Input_new_mouse_K = Button_inverter ? 1 : 2;
 | 
			
		||||
      return Move_cursor_with_constraints();
 | 
			
		||||
    }
 | 
			
		||||
    #ifdef __GP2X__
 | 
			
		||||
    switch(event.button)
 | 
			
		||||
    {
 | 
			
		||||
      case GP2X_BUTTON_UP:
 | 
			
		||||
      #ifdef JOY_BUTTON_UP
 | 
			
		||||
      case JOY_BUTTON_UP:
 | 
			
		||||
        Directional_up=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_UPRIGHT:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_UPRIGHT
 | 
			
		||||
      case JOY_BUTTON_UPRIGHT:
 | 
			
		||||
        Directional_up_right=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_RIGHT:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_RIGHT
 | 
			
		||||
      case JOY_BUTTON_RIGHT:
 | 
			
		||||
        Directional_right=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_DOWNRIGHT:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWNRIGHT
 | 
			
		||||
      case JOY_BUTTON_DOWNRIGHT:
 | 
			
		||||
        Directional_down_right=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_DOWN:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWN
 | 
			
		||||
      case JOY_BUTTON_DOWN:
 | 
			
		||||
        Directional_down=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_DOWNLEFT:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWNLEFT
 | 
			
		||||
      case JOY_BUTTON_DOWNLEFT:
 | 
			
		||||
        Directional_down_left=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_LEFT:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_LEFT
 | 
			
		||||
      case JOY_BUTTON_LEFT:
 | 
			
		||||
        Directional_left=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_UPLEFT:
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_UPLEFT
 | 
			
		||||
      case JOY_BUTTON_UPLEFT:
 | 
			
		||||
        Directional_up_left=1;
 | 
			
		||||
        break;
 | 
			
		||||
      #endif
 | 
			
		||||
      
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
      
 | 
			
		||||
    Key = (KEY_JOYBUTTON+event.button)|Key_modifiers(SDL_GetModState());
 | 
			
		||||
    // TODO: systeme de répétition
 | 
			
		||||
    
 | 
			
		||||
@ -527,58 +706,75 @@ int Handle_joystick_release(SDL_JoyButtonEvent event)
 | 
			
		||||
      return Move_cursor_with_constraints();
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    #ifdef __GP2X__
 | 
			
		||||
    switch(event.button)
 | 
			
		||||
    {
 | 
			
		||||
      case GP2X_BUTTON_UP:
 | 
			
		||||
        Directional_up=0;
 | 
			
		||||
      #ifdef JOY_BUTTON_UP
 | 
			
		||||
      case JOY_BUTTON_UP:
 | 
			
		||||
        Directional_up=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_UPRIGHT:
 | 
			
		||||
        Directional_up_right=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_UPRIGHT
 | 
			
		||||
      case JOY_BUTTON_UPRIGHT:
 | 
			
		||||
        Directional_up_right=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_RIGHT:
 | 
			
		||||
        Directional_right=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_RIGHT
 | 
			
		||||
      case JOY_BUTTON_RIGHT:
 | 
			
		||||
        Directional_right=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_DOWNRIGHT:
 | 
			
		||||
        Directional_down_right=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWNRIGHT
 | 
			
		||||
      case JOY_BUTTON_DOWNRIGHT:
 | 
			
		||||
        Directional_down_right=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_DOWN:
 | 
			
		||||
        Directional_down=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWN
 | 
			
		||||
      case JOY_BUTTON_DOWN:
 | 
			
		||||
        Directional_down=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_DOWNLEFT:
 | 
			
		||||
        Directional_down_left=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWNLEFT
 | 
			
		||||
      case JOY_BUTTON_DOWNLEFT:
 | 
			
		||||
        Directional_down_left=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_LEFT:
 | 
			
		||||
        Directional_left=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_LEFT
 | 
			
		||||
      case JOY_BUTTON_LEFT:
 | 
			
		||||
        Directional_left=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case GP2X_BUTTON_UPLEFT:
 | 
			
		||||
        Directional_up_left=0;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_UPLEFT
 | 
			
		||||
      case JOY_BUTTON_UPLEFT:
 | 
			
		||||
        Directional_up_left=1;
 | 
			
		||||
        break;
 | 
			
		||||
      #endif
 | 
			
		||||
      
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
  return Move_cursor_with_constraints();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Handle_joystick_movement(SDL_JoyAxisEvent event)
 | 
			
		||||
{
 | 
			
		||||
    if (event.axis==0) // X
 | 
			
		||||
    if (event.axis==JOYSTICK_AXIS_X)
 | 
			
		||||
    {
 | 
			
		||||
      Directional_right=Directional_left=0;
 | 
			
		||||
      if (event.value<-1000)
 | 
			
		||||
      if (event.value<-JOYSTICK_THRESHOLD)
 | 
			
		||||
      {
 | 
			
		||||
        Directional_left=1;
 | 
			
		||||
      }
 | 
			
		||||
      else if (event.value>1000)
 | 
			
		||||
      else if (event.value>JOYSTICK_THRESHOLD)
 | 
			
		||||
        Directional_right=1;
 | 
			
		||||
    }
 | 
			
		||||
    else if (event.axis==1) // Y
 | 
			
		||||
    else if (event.axis==JOYSTICK_AXIS_Y)
 | 
			
		||||
    {
 | 
			
		||||
      Directional_up=Directional_down=0;
 | 
			
		||||
      if (event.value<-1000)
 | 
			
		||||
      if (event.value<-JOYSTICK_THRESHOLD)
 | 
			
		||||
      {
 | 
			
		||||
        Directional_up=1;
 | 
			
		||||
      }
 | 
			
		||||
      else if (event.value>1000)
 | 
			
		||||
      else if (event.value>JOYSTICK_THRESHOLD)
 | 
			
		||||
        Directional_down=1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -616,138 +812,222 @@ int Cursor_displace(short delta_x, short delta_y)
 | 
			
		||||
  return Move_cursor_with_constraints();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This function is the acceleration profile for directional (digital) cursor
 | 
			
		||||
// controllers.
 | 
			
		||||
int Directional_acceleration(int msec)
 | 
			
		||||
{
 | 
			
		||||
  const int initial_delay = 250;
 | 
			
		||||
  const int linear_factor = 200;
 | 
			
		||||
  const int accel_factor = 10000;
 | 
			
		||||
  // At beginning there is 1 pixel move, then nothing for N milliseconds
 | 
			
		||||
  if (msec<initial_delay)
 | 
			
		||||
    return 1;
 | 
			
		||||
    
 | 
			
		||||
  // After that, position over time is generally y = ax²+bx+c
 | 
			
		||||
  // a = 1/accel_factor
 | 
			
		||||
  // b = 1/linear_factor
 | 
			
		||||
  // c = 1
 | 
			
		||||
  return 1+(msec-initial_delay+linear_factor)/linear_factor+(msec-initial_delay)*(msec-initial_delay)/accel_factor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Main input handling function
 | 
			
		||||
 | 
			
		||||
int Get_input(void)
 | 
			
		||||
int Get_input(int sleep_time)
 | 
			
		||||
{
 | 
			
		||||
    SDL_Event event;
 | 
			
		||||
    int user_feedback_required = 0; // Flag qui indique si on doit arrêter de traiter les évènements ou si on peut enchainer
 | 
			
		||||
                
 | 
			
		||||
    // Commit any pending screen update.
 | 
			
		||||
    // This is done in this function because it's called after reading 
 | 
			
		||||
    // some user input.
 | 
			
		||||
    Flush_update();
 | 
			
		||||
    Color_cycling(NULL);
 | 
			
		||||
    Key_ANSI = 0;
 | 
			
		||||
    Key = 0;
 | 
			
		||||
    Mouse_moved=0;
 | 
			
		||||
    Input_new_mouse_X = Mouse_X;
 | 
			
		||||
    Input_new_mouse_Y = Mouse_Y;
 | 
			
		||||
    Input_new_mouse_K = Mouse_K;
 | 
			
		||||
 | 
			
		||||
    // Not using SDL_PollEvent() because every call polls the input
 | 
			
		||||
    // device. In some cases such as high-sensitivity mouse or cheap
 | 
			
		||||
    // digital joypad, every call will see something subtly different in
 | 
			
		||||
    // the state of the device, and thus it will enqueue a new event.
 | 
			
		||||
    // The result is that the queue will never empty !!!
 | 
			
		||||
 | 
			
		||||
    // Get new events from input devices.
 | 
			
		||||
    SDL_PumpEvents();
 | 
			
		||||
 | 
			
		||||
    // Process as much events as possible without redrawing the screen.
 | 
			
		||||
    // This mostly allows us to merge mouse events for people with an high
 | 
			
		||||
    // resolution mouse
 | 
			
		||||
    while( (!user_feedback_required) && SDL_PollEvent(&event)) // Try to cumulate for a full VBL except if there is a required feedback
 | 
			
		||||
    while(!user_feedback_required && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_ALLEVENTS)==1)
 | 
			
		||||
    {
 | 
			
		||||
        switch(event.type)
 | 
			
		||||
        {
 | 
			
		||||
            case SDL_VIDEORESIZE:
 | 
			
		||||
                Handle_window_resize(event.resize);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
      switch(event.type)
 | 
			
		||||
      {
 | 
			
		||||
          case SDL_VIDEORESIZE:
 | 
			
		||||
              Handle_window_resize(event.resize);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_QUIT:
 | 
			
		||||
                Handle_window_exit(event.quit);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_QUIT:
 | 
			
		||||
              Handle_window_exit(event.quit);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_MOUSEMOTION:
 | 
			
		||||
                user_feedback_required = Handle_mouse_move(event.motion);
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_MOUSEMOTION:
 | 
			
		||||
              user_feedback_required = Handle_mouse_move(event.motion);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_MOUSEBUTTONDOWN:
 | 
			
		||||
                Handle_mouse_click(event.button);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_MOUSEBUTTONDOWN:
 | 
			
		||||
              Handle_mouse_click(event.button);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_MOUSEBUTTONUP:
 | 
			
		||||
                Handle_mouse_release(event.button);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_MOUSEBUTTONUP:
 | 
			
		||||
              Handle_mouse_release(event.button);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_KEYDOWN:
 | 
			
		||||
                Handle_key_press(event.key);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_KEYDOWN:
 | 
			
		||||
              Handle_key_press(event.key);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_KEYUP:
 | 
			
		||||
                Handle_key_release(event.key);
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_KEYUP:
 | 
			
		||||
              Handle_key_release(event.key);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            // Start of Joystik handling
 | 
			
		||||
            #ifdef USE_JOYSTICK
 | 
			
		||||
          // Start of Joystik handling
 | 
			
		||||
          #ifdef USE_JOYSTICK
 | 
			
		||||
 | 
			
		||||
            case SDL_JOYBUTTONUP:
 | 
			
		||||
                Handle_joystick_release(event.jbutton);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_JOYBUTTONUP:
 | 
			
		||||
              Handle_joystick_release(event.jbutton);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_JOYBUTTONDOWN:
 | 
			
		||||
                Handle_joystick_press(event.jbutton);
 | 
			
		||||
                user_feedback_required = 1;
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_JOYBUTTONDOWN:
 | 
			
		||||
              Handle_joystick_press(event.jbutton);
 | 
			
		||||
              user_feedback_required = 1;
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            case SDL_JOYAXISMOTION:
 | 
			
		||||
                Handle_joystick_movement(event.jaxis);
 | 
			
		||||
                break;
 | 
			
		||||
          case SDL_JOYAXISMOTION:
 | 
			
		||||
              Handle_joystick_movement(event.jaxis);
 | 
			
		||||
              break;
 | 
			
		||||
 | 
			
		||||
            #endif
 | 
			
		||||
            // End of Joystick handling
 | 
			
		||||
            
 | 
			
		||||
            default:
 | 
			
		||||
            //    DEBUG("Unhandled SDL event number : ",event.type);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
          #endif
 | 
			
		||||
          // End of Joystick handling
 | 
			
		||||
          
 | 
			
		||||
          case SDL_SYSWMEVENT:
 | 
			
		||||
#ifdef __WIN32__
 | 
			
		||||
              if(event.syswm.msg->msg  == WM_DROPFILES)
 | 
			
		||||
              {
 | 
			
		||||
                int file_count;
 | 
			
		||||
                HDROP hdrop = (HDROP)(event.syswm.msg->wParam);
 | 
			
		||||
                if((file_count = DragQueryFile(hdrop,(UINT)-1,(LPTSTR) NULL ,(UINT) 0)) > 0)
 | 
			
		||||
                {
 | 
			
		||||
                  long len;
 | 
			
		||||
                  // Query filename length
 | 
			
		||||
                  len = DragQueryFile(hdrop,0 ,NULL ,0);
 | 
			
		||||
                  if (len)
 | 
			
		||||
                  {
 | 
			
		||||
                    Drop_file_name=calloc(len+1,1);
 | 
			
		||||
                    if (Drop_file_name)
 | 
			
		||||
                    {
 | 
			
		||||
                      if (DragQueryFile(hdrop,0 ,(LPTSTR) Drop_file_name ,(UINT) MAX_PATH))
 | 
			
		||||
                      {
 | 
			
		||||
                        // Success
 | 
			
		||||
                      }
 | 
			
		||||
                      else
 | 
			
		||||
                      {
 | 
			
		||||
                        free(Drop_file_name);
 | 
			
		||||
                        // Don't report name copy error
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                      // Don't report alloc error (for a file name? :/ )
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                  else
 | 
			
		||||
                  {
 | 
			
		||||
                    // Don't report weird Windows error
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                  // Drop of zero files. Thanks for the information, Bill.
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
#endif
 | 
			
		||||
              break;
 | 
			
		||||
          
 | 
			
		||||
          default:
 | 
			
		||||
              //DEBUG("Unhandled SDL event number : ",event.type);
 | 
			
		||||
              break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Directional controller
 | 
			
		||||
    if (!(Directional_up||Directional_up_right||Directional_right||
 | 
			
		||||
    Directional_down_right||Directional_down||Directional_down_left||
 | 
			
		||||
      Directional_left||Directional_up_left))
 | 
			
		||||
      Directional_down_right||Directional_down||Directional_down_left||
 | 
			
		||||
      Directional_left||Directional_up_left||Directional_emulated_up||
 | 
			
		||||
      Directional_emulated_right||Directional_emulated_down||
 | 
			
		||||
      Directional_emulated_left))
 | 
			
		||||
    {
 | 
			
		||||
      Directional_delay=-1;
 | 
			
		||||
      Directional_last_move=SDL_GetTicks();
 | 
			
		||||
       Directional_first_move=0;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      long time_now;
 | 
			
		||||
      int step=0;
 | 
			
		||||
      
 | 
			
		||||
      time_now=SDL_GetTicks();
 | 
			
		||||
      
 | 
			
		||||
      if (time_now>Directional_last_move+Directional_delay)
 | 
			
		||||
      if (Directional_first_move==0)
 | 
			
		||||
      {
 | 
			
		||||
        Directional_first_move=time_now;
 | 
			
		||||
        step=1;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        // Compute how much the cursor has moved since last call.
 | 
			
		||||
        // This tries to make smooth cursor movement
 | 
			
		||||
        // no matter the frequency of calls to Get_input()
 | 
			
		||||
        step =
 | 
			
		||||
          Directional_acceleration(time_now - Directional_first_move) -
 | 
			
		||||
          Directional_acceleration(Directional_last_move - Directional_first_move);
 | 
			
		||||
        
 | 
			
		||||
        // Clip speed at 3 pixel per visible frame.
 | 
			
		||||
        if (step > 3)
 | 
			
		||||
          step=3;
 | 
			
		||||
        
 | 
			
		||||
      }
 | 
			
		||||
      Directional_last_move = time_now;
 | 
			
		||||
      if (step)
 | 
			
		||||
      {
 | 
			
		||||
        // Speed parameters, acceleration etc. are here
 | 
			
		||||
        if (Directional_delay==-1)
 | 
			
		||||
        {
 | 
			
		||||
          Directional_delay=150;
 | 
			
		||||
          Directional_step=16;
 | 
			
		||||
        }
 | 
			
		||||
        else if (Directional_delay==150)
 | 
			
		||||
          Directional_delay=40;
 | 
			
		||||
        else if (Directional_delay!=0)
 | 
			
		||||
          Directional_delay=Directional_delay*8/10;
 | 
			
		||||
        else if (Directional_step<16*4)
 | 
			
		||||
          Directional_step++;
 | 
			
		||||
        Directional_last_move = time_now;
 | 
			
		||||
      
 | 
			
		||||
        // Directional controller UP
 | 
			
		||||
        if ((Directional_up||Directional_up_left||Directional_up_right) &&
 | 
			
		||||
           !(Directional_down_right||Directional_down||Directional_down_left))
 | 
			
		||||
        if ((Directional_up||Directional_emulated_up||Directional_up_left||Directional_up_right) &&
 | 
			
		||||
           !(Directional_down_right||Directional_down||Directional_emulated_down||Directional_down_left))
 | 
			
		||||
        {
 | 
			
		||||
          Cursor_displace(0, -Directional_step/16);
 | 
			
		||||
          Cursor_displace(0, -step);
 | 
			
		||||
        }
 | 
			
		||||
        // Directional controller RIGHT
 | 
			
		||||
        if ((Directional_up_right||Directional_right||Directional_down_right) &&
 | 
			
		||||
           !(Directional_down_left||Directional_left||Directional_up_left))
 | 
			
		||||
        if ((Directional_up_right||Directional_right||Directional_emulated_right||Directional_down_right) &&
 | 
			
		||||
           !(Directional_down_left||Directional_left||Directional_emulated_left||Directional_up_left))
 | 
			
		||||
        {
 | 
			
		||||
          Cursor_displace(Directional_step/16,0);
 | 
			
		||||
          Cursor_displace(step,0);
 | 
			
		||||
        }    
 | 
			
		||||
        // Directional controller DOWN
 | 
			
		||||
        if ((Directional_down_right||Directional_down||Directional_down_left) &&
 | 
			
		||||
           !(Directional_up_left||Directional_up||Directional_up_right))
 | 
			
		||||
        if ((Directional_down_right||Directional_down||Directional_emulated_down||Directional_down_left) &&
 | 
			
		||||
           !(Directional_up_left||Directional_up||Directional_emulated_up||Directional_up_right))
 | 
			
		||||
        {
 | 
			
		||||
          Cursor_displace(0, Directional_step/16);
 | 
			
		||||
          Cursor_displace(0, step);
 | 
			
		||||
        }
 | 
			
		||||
        // Directional controller LEFT
 | 
			
		||||
        if ((Directional_down_left||Directional_left||Directional_up_left) &&
 | 
			
		||||
           !(Directional_up_right||Directional_right||Directional_down_right))
 | 
			
		||||
        if ((Directional_down_left||Directional_left||Directional_emulated_left||Directional_up_left) &&
 | 
			
		||||
           !(Directional_up_right||Directional_right||Directional_emulated_right||Directional_down_right))
 | 
			
		||||
        {
 | 
			
		||||
          Cursor_displace(-Directional_step/16,0);
 | 
			
		||||
          Cursor_displace(-step,0);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -757,14 +1037,15 @@ int Get_input(void)
 | 
			
		||||
    {
 | 
			
		||||
      Compute_paintbrush_coordinates();
 | 
			
		||||
      Display_cursor();
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
    // Commit any pending screen update.
 | 
			
		||||
    // This is done in this function because it's called after reading 
 | 
			
		||||
    // some user input.
 | 
			
		||||
    Flush_update();
 | 
			
		||||
 | 
			
		||||
    if (user_feedback_required)
 | 
			
		||||
      return 1;
 | 
			
		||||
    
 | 
			
		||||
    return (Mouse_moved!=0) || user_feedback_required;
 | 
			
		||||
    // Nothing significant happened
 | 
			
		||||
    if (sleep_time)
 | 
			
		||||
      SDL_Delay(sleep_time);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Adjust_mouse_sensitivity(word fullscreen)
 | 
			
		||||
@ -796,3 +1077,74 @@ void Set_mouse_position(void)
 | 
			
		||||
      Mouse_virtual_y_position = 12*Mouse_Y*Pixel_height;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Color_cycling(__attribute__((unused)) void* useless)
 | 
			
		||||
{
 | 
			
		||||
  static byte offset[16];
 | 
			
		||||
  int i, color;
 | 
			
		||||
  static SDL_Color PaletteSDL[256];
 | 
			
		||||
  int changed; // boolean : true if the palette needs a change in this tick.
 | 
			
		||||
  
 | 
			
		||||
  long now;
 | 
			
		||||
  static long start=0;
 | 
			
		||||
  
 | 
			
		||||
  if (start==0)
 | 
			
		||||
  {
 | 
			
		||||
    // First run
 | 
			
		||||
    start = SDL_GetTicks();
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  if (!Allow_colorcycling || !Cycling_mode)
 | 
			
		||||
    return 1;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
  now = SDL_GetTicks();
 | 
			
		||||
  changed=0;
 | 
			
		||||
  
 | 
			
		||||
  // Check all cycles for a change at this tick
 | 
			
		||||
  for (i=0; i<16; i++)
 | 
			
		||||
  {
 | 
			
		||||
    int len;
 | 
			
		||||
    
 | 
			
		||||
    len=Main_backups->Pages->Gradients->Range[i].End-Main_backups->Pages->Gradients->Range[i].Start+1;
 | 
			
		||||
    if (len>1 && Main_backups->Pages->Gradients->Range[i].Speed)
 | 
			
		||||
    {
 | 
			
		||||
      int new_offset;
 | 
			
		||||
      
 | 
			
		||||
      new_offset=(now-start)/(int)(1000.0/(Main_backups->Pages->Gradients->Range[i].Speed*0.2856)) % len;
 | 
			
		||||
      if (!Main_backups->Pages->Gradients->Range[i].Inverse)
 | 
			
		||||
        new_offset=len - new_offset;
 | 
			
		||||
      
 | 
			
		||||
      if (new_offset!=offset[i])
 | 
			
		||||
        changed=1;
 | 
			
		||||
      offset[i]=new_offset;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (changed)
 | 
			
		||||
  {
 | 
			
		||||
    // Initialize the palette
 | 
			
		||||
    for(color=0;color<256;color++)
 | 
			
		||||
    {
 | 
			
		||||
      PaletteSDL[color].r=Main_palette[color].R;
 | 
			
		||||
      PaletteSDL[color].g=Main_palette[color].G;
 | 
			
		||||
      PaletteSDL[color].b=Main_palette[color].B;
 | 
			
		||||
    }
 | 
			
		||||
    for (i=0; i<16; i++)
 | 
			
		||||
    {
 | 
			
		||||
      int len;
 | 
			
		||||
    
 | 
			
		||||
      len=Main_backups->Pages->Gradients->Range[i].End-Main_backups->Pages->Gradients->Range[i].Start+1;
 | 
			
		||||
      if (len>1 && Main_backups->Pages->Gradients->Range[i].Speed)
 | 
			
		||||
      {
 | 
			
		||||
        for(color=Main_backups->Pages->Gradients->Range[i].Start;color<=Main_backups->Pages->Gradients->Range[i].End;color++)
 | 
			
		||||
        {
 | 
			
		||||
          PaletteSDL[color].r=Main_palette[Main_backups->Pages->Gradients->Range[i].Start+((color-Main_backups->Pages->Gradients->Range[i].Start+offset[i])%len)].R;
 | 
			
		||||
          PaletteSDL[color].g=Main_palette[Main_backups->Pages->Gradients->Range[i].Start+((color-Main_backups->Pages->Gradients->Range[i].Start+offset[i])%len)].G;
 | 
			
		||||
          PaletteSDL[color].b=Main_palette[Main_backups->Pages->Gradients->Range[i].Start+((color-Main_backups->Pages->Gradients->Range[i].Start+offset[i])%len)].B;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    SDL_SetPalette(Screen_SDL, SDL_PHYSPAL | SDL_LOGPAL, PaletteSDL,0,256);
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/input.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/input.h
									
									
									
									
									
								
							@ -33,11 +33,14 @@
 | 
			
		||||
/// The latest input variables are held in ::Key, ::Key_ANSI, ::Mouse_X, ::Mouse_Y, ::Mouse_K.
 | 
			
		||||
/// Note that ::Key and ::Key_ANSI are not persistent, they will be reset to 0
 | 
			
		||||
/// on subsequent calls to ::Get_input().
 | 
			
		||||
int  Get_input(void);
 | 
			
		||||
int  Get_input(int sleep_time);
 | 
			
		||||
 | 
			
		||||
/// Returns true if the keycode has been set as a keyboard shortcut for the function.
 | 
			
		||||
int Is_shortcut(word key, word function);
 | 
			
		||||
 | 
			
		||||
/// Returns true if the function has any shortcut key.
 | 
			
		||||
int Has_shortcut(word function);
 | 
			
		||||
 | 
			
		||||
/// Adjust mouse sensitivity (and actual mouse input mode)
 | 
			
		||||
void Adjust_mouse_sensitivity(word fullscreen);
 | 
			
		||||
 | 
			
		||||
@ -56,3 +59,8 @@ extern int Snap_axis;
 | 
			
		||||
extern int Snap_axis_origin_X;
 | 
			
		||||
/// For the :Snap_axis mode, sets the origin's point (in image coordinates)
 | 
			
		||||
extern int Snap_axis_origin_Y;
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// This malloced string is set when a drag-and-drop event
 | 
			
		||||
/// brings a file to Grafx2's window.
 | 
			
		||||
extern char * Drop_file_name;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								src/io.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								src/io.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
@ -32,14 +33,24 @@
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#if defined(__amigaos4__)
 | 
			
		||||
#if defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__)
 | 
			
		||||
    #include <proto/dos.h>
 | 
			
		||||
    #include <sys/types.h>
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #define isHidden(x) (0)
 | 
			
		||||
#elif defined(__WIN32__)
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #include <windows.h>
 | 
			
		||||
    //#include <commdlg.h>
 | 
			
		||||
    #define isHidden(x) (GetFileAttributesA((x)->d_name)&FILE_ATTRIBUTE_HIDDEN)
 | 
			
		||||
#elif defined(__MINT__)
 | 
			
		||||
    #include <mint/osbind.h>
 | 
			
		||||
    #include <mint/sysbind.h>
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #define isHidden(x) (0)
 | 
			
		||||
#else
 | 
			
		||||
    #include <dirent.h>
 | 
			
		||||
    #define isHidden(x) ((x)->d_name[0]=='.')
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
@ -276,6 +287,38 @@ void For_each_file(const char * directory_name, void Callback(const char *))
 | 
			
		||||
  closedir(current_directory);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Scans a directory, calls Callback for each file or directory in it,
 | 
			
		||||
void For_each_directory_entry(const char * directory_name, void Callback(const char *, byte is_file, byte is_directory, byte is_hidden))
 | 
			
		||||
{
 | 
			
		||||
  // Pour scan de répertoire
 | 
			
		||||
  DIR*  current_directory; //Répertoire courant
 | 
			
		||||
  struct dirent* entry; // Structure de lecture des éléments
 | 
			
		||||
  char full_filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
  int filename_position;
 | 
			
		||||
  strcpy(full_filename, directory_name);
 | 
			
		||||
  current_directory=opendir(directory_name);
 | 
			
		||||
  if(current_directory == NULL) return;        // Répertoire invalide ...
 | 
			
		||||
  filename_position = strlen(full_filename);
 | 
			
		||||
  if (filename_position==0 || strcmp(full_filename+filename_position-1,PATH_SEPARATOR))
 | 
			
		||||
  {
 | 
			
		||||
    strcat(full_filename, PATH_SEPARATOR);
 | 
			
		||||
    filename_position = strlen(full_filename);
 | 
			
		||||
  }
 | 
			
		||||
  while ((entry=readdir(current_directory)))
 | 
			
		||||
  {
 | 
			
		||||
    struct stat Infos_enreg;
 | 
			
		||||
    strcpy(&full_filename[filename_position], entry->d_name);
 | 
			
		||||
    stat(full_filename,&Infos_enreg);
 | 
			
		||||
    Callback(
 | 
			
		||||
      full_filename, 
 | 
			
		||||
      S_ISREG(Infos_enreg.st_mode), 
 | 
			
		||||
      S_ISDIR(Infos_enreg.st_mode), 
 | 
			
		||||
      isHidden(entry)?1:0);
 | 
			
		||||
  }
 | 
			
		||||
  closedir(current_directory);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Get_full_filename(char * output_name, char * file_name, char * directory_name)
 | 
			
		||||
{
 | 
			
		||||
  strcpy(output_name,directory_name);
 | 
			
		||||
@ -299,7 +342,7 @@ int Lock_file_handle = -1;
 | 
			
		||||
 | 
			
		||||
byte Create_lock_file(const char *file_directory)
 | 
			
		||||
{
 | 
			
		||||
  #ifdef __amigaos__
 | 
			
		||||
  #if defined (__amigaos__)||(__AROS__)
 | 
			
		||||
    #warning "Missing code for your platform, please check and correct!"
 | 
			
		||||
  #else
 | 
			
		||||
  char lock_filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
@ -336,7 +379,7 @@ byte Create_lock_file(const char *file_directory)
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  #endif
 | 
			
		||||
  #endif // __amigaos__
 | 
			
		||||
  #endif // __amigaos__ or __AROS__
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								src/io.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								src/io.h
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
 | 
			
		||||
@ -71,6 +72,8 @@ char * Find_last_slash(const char * str);
 | 
			
		||||
 | 
			
		||||
#if defined(__WIN32__)
 | 
			
		||||
  #define PATH_SEPARATOR "\\"
 | 
			
		||||
#elif defined(__MINT__)
 | 
			
		||||
  #define PATH_SEPARATOR "\\"
 | 
			
		||||
#else
 | 
			
		||||
  #define PATH_SEPARATOR "/"
 | 
			
		||||
#endif
 | 
			
		||||
@ -90,6 +93,10 @@ int  Directory_exists(char * directory);
 | 
			
		||||
/// Scans a directory, calls Callback for each file in it,
 | 
			
		||||
void For_each_file(const char * directory_name, void Callback(const char *));
 | 
			
		||||
 | 
			
		||||
/// Scans a directory, calls Callback for each file or directory in it,
 | 
			
		||||
void For_each_directory_entry(const char * directory_name, void Callback(const char *, byte is_file, byte is_directory, byte is_hidden));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Creates a fully qualified name from a directory and filename.
 | 
			
		||||
/// The point is simply to insert a PATH_SEPARATOR when needed.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										108
									
								
								src/keyboard.c
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/keyboard.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2010 Alexander Filyanov
 | 
			
		||||
    Copyright 2009 Franck Charlet
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
@ -465,38 +466,93 @@ const char * Key_name(word key)
 | 
			
		||||
  
 | 
			
		||||
  key=key & ~(MOD_CTRL|MOD_ALT|MOD_SHIFT);
 | 
			
		||||
  
 | 
			
		||||
  if (key>=KEY_JOYBUTTON && key<=KEY_JOYBUTTON+18)
 | 
			
		||||
  // 99 is only a sanity check
 | 
			
		||||
  if (key>=KEY_JOYBUTTON && key<=KEY_JOYBUTTON+99)
 | 
			
		||||
  {
 | 
			
		||||
#ifdef __GP2X__
 | 
			
		||||
    
 | 
			
		||||
    char *button_name;
 | 
			
		||||
    switch(key-KEY_JOYBUTTON)
 | 
			
		||||
    {    
 | 
			
		||||
      case GP2X_BUTTON_UP: button_name="[UP]"; break;
 | 
			
		||||
      case GP2X_BUTTON_DOWN: button_name="[DOWN]"; break;
 | 
			
		||||
      case GP2X_BUTTON_LEFT: button_name="[LEFT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_RIGHT: button_name="[RIGHT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_UPLEFT: button_name="[UP-LEFT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_UPRIGHT: button_name="[UP-RIGHT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_DOWNLEFT: button_name="[DOWN-LEFT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_DOWNRIGHT: button_name="[DOWN-RIGHT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_CLICK: button_name="[CLICK]"; break;
 | 
			
		||||
      case GP2X_BUTTON_A: button_name="[A]"; break;
 | 
			
		||||
      case GP2X_BUTTON_B: button_name="[B]"; break;
 | 
			
		||||
      case GP2X_BUTTON_X: button_name="[X]"; break;
 | 
			
		||||
      case GP2X_BUTTON_Y: button_name="[Y]"; break;
 | 
			
		||||
      case GP2X_BUTTON_L: button_name="[L]"; break;
 | 
			
		||||
      case GP2X_BUTTON_R: button_name="[R]"; break;
 | 
			
		||||
      case GP2X_BUTTON_START: button_name="[START]"; break;
 | 
			
		||||
      case GP2X_BUTTON_SELECT: button_name="[SELECT]"; break;
 | 
			
		||||
      case GP2X_BUTTON_VOLUP: button_name="[VOL UP]"; break;
 | 
			
		||||
      case GP2X_BUTTON_VOLDOWN: button_name="[VOL DOWN]"; break;
 | 
			
		||||
      default: sprintf(buffer+strlen(buffer), "[B%d]", key);return buffer;
 | 
			
		||||
    {
 | 
			
		||||
      #ifdef JOY_BUTTON_UP
 | 
			
		||||
      case JOY_BUTTON_UP: button_name="[UP]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWN
 | 
			
		||||
      case JOY_BUTTON_DOWN: button_name="[DOWN]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_LEFT
 | 
			
		||||
      case JOY_BUTTON_LEFT: button_name="[LEFT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_RIGHT
 | 
			
		||||
      case JOY_BUTTON_RIGHT: button_name="[RIGHT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_UPLEFT
 | 
			
		||||
      case JOY_BUTTON_UPLEFT: button_name="[UP-LEFT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_UPRIGHT
 | 
			
		||||
      case JOY_BUTTON_UPRIGHT: button_name="[UP-RIGHT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWNLEFT
 | 
			
		||||
      case JOY_BUTTON_DOWNLEFT: button_name="[DOWN-LEFT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_DOWNRIGHT
 | 
			
		||||
      case JOY_BUTTON_DOWNRIGHT: button_name="[DOWN-RIGHT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_CLICK
 | 
			
		||||
      case JOY_BUTTON_CLICK: button_name="[CLICK]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_A
 | 
			
		||||
      case JOY_BUTTON_A: button_name="[A]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_B
 | 
			
		||||
      case JOY_BUTTON_B: button_name="[B]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_X
 | 
			
		||||
      case JOY_BUTTON_X: button_name="[X]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_Y
 | 
			
		||||
      case JOY_BUTTON_Y: button_name="[Y]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_L
 | 
			
		||||
      case JOY_BUTTON_L: button_name="[L]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_R
 | 
			
		||||
      case JOY_BUTTON_R: button_name="[R]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_START
 | 
			
		||||
      case JOY_BUTTON_START: button_name="[START]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_SELECT
 | 
			
		||||
      case JOY_BUTTON_SELECT: button_name="[SELECT]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_VOLUP
 | 
			
		||||
      case JOY_BUTTON_VOLUP: button_name="[VOL UP]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_VOLDOWN
 | 
			
		||||
      case JOY_BUTTON_VOLDOWN: button_name="[VOL DOWN]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_MENU
 | 
			
		||||
      case JOY_BUTTON_MENU: button_name="[MENU]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_HOME
 | 
			
		||||
      case JOY_BUTTON_HOME: button_name="[HOME]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_HOLD
 | 
			
		||||
      case JOY_BUTTON_HOLD: button_name="[HOLD]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_I
 | 
			
		||||
      case JOY_BUTTON_I: button_name="[BUTTON I]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_II
 | 
			
		||||
      case JOY_BUTTON_II: button_name="[BUTTON II]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      #ifdef JOY_BUTTON_JOY
 | 
			
		||||
      case JOY_BUTTON_JOY: button_name="[THUMB JOY]"; break;
 | 
			
		||||
      #endif
 | 
			
		||||
      
 | 
			
		||||
      default: sprintf(buffer+strlen(buffer), "[B%d]", key-KEY_JOYBUTTON);return buffer;
 | 
			
		||||
    }
 | 
			
		||||
    strcat(buffer,button_name);
 | 
			
		||||
#else    
 | 
			
		||||
    sprintf(buffer+strlen(buffer), "[B%d]", key-KEY_JOYBUTTON);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return buffer;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										373
									
								
								src/loadsave.c
									
									
									
									
									
								
							
							
						
						
									
										373
									
								
								src/loadsave.c
									
									
									
									
									
								
							@ -2,6 +2,8 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2010 Alexander Filyanov
 | 
			
		||||
    Copyright 2009 Petter Lindquist
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -47,6 +49,8 @@
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "engine.h"
 | 
			
		||||
#include "brush.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
// -- PKM -------------------------------------------------------------------
 | 
			
		||||
void Test_PKM(T_IO_Context *);
 | 
			
		||||
@ -121,6 +125,10 @@ void Save_C64(T_IO_Context *);
 | 
			
		||||
// -- SCR (Amstrad CPC)
 | 
			
		||||
void Save_SCR(T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
// -- XPM (X PixMap)
 | 
			
		||||
// Loading is done through SDL_Image 
 | 
			
		||||
void Save_XPM(T_IO_Context*);
 | 
			
		||||
 | 
			
		||||
// -- PNG -------------------------------------------------------------------
 | 
			
		||||
#ifndef __no_pnglib__
 | 
			
		||||
void Test_PNG(T_IO_Context *);
 | 
			
		||||
@ -133,7 +141,7 @@ void Save_PNG(T_IO_Context *);
 | 
			
		||||
void Load_SDL_Image(T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
// ENUM     Name  TestFunc LoadFunc SaveFunc PalOnly Comment Layers Ext Exts  
 | 
			
		||||
T_Format File_formats[NB_KNOWN_FORMATS] = {
 | 
			
		||||
T_Format File_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;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"},
 | 
			
		||||
@ -143,7 +151,7 @@ T_Format File_formats[NB_KNOWN_FORMATS] = {
 | 
			
		||||
  {FORMAT_BMP, " bmp", Test_BMP, Load_BMP, Save_BMP, 0, 0, 0, "bmp", "bmp"},
 | 
			
		||||
  {FORMAT_PCX, " pcx", Test_PCX, Load_PCX, Save_PCX, 0, 0, 0, "pcx", "pcx"},
 | 
			
		||||
  {FORMAT_PKM, " pkm", Test_PKM, Load_PKM, Save_PKM, 0, 1, 0, "pkm", "pkm"},
 | 
			
		||||
  {FORMAT_LBM, " lbm", Test_LBM, Load_LBM, Save_LBM, 0, 0, 0, "lbm", "lbm;iff"},
 | 
			
		||||
  {FORMAT_LBM, " lbm", Test_LBM, Load_LBM, Save_LBM, 0, 0, 0, "lbm", "lbm;iff;ilbm"},
 | 
			
		||||
  {FORMAT_IMG, " img", Test_IMG, Load_IMG, Save_IMG, 0, 0, 0, "img", "img"},
 | 
			
		||||
  {FORMAT_SCx, " sc?", Test_SCx, Load_SCx, Save_SCx, 0, 0, 0, "sc?", "sci;scq;scf;scn;sco"},
 | 
			
		||||
  {FORMAT_PI1, " pi1", Test_PI1, Load_PI1, Save_PI1, 0, 0, 0, "pi1", "pi1"},
 | 
			
		||||
@ -154,9 +162,16 @@ T_Format File_formats[NB_KNOWN_FORMATS] = {
 | 
			
		||||
  {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;koala;fli;bml;cdu;prg"},
 | 
			
		||||
  {FORMAT_SCR, " cpc", NULL,     NULL,     Save_SCR, 0, 0, 0, "cpc", "cpc;scr"},
 | 
			
		||||
  {FORMAT_XPM, " xpm", NULL,     NULL,     Save_XPM, 0, 0, 0, "xpm", "xpm"},
 | 
			
		||||
  {FORMAT_MISC,"misc.",NULL,     NULL,     NULL,     0, 0, 0, "",    "tga;pnm;xpm;xcf;jpg;jpeg;tif;tiff;ico"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Total number of known file formats
 | 
			
		||||
unsigned int Nb_known_formats(void)
 | 
			
		||||
{
 | 
			
		||||
  return sizeof(File_formats)/sizeof(File_formats[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Set the color of a pixel (on load)
 | 
			
		||||
void Set_pixel(T_IO_Context *context, short x_pos, short y_pos, byte color)
 | 
			
		||||
{
 | 
			
		||||
@ -180,38 +195,32 @@ void Set_pixel(T_IO_Context *context, short x_pos, short y_pos, byte color)
 | 
			
		||||
    // Chargement des pixels dans la preview
 | 
			
		||||
    case CONTEXT_PREVIEW:
 | 
			
		||||
      // Skip pixels of transparent index if :
 | 
			
		||||
      // - It's the first layer, and image has transparent background.
 | 
			
		||||
      // - or it's a layer above the first one
 | 
			
		||||
      if (color == context->Transparent_color && (context->Current_layer > 0 || context->Background_transparent))
 | 
			
		||||
      // it's a layer above the first one
 | 
			
		||||
      if (color == context->Transparent_color && context->Current_layer > 0)
 | 
			
		||||
        break;
 | 
			
		||||
      
 | 
			
		||||
      if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0))
 | 
			
		||||
      {
 | 
			
		||||
        // Tag the color as 'used'
 | 
			
		||||
        context->Preview_usage[color]=1;
 | 
			
		||||
        
 | 
			
		||||
        // Store pixel
 | 
			
		||||
        if (context->Ratio == PIXEL_WIDE && 
 | 
			
		||||
          Pixel_ratio != PIXEL_WIDE &&
 | 
			
		||||
          Pixel_ratio != PIXEL_WIDE2)
 | 
			
		||||
        {
 | 
			
		||||
           Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X*2),
 | 
			
		||||
                 context->Preview_pos_Y+(y_pos/context->Preview_factor_Y),
 | 
			
		||||
                 color);
 | 
			
		||||
           Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X*2)+1,
 | 
			
		||||
                 context->Preview_pos_Y+(y_pos/context->Preview_factor_Y),
 | 
			
		||||
                 color);
 | 
			
		||||
          context->Preview_bitmap[x_pos/context->Preview_factor_X*2 + (y_pos/context->Preview_factor_Y)*PREVIEW_WIDTH*Menu_factor_X]=color;
 | 
			
		||||
          context->Preview_bitmap[x_pos/context->Preview_factor_X*2+1 + (y_pos/context->Preview_factor_Y)*PREVIEW_WIDTH*Menu_factor_X]=color;
 | 
			
		||||
        }
 | 
			
		||||
        else if (context->Ratio == PIXEL_TALL && 
 | 
			
		||||
          Pixel_ratio != PIXEL_TALL &&
 | 
			
		||||
          Pixel_ratio != PIXEL_TALL2)
 | 
			
		||||
        {
 | 
			
		||||
           Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X),
 | 
			
		||||
                 context->Preview_pos_Y+(y_pos/context->Preview_factor_Y*2),
 | 
			
		||||
                 color);
 | 
			
		||||
           Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X),
 | 
			
		||||
                 context->Preview_pos_Y+(y_pos/context->Preview_factor_Y*2)+1,
 | 
			
		||||
                 color);
 | 
			
		||||
          context->Preview_bitmap[x_pos/context->Preview_factor_X + (y_pos/context->Preview_factor_Y*2)*PREVIEW_WIDTH*Menu_factor_X]=color;
 | 
			
		||||
          context->Preview_bitmap[x_pos/context->Preview_factor_X + (y_pos/context->Preview_factor_Y*2+1)*PREVIEW_WIDTH*Menu_factor_X]=color;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
          Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X),
 | 
			
		||||
                context->Preview_pos_Y+(y_pos/context->Preview_factor_Y),
 | 
			
		||||
                color);
 | 
			
		||||
          context->Preview_bitmap[x_pos/context->Preview_factor_X + (y_pos/context->Preview_factor_Y)*PREVIEW_WIDTH*Menu_factor_X]=color;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      break;
 | 
			
		||||
@ -234,8 +243,6 @@ void Palette_loaded(T_IO_Context *context)
 | 
			
		||||
  {
 | 
			
		||||
    case CONTEXT_MAIN_IMAGE:
 | 
			
		||||
    case CONTEXT_PREVIEW:
 | 
			
		||||
      Set_palette(context->Palette);
 | 
			
		||||
      break;
 | 
			
		||||
    case CONTEXT_BRUSH:
 | 
			
		||||
    case CONTEXT_SURFACE:
 | 
			
		||||
      break;
 | 
			
		||||
@ -243,67 +250,7 @@ void Palette_loaded(T_IO_Context *context)
 | 
			
		||||
 | 
			
		||||
  switch (context->Type)
 | 
			
		||||
  {
 | 
			
		||||
    case CONTEXT_PREVIEW:
 | 
			
		||||
    
 | 
			
		||||
      Compute_optimal_menu_colors(context->Palette);
 | 
			
		||||
      /*
 | 
			
		||||
      if(
 | 
			
		||||
        (
 | 
			
		||||
          context->Palette[MC_Black].R==context->Palette[MC_Dark].R &&
 | 
			
		||||
          context->Palette[MC_Black].G==context->Palette[MC_Dark].G &&
 | 
			
		||||
          context->Palette[MC_Black].B==context->Palette[MC_Dark].B
 | 
			
		||||
        ) ||
 | 
			
		||||
        (
 | 
			
		||||
          context->Palette[MC_Light].R==context->Palette[MC_Dark].R &&
 | 
			
		||||
          context->Palette[MC_Light].G==context->Palette[MC_Dark].G &&
 | 
			
		||||
          context->Palette[MC_Light].B==context->Palette[MC_Dark].B
 | 
			
		||||
        ) ||
 | 
			
		||||
        (
 | 
			
		||||
          context->Palette[MC_White].R==context->Palette[MC_Light].R &&
 | 
			
		||||
          context->Palette[MC_White].G==context->Palette[MC_Light].G &&
 | 
			
		||||
          context->Palette[MC_White].B==context->Palette[MC_Light].B
 | 
			
		||||
        )
 | 
			
		||||
        )
 | 
			
		||||
        
 | 
			
		||||
      {
 | 
			
		||||
          // Si on charge une image monochrome, le fileselect ne sera plus visible. Dans ce cas on force quelques couleurs à des valeurs sures
 | 
			
		||||
    
 | 
			
		||||
          int black =
 | 
			
		||||
              Main_palette[MC_Black].R +
 | 
			
		||||
              Main_palette[MC_Black].G +
 | 
			
		||||
              Main_palette[MC_Black].B;
 | 
			
		||||
          int white =
 | 
			
		||||
              Main_palette[MC_White].R +
 | 
			
		||||
              Main_palette[MC_White].G +
 | 
			
		||||
              Main_palette[MC_White].B;
 | 
			
		||||
    
 | 
			
		||||
          //Set_color(MC_Light,(2*white+black)/9,(2*white+black)/9,(2*white+black)/9);
 | 
			
		||||
          //Set_color(MC_Dark,(2*black+white)/9,(2*black+white)/9,(2*black+white)/9);
 | 
			
		||||
          Main_palette[MC_Dark].R=(2*black+white)/9;
 | 
			
		||||
          Main_palette[MC_Dark].G=(2*black+white)/9;
 | 
			
		||||
          Main_palette[MC_Dark].B=(2*black+white)/9;
 | 
			
		||||
          Main_palette[MC_Light].R=(2*white+black)/9;
 | 
			
		||||
          Main_palette[MC_Light].G=(2*white+black)/9;
 | 
			
		||||
          Main_palette[MC_Light].B=(2*white+black)/9;
 | 
			
		||||
    
 | 
			
		||||
          Set_palette(Main_palette);
 | 
			
		||||
      }
 | 
			
		||||
      */
 | 
			
		||||
      Remap_screen_after_menu_colors_change();
 | 
			
		||||
      
 | 
			
		||||
      // Preview palette
 | 
			
		||||
      if (Get_fileformat(context->Format)->Palette_only)
 | 
			
		||||
      {
 | 
			
		||||
        short index;
 | 
			
		||||
      
 | 
			
		||||
        if (context->Type == CONTEXT_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);
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    case CONTEXT_PREVIEW:      
 | 
			
		||||
    case CONTEXT_MAIN_IMAGE:
 | 
			
		||||
    case CONTEXT_BRUSH:
 | 
			
		||||
    case CONTEXT_SURFACE:
 | 
			
		||||
@ -336,17 +283,17 @@ void Set_pixel_24b(T_IO_Context *context, short x_pos, short y_pos, byte r, byte
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    case CONTEXT_PREVIEW:
 | 
			
		||||
      {
 | 
			
		||||
      
 | 
			
		||||
        if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0))
 | 
			
		||||
        {
 | 
			
		||||
          color=((r >> 5) << 5) |
 | 
			
		||||
                  ((g >> 5) << 2) |
 | 
			
		||||
                  ((b >> 6));
 | 
			
		||||
          Pixel(context->Preview_pos_X+(x_pos/context->Preview_factor_X),
 | 
			
		||||
                context->Preview_pos_Y+(y_pos/context->Preview_factor_Y),
 | 
			
		||||
                color);
 | 
			
		||||
        }
 | 
			
		||||
      if (((x_pos % context->Preview_factor_X)==0) && ((y_pos % context->Preview_factor_Y)==0))
 | 
			
		||||
      {
 | 
			
		||||
        color=((r >> 5) << 5) |
 | 
			
		||||
                ((g >> 5) << 2) |
 | 
			
		||||
                ((b >> 6));
 | 
			
		||||
        
 | 
			
		||||
        // Tag the color as 'used'
 | 
			
		||||
        context->Preview_usage[color]=1;
 | 
			
		||||
        
 | 
			
		||||
        context->Preview_bitmap[x_pos/context->Preview_factor_X + (y_pos/context->Preview_factor_Y)*PREVIEW_WIDTH*Menu_factor_X]=color;
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
@ -388,6 +335,11 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
 | 
			
		||||
    // Preview
 | 
			
		||||
    case CONTEXT_PREVIEW:
 | 
			
		||||
      // Préparation du chargement d'une preview:
 | 
			
		||||
      
 | 
			
		||||
      context->Preview_bitmap=malloc(PREVIEW_WIDTH*PREVIEW_HEIGHT*Menu_factor_X*Menu_factor_Y);
 | 
			
		||||
      if (!context->Preview_bitmap)
 | 
			
		||||
        File_error=1;
 | 
			
		||||
      
 | 
			
		||||
      // Affichage des données "Image size:"
 | 
			
		||||
      if ((width<10000) && (height<10000))
 | 
			
		||||
      {
 | 
			
		||||
@ -426,11 +378,12 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
 | 
			
		||||
      {
 | 
			
		||||
        Print_in_window( 59,59,Get_fileformat(format)->Label,MC_Black,MC_Light);
 | 
			
		||||
      }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
      // On efface le commentaire précédent
 | 
			
		||||
      Window_rectangle(45,70,32*8,8,MC_Light);
 | 
			
		||||
      // Affichage du commentaire
 | 
			
		||||
      Print_in_window(45,70,context->Comment,MC_Black,MC_Light);
 | 
			
		||||
      if (Get_fileformat(format)->Comment)
 | 
			
		||||
        Print_in_window(45,70,Main_comment,MC_Black,MC_Light);
 | 
			
		||||
  
 | 
			
		||||
      // Calcul des données nécessaires à l'affichage de la preview:
 | 
			
		||||
      if (ratio == PIXEL_WIDE && 
 | 
			
		||||
@ -442,8 +395,8 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
 | 
			
		||||
          Pixel_ratio != PIXEL_TALL2)
 | 
			
		||||
        height*=2;
 | 
			
		||||
      
 | 
			
		||||
      context->Preview_factor_X=Round_div_max(width,122*Menu_factor_X);
 | 
			
		||||
      context->Preview_factor_Y=Round_div_max(height, 82*Menu_factor_Y);
 | 
			
		||||
      context->Preview_factor_X=Round_div_max(width,120*Menu_factor_X);
 | 
			
		||||
      context->Preview_factor_Y=Round_div_max(height, 80*Menu_factor_Y);
 | 
			
		||||
  
 | 
			
		||||
      if ( (!Config.Maximize_preview) && (context->Preview_factor_X!=context->Preview_factor_Y) )
 | 
			
		||||
      {
 | 
			
		||||
@ -457,17 +410,17 @@ void Pre_load(T_IO_Context *context, short width, short height, long file_size,
 | 
			
		||||
      context->Preview_pos_Y=Window_pos_Y+ 95*Menu_factor_Y;
 | 
			
		||||
  
 | 
			
		||||
      // On nettoie la zone où va s'afficher la preview:
 | 
			
		||||
      Window_rectangle(183,95,120,80,MC_Light);
 | 
			
		||||
      Window_rectangle(183,95,PREVIEW_WIDTH,PREVIEW_HEIGHT,MC_Light);
 | 
			
		||||
      
 | 
			
		||||
      // Un update pour couvrir les 4 zones: 3 libellés plus le commentaire
 | 
			
		||||
      Update_window_area(45,48,256,30);
 | 
			
		||||
      // Zone de preview
 | 
			
		||||
      Update_window_area(183,95,120,80);
 | 
			
		||||
      Update_window_area(183,95,PREVIEW_WIDTH,PREVIEW_HEIGHT);
 | 
			
		||||
      break;
 | 
			
		||||
      
 | 
			
		||||
    // Other loading
 | 
			
		||||
    case CONTEXT_MAIN_IMAGE:
 | 
			
		||||
      if (Backup_with_new_dimensions(0,1,width,height))
 | 
			
		||||
      if (Backup_new_image(1,width,height))
 | 
			
		||||
      {
 | 
			
		||||
        // La nouvelle page a pu être allouée, elle est pour l'instant pleine
 | 
			
		||||
        // de 0s. Elle fait Main_image_width de large.
 | 
			
		||||
@ -605,7 +558,10 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int index; // index de balayage des formats
 | 
			
		||||
  T_Format *format = &(File_formats[2]); // Format du fichier à charger
 | 
			
		||||
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  // Not sure it's the best place...
 | 
			
		||||
  context->Color_cycles=0;
 | 
			
		||||
 | 
			
		||||
  // On place par défaut File_error à vrai au cas où on ne sache pas
 | 
			
		||||
  // charger le format du fichier:
 | 
			
		||||
@ -622,7 +578,7 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
  {
 | 
			
		||||
    //  Sinon, on va devoir scanner les différents formats qu'on connait pour
 | 
			
		||||
    // savoir à quel format est le fichier:
 | 
			
		||||
    for (index=0; index < NB_KNOWN_FORMATS; index++)
 | 
			
		||||
    for (index=0; index < Nb_known_formats(); index++)
 | 
			
		||||
    {
 | 
			
		||||
      format = Get_fileformat(index);
 | 
			
		||||
      // Loadable format
 | 
			
		||||
@ -714,7 +670,7 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
          
 | 
			
		||||
        case CONTEXT_SURFACE:
 | 
			
		||||
          if (Convert_24b_bitmap_to_256(context->Surface->pixels,context->Buffer_image_24b,context->Width,context->Height,context->Palette))
 | 
			
		||||
            File_error=1;
 | 
			
		||||
          File_error=1;
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
@ -722,11 +678,34 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
    free(context->Buffer_image_24b);
 | 
			
		||||
    context->Buffer_image_24b = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  else if (context->Type == CONTEXT_MAIN_IMAGE)
 | 
			
		||||
  {
 | 
			
		||||
    // Non-24b main image: Add menu colors
 | 
			
		||||
    if (Config.Safety_colors)
 | 
			
		||||
    {
 | 
			
		||||
      dword color_usage[256];
 | 
			
		||||
      memset(color_usage,0,sizeof(color_usage));
 | 
			
		||||
      if (Count_used_colors(color_usage)<252)
 | 
			
		||||
      {
 | 
			
		||||
        int gui_index=0;
 | 
			
		||||
        int c;
 | 
			
		||||
        for (c=255; c>=0 && gui_index<4; c--)
 | 
			
		||||
        {
 | 
			
		||||
          if (color_usage[c]==0)
 | 
			
		||||
          {
 | 
			
		||||
            context->Palette[c]=*Favorite_GUI_color(gui_index);
 | 
			
		||||
            gui_index++;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (context->Type == CONTEXT_MAIN_IMAGE)
 | 
			
		||||
  {
 | 
			
		||||
    if ( File_error!=1)
 | 
			
		||||
    {
 | 
			
		||||
      Set_palette(context->Palette);
 | 
			
		||||
      if (format->Palette_only)
 | 
			
		||||
      {
 | 
			
		||||
        // Make a backup step
 | 
			
		||||
@ -773,6 +752,21 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
          Main_image_width=1;
 | 
			
		||||
        if (Main_image_height<1)
 | 
			
		||||
          Main_image_height=1;
 | 
			
		||||
 | 
			
		||||
        // Color cyling ranges:
 | 
			
		||||
        for (i=0; i<16; i++)
 | 
			
		||||
          Main_backups->Pages->Gradients->Range[i].Speed=0;
 | 
			
		||||
        for (i=0; i<context->Color_cycles; i++)
 | 
			
		||||
        {
 | 
			
		||||
          Main_backups->Pages->Gradients->Range[i].Start=context->Cycle_range[i].Start;
 | 
			
		||||
          Main_backups->Pages->Gradients->Range[i].End=context->Cycle_range[i].End;
 | 
			
		||||
          Main_backups->Pages->Gradients->Range[i].Inverse=context->Cycle_range[i].Inverse;
 | 
			
		||||
          Main_backups->Pages->Gradients->Range[i].Speed=context->Cycle_range[i].Speed;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Comment
 | 
			
		||||
        strcpy(Main_comment, context->Comment);
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else if (File_error!=1)
 | 
			
		||||
@ -791,19 +785,16 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
  }
 | 
			
		||||
  else if (context->Type == CONTEXT_BRUSH && File_error==0)
 | 
			
		||||
  {
 | 
			
		||||
    free(Brush);
 | 
			
		||||
    Brush=context->Buffer_image;
 | 
			
		||||
    context->Buffer_image = NULL;
 | 
			
		||||
 | 
			
		||||
    Brush_width=context->Width;
 | 
			
		||||
    Brush_height=context->Height;
 | 
			
		||||
 | 
			
		||||
    free(Smear_brush);
 | 
			
		||||
      Smear_brush_width=(Brush_width>MAX_PAINTBRUSH_SIZE)?Brush_width:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
      Smear_brush_height=(Brush_height>MAX_PAINTBRUSH_SIZE)?Brush_height:MAX_PAINTBRUSH_SIZE;
 | 
			
		||||
    Smear_brush=(byte *)malloc(Smear_brush_width*Smear_brush_height);
 | 
			
		||||
    if (!Smear_brush)
 | 
			
		||||
    
 | 
			
		||||
    if (Realloc_brush(context->Width, context->Height, context->Buffer_image, NULL))
 | 
			
		||||
    {
 | 
			
		||||
      File_error=3;
 | 
			
		||||
      free(context->Buffer_image);
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(Brush_original_palette, context->Palette, sizeof(T_Palette));
 | 
			
		||||
    Remap_brush();
 | 
			
		||||
 | 
			
		||||
    context->Buffer_image = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  else if (context->Type == CONTEXT_SURFACE)
 | 
			
		||||
  {
 | 
			
		||||
@ -822,6 +813,91 @@ void Load_image(T_IO_Context *context)
 | 
			
		||||
      SDL_SetColors(context->Surface, colors, 0, 256);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (context->Type == CONTEXT_PREVIEW
 | 
			
		||||
    /*&& !context->Buffer_image_24b*/
 | 
			
		||||
    /*&& !Get_fileformat(context->Format)->Palette_only*/)
 | 
			
		||||
  {
 | 
			
		||||
  
 | 
			
		||||
    // Try to adapt the palette to accomodate the GUI.
 | 
			
		||||
    int c;
 | 
			
		||||
    int count_unused;
 | 
			
		||||
    byte unused_color[4];
 | 
			
		||||
    
 | 
			
		||||
    count_unused=0;
 | 
			
		||||
    // Try find 4 unused colors and insert good colors there
 | 
			
		||||
    for (c=255; c>=0 && count_unused<4; c--)
 | 
			
		||||
    {
 | 
			
		||||
      if (!context->Preview_usage[c])
 | 
			
		||||
      {
 | 
			
		||||
        unused_color[count_unused]=c;
 | 
			
		||||
        count_unused++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Found! replace them with some favorites
 | 
			
		||||
    if (count_unused==4)
 | 
			
		||||
    {
 | 
			
		||||
      int gui_index;
 | 
			
		||||
      for (gui_index=0; gui_index<4; gui_index++)
 | 
			
		||||
      {
 | 
			
		||||
        context->Palette[unused_color[gui_index]]=*Favorite_GUI_color(gui_index);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // All preview display is here
 | 
			
		||||
    
 | 
			
		||||
    // Update palette and screen first
 | 
			
		||||
    Compute_optimal_menu_colors(context->Palette);
 | 
			
		||||
    Remap_screen_after_menu_colors_change();
 | 
			
		||||
    Set_palette(context->Palette);
 | 
			
		||||
    
 | 
			
		||||
    // Display palette preview
 | 
			
		||||
    if (Get_fileformat(context->Format)->Palette_only)
 | 
			
		||||
    {
 | 
			
		||||
      short index;
 | 
			
		||||
    
 | 
			
		||||
      if (context->Type == CONTEXT_PREVIEW)
 | 
			
		||||
        for (index=0; index<256; index++)
 | 
			
		||||
          Window_rectangle(183+(index/16)*7,95+(index&15)*5,5,5,index);
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
    // Display normal image
 | 
			
		||||
    else if (context->Preview_bitmap)
 | 
			
		||||
    {
 | 
			
		||||
      int x_pos,y_pos;
 | 
			
		||||
      int width,height;
 | 
			
		||||
      width=context->Width/context->Preview_factor_X;
 | 
			
		||||
      height=context->Height/context->Preview_factor_Y;
 | 
			
		||||
      if (context->Ratio == PIXEL_WIDE && 
 | 
			
		||||
          Pixel_ratio != PIXEL_WIDE &&
 | 
			
		||||
          Pixel_ratio != PIXEL_WIDE2)
 | 
			
		||||
        width*=2;
 | 
			
		||||
      else if (context->Ratio == PIXEL_TALL && 
 | 
			
		||||
          Pixel_ratio != PIXEL_TALL &&
 | 
			
		||||
          Pixel_ratio != PIXEL_TALL2)
 | 
			
		||||
        height*=2;
 | 
			
		||||
      
 | 
			
		||||
      for (y_pos=0; y_pos<height;y_pos++)
 | 
			
		||||
        for (x_pos=0; x_pos<width;x_pos++)
 | 
			
		||||
        {
 | 
			
		||||
          byte color=context->Preview_bitmap[x_pos+y_pos*PREVIEW_WIDTH*Menu_factor_X];
 | 
			
		||||
 | 
			
		||||
          // Skip transparent if image has transparent background.
 | 
			
		||||
          if (color == context->Transparent_color && context->Background_transparent)
 | 
			
		||||
            color=MC_Window;
 | 
			
		||||
 | 
			
		||||
          Pixel(context->Preview_pos_X+x_pos,
 | 
			
		||||
                context->Preview_pos_Y+y_pos,
 | 
			
		||||
                color);
 | 
			
		||||
        }
 | 
			
		||||
    }    
 | 
			
		||||
    // Refresh modified part
 | 
			
		||||
    Update_window_area(183,95,PREVIEW_WIDTH,PREVIEW_HEIGHT);
 | 
			
		||||
    
 | 
			
		||||
    // Preview comment
 | 
			
		||||
    Print_in_window(45,70,context->Comment,MC_Black,MC_Light);
 | 
			
		||||
    //Update_window_area(45,70,32*8,8);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -916,8 +992,10 @@ void Load_SDL_Image(T_IO_Context *context)
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    // Hi/Trucolor
 | 
			
		||||
    Pre_load(context, surface->w, surface->h, file_size ,FORMAT_ALL_IMAGES, PIXEL_SIMPLE, 1);
 | 
			
		||||
    {
 | 
			
		||||
      // Hi/Trucolor
 | 
			
		||||
      Pre_load(context, surface->w, surface->h, file_size ,FORMAT_ALL_IMAGES, PIXEL_SIMPLE, 1);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    for (y_pos=0; y_pos<context->Height; y_pos++)
 | 
			
		||||
    {
 | 
			
		||||
@ -938,8 +1016,10 @@ void Load_SDL_Image(T_IO_Context *context)
 | 
			
		||||
  SDL_FreeSurface(surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Load an arbitrary SDL_Surface.
 | 
			
		||||
SDL_Surface * Load_surface(char *full_name)
 | 
			
		||||
/// @param gradients Pass the address of a target T_Gradient_array if you want the gradients, NULL otherwise
 | 
			
		||||
SDL_Surface * Load_surface(char *full_name, T_Gradient_array *gradients)
 | 
			
		||||
{
 | 
			
		||||
  SDL_Surface * bmp=NULL;
 | 
			
		||||
  T_IO_Context context;
 | 
			
		||||
@ -948,8 +1028,23 @@ SDL_Surface * Load_surface(char *full_name)
 | 
			
		||||
  Load_image(&context);
 | 
			
		||||
  
 | 
			
		||||
  if (context.Surface)
 | 
			
		||||
  {
 | 
			
		||||
    bmp=context.Surface;
 | 
			
		||||
    
 | 
			
		||||
    // Caller wants the gradients:
 | 
			
		||||
    if (gradients != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      int i;
 | 
			
		||||
      
 | 
			
		||||
      memset(gradients, 0, sizeof(T_Gradient_array));
 | 
			
		||||
      for (i=0; i<context.Color_cycles; i++)
 | 
			
		||||
      {
 | 
			
		||||
        gradients->Range[i].Start=context.Cycle_range[i].Start;
 | 
			
		||||
        gradients->Range[i].End=context.Cycle_range[i].End;
 | 
			
		||||
        gradients->Range[i].Inverse=context.Cycle_range[i].Inverse;
 | 
			
		||||
        gradients->Range[i].Speed=context.Cycle_range[i].Speed;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } 
 | 
			
		||||
  Destroy_context(&context);
 | 
			
		||||
 | 
			
		||||
  return bmp;
 | 
			
		||||
@ -1011,10 +1106,12 @@ void Emergency_backup(const char *fname, byte *source, int width, int height, T_
 | 
			
		||||
 | 
			
		||||
void Image_emergency_backup()
 | 
			
		||||
{
 | 
			
		||||
#ifndef NOLAYERS
 | 
			
		||||
  if (Main_backups && Main_backups->Pages && Main_backups->Pages->Nb_layers == 1)
 | 
			
		||||
    Emergency_backup("a999999.bkp",Main_screen, Main_image_width, Main_image_height, &Main_palette);
 | 
			
		||||
    Emergency_backup(SAFETYBACKUP_PREFIX_A "999999" BACKUP_FILE_EXTENSION,Main_screen, Main_image_width, Main_image_height, &Main_palette);
 | 
			
		||||
  if (Spare_backups && Spare_backups->Pages && Spare_backups->Pages->Nb_layers == 1)
 | 
			
		||||
    Emergency_backup("b999999.bkp",Spare_visible_image.Image, Spare_image_width, Spare_image_height, &Spare_palette);
 | 
			
		||||
    Emergency_backup(SAFETYBACKUP_PREFIX_B "999999" BACKUP_FILE_EXTENSION,Spare_visible_image.Image, Spare_image_width, Spare_image_height, &Spare_palette);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
T_Format * Get_fileformat(byte format)
 | 
			
		||||
@ -1022,7 +1119,7 @@ T_Format * Get_fileformat(byte format)
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  T_Format * safe_default = File_formats;
 | 
			
		||||
  
 | 
			
		||||
  for (i=0; i < NB_KNOWN_FORMATS; i++)
 | 
			
		||||
  for (i=0; i < Nb_known_formats(); i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (File_formats[i].Identifier == format)
 | 
			
		||||
      return &(File_formats[i]);
 | 
			
		||||
@ -1041,11 +1138,12 @@ byte Get_pixel(T_IO_Context *context, short x, short y)
 | 
			
		||||
  return *(context->Target_address + y*context->Pitch + x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Cleans up resources (currently: the 24bit buffer) 
 | 
			
		||||
/// Cleans up resources
 | 
			
		||||
void Destroy_context(T_IO_Context *context)
 | 
			
		||||
{
 | 
			
		||||
  free(context->Buffer_image_24b);
 | 
			
		||||
  free(context->Buffer_image);
 | 
			
		||||
  free(context->Preview_bitmap);
 | 
			
		||||
  memset(context, 0, sizeof(T_IO_Context));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1069,6 +1167,8 @@ void Init_context_backup_image(T_IO_Context * context, char *file_name, char *fi
 | 
			
		||||
/// Setup for loading/saving the current main image
 | 
			
		||||
void Init_context_layered_image(T_IO_Context * context, char *file_name, char *file_directory)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  memset(context, 0, sizeof(T_IO_Context));
 | 
			
		||||
  
 | 
			
		||||
  context->Type = CONTEXT_MAIN_IMAGE;
 | 
			
		||||
@ -1091,6 +1191,18 @@ void Init_context_layered_image(T_IO_Context * context, char *file_name, char *f
 | 
			
		||||
  context->Target_address=Main_backups->Pages->Image[0];
 | 
			
		||||
  context->Pitch=Main_image_width;
 | 
			
		||||
  
 | 
			
		||||
  // Color cyling ranges:
 | 
			
		||||
  for (i=0; i<16; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (Main_backups->Pages->Gradients->Range[i].Start!=Main_backups->Pages->Gradients->Range[i].End)
 | 
			
		||||
    {
 | 
			
		||||
      context->Cycle_range[context->Color_cycles].Start=Main_backups->Pages->Gradients->Range[i].Start;
 | 
			
		||||
      context->Cycle_range[context->Color_cycles].End=Main_backups->Pages->Gradients->Range[i].End;
 | 
			
		||||
      context->Cycle_range[context->Color_cycles].Inverse=Main_backups->Pages->Gradients->Range[i].Inverse;
 | 
			
		||||
      context->Cycle_range[context->Color_cycles].Speed=Main_backups->Pages->Gradients->Range[i].Speed;
 | 
			
		||||
      context->Color_cycles++;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Setup for loading/saving the flattened version of current main image
 | 
			
		||||
@ -1332,8 +1444,13 @@ int Check_recovery(void)
 | 
			
		||||
  int restored_main;
 | 
			
		||||
  
 | 
			
		||||
  // First check if can write backups
 | 
			
		||||
  if (Create_lock_file(Config_directory))
 | 
			
		||||
#if defined (__MINT__) 
 | 
			
		||||
   //TODO: enable file lock under Freemint only
 | 
			
		||||
   return 0;
 | 
			
		||||
#else  
 | 
			
		||||
if (Create_lock_file(Config_directory))
 | 
			
		||||
    return -1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  Safety_backup_active=1;
 | 
			
		||||
    
 | 
			
		||||
@ -1389,7 +1506,7 @@ void Rotate_safety_backups(void)
 | 
			
		||||
  {
 | 
			
		||||
    
 | 
			
		||||
    // Clear a previous save (rotating saves)
 | 
			
		||||
    sprintf(deleted_file, "%s%c%6.6d.bkp",
 | 
			
		||||
    sprintf(deleted_file, "%s%c%6.6d" BACKUP_FILE_EXTENSION,
 | 
			
		||||
      Config_directory,
 | 
			
		||||
      Main_safety_backup_prefix,
 | 
			
		||||
      (Uint32)(Main_safety_number + 1000000l - Rotation_safety_backup) % (Uint32)1000000l);
 | 
			
		||||
@ -1400,7 +1517,7 @@ void Rotate_safety_backups(void)
 | 
			
		||||
    Main_time_of_safety_backup=now;
 | 
			
		||||
 | 
			
		||||
    // Create a new file name and save
 | 
			
		||||
    sprintf(file_name, "%c%6.6d.bkp",
 | 
			
		||||
    sprintf(file_name, "%c%6.6d" BACKUP_FILE_EXTENSION,
 | 
			
		||||
      Main_safety_backup_prefix,
 | 
			
		||||
      (Uint32)Main_safety_number);
 | 
			
		||||
    Init_context_backup_image(&context, file_name, Config_directory);
 | 
			
		||||
@ -1442,6 +1559,10 @@ void Delete_safety_backups(void)
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Release lock file
 | 
			
		||||
#if defined (__MINT__) 
 | 
			
		||||
  //TODO: release file lock under Freemint only
 | 
			
		||||
#else 
 | 
			
		||||
  Release_lock_file(Config_directory);
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,14 @@ enum CONTEXT_TYPE {
 | 
			
		||||
  CONTEXT_SURFACE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Data for a cycling color series. Heavily cloned from T_Gradient_array.
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  byte Start;    ///< First color
 | 
			
		||||
  byte End;      ///< Last color
 | 
			
		||||
  byte Inverse;  ///< Boolean, true if the gradient goes in descending order
 | 
			
		||||
  byte Speed;    ///< Frequency of cycling, from 1 (slow) to 64 (fast)
 | 
			
		||||
} T_Color_cycle;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
@ -71,6 +79,9 @@ typedef struct
 | 
			
		||||
  /// Original file directory, stored in GIF file
 | 
			
		||||
  char * Original_file_directory;
 | 
			
		||||
 | 
			
		||||
  byte Color_cycles;
 | 
			
		||||
  T_Color_cycle Cycle_range[16];
 | 
			
		||||
 | 
			
		||||
  /// Internal: during load, marks which layer is being loaded.
 | 
			
		||||
  short Current_layer;
 | 
			
		||||
 | 
			
		||||
@ -87,12 +98,17 @@ typedef struct
 | 
			
		||||
  short Preview_factor_Y;
 | 
			
		||||
  short Preview_pos_X;
 | 
			
		||||
  short Preview_pos_Y;
 | 
			
		||||
  byte *Preview_bitmap;
 | 
			
		||||
  byte  Preview_usage[256];
 | 
			
		||||
  
 | 
			
		||||
  // Internal: returned surface for SDL_Surface case
 | 
			
		||||
  SDL_Surface * Surface;
 | 
			
		||||
 | 
			
		||||
} T_IO_Context;
 | 
			
		||||
 | 
			
		||||
#define PREVIEW_WIDTH  120
 | 
			
		||||
#define PREVIEW_HEIGHT  80
 | 
			
		||||
 | 
			
		||||
/// Type of a function that can be called for a T_IO_Context. Kind of a method.
 | 
			
		||||
typedef void (* Func_IO) (T_IO_Context *);
 | 
			
		||||
 | 
			
		||||
@ -165,8 +181,10 @@ extern T_Format File_formats[];
 | 
			
		||||
/// is too high.
 | 
			
		||||
void Image_emergency_backup(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Load an arbitrary SDL_Surface.
 | 
			
		||||
SDL_Surface * Load_surface(char *full_name);
 | 
			
		||||
/// @param gradients Pass the address of a target T_Gradient_array if you want the gradients, NULL otherwise
 | 
			
		||||
SDL_Surface * Load_surface(char *full_name, T_Gradient_array *gradients);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@ -178,12 +196,8 @@ T_Format * Get_fileformat(byte format);
 | 
			
		||||
 | 
			
		||||
// -- File formats
 | 
			
		||||
 | 
			
		||||
#ifndef __no_pnglib__
 | 
			
		||||
#define NB_KNOWN_FORMATS 19 ///< Total number of known file formats.
 | 
			
		||||
#else
 | 
			
		||||
// Without pnglib
 | 
			
		||||
#define NB_KNOWN_FORMATS 18 ///< Total number of known file formats.
 | 
			
		||||
#endif
 | 
			
		||||
/// Total number of known file formats
 | 
			
		||||
unsigned int Nb_known_formats(void);
 | 
			
		||||
 | 
			
		||||
// Internal use
 | 
			
		||||
 | 
			
		||||
@ -210,7 +224,6 @@ void Set_layer(T_IO_Context *context, byte layer);
 | 
			
		||||
// =================================================================
 | 
			
		||||
 | 
			
		||||
// This is here and not in fileformats.c because the emergency save uses it...
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  byte Filler1[6];
 | 
			
		||||
@ -219,7 +232,6 @@ typedef struct
 | 
			
		||||
  byte Filler2[118];
 | 
			
		||||
  T_Palette Palette;
 | 
			
		||||
} T_IMG_Header;
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
// Data for 24bit loading
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										164
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								src/main.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2009 Pasi Kallinen
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -40,7 +41,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// There is no WM on the GP2X...
 | 
			
		||||
#ifndef __GP2X__
 | 
			
		||||
#if !defined(__GP2X__) && !defined(__WIZ__) && !defined(__CAANOO__)
 | 
			
		||||
    #include <SDL_syswm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -65,11 +66,14 @@
 | 
			
		||||
#include "brush.h"
 | 
			
		||||
#include "palette.h"
 | 
			
		||||
#include "realpath.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__WIN32__)
 | 
			
		||||
    #include <windows.h>
 | 
			
		||||
    #include <shlwapi.h>
 | 
			
		||||
    #define chdir(dir) SetCurrentDirectory(dir)
 | 
			
		||||
#elif defined (__MINT__)
 | 
			
		||||
    #include <mint/osbind.h>
 | 
			
		||||
#elif defined(__macosx__)
 | 
			
		||||
    #import <corefoundation/corefoundation.h>
 | 
			
		||||
    #import <sys/param.h>
 | 
			
		||||
@ -85,6 +89,8 @@
 | 
			
		||||
  extern DECLSPEC int SDLCALL SDL_putenv(const char *variable);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern char Program_version[]; // generated in pversion.c
 | 
			
		||||
 | 
			
		||||
//--- Affichage de la syntaxe, et de la liste des modes vidéos disponibles ---
 | 
			
		||||
void Display_syntax(void)
 | 
			
		||||
{
 | 
			
		||||
@ -139,7 +145,7 @@ void Error_function(int error_code, const char *filename, int line_number, const
 | 
			
		||||
    for (index=0;index<=255;index++)
 | 
			
		||||
      temp_palette[index].R=255;
 | 
			
		||||
    Set_palette(temp_palette);
 | 
			
		||||
    SDL_Delay(500);
 | 
			
		||||
    Delay_with_active_mouse(50); // Half a second of red flash
 | 
			
		||||
    Set_palette(Main_palette);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
@ -400,22 +406,39 @@ int Analyze_command_line(int argc, char * argv[], char *main_filename, char *mai
 | 
			
		||||
  return file_in_command_line;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Compile-time assertions:
 | 
			
		||||
#define CT_ASSERT(e) extern char (*ct_assert(void)) [sizeof(char[1 - 2*!(e)])]
 | 
			
		||||
 | 
			
		||||
// This line will raise an error at compile time
 | 
			
		||||
// when sizeof(T_Components) is not 3.
 | 
			
		||||
CT_ASSERT(sizeof(T_Components)==3);
 | 
			
		||||
 | 
			
		||||
// This line will raise an error at compile time
 | 
			
		||||
// when sizeof(T_Palette) is not 768.
 | 
			
		||||
CT_ASSERT(sizeof(T_Palette)==768);
 | 
			
		||||
 | 
			
		||||
// ------------------------ Initialiser le programme -------------------------
 | 
			
		||||
// Returns 0 on fail
 | 
			
		||||
int Init_program(int argc,char * argv[])
 | 
			
		||||
{
 | 
			
		||||
{   
 | 
			
		||||
  int temp;
 | 
			
		||||
  int starting_videomode;
 | 
			
		||||
  static char program_directory[MAX_PATH_CHARACTERS];
 | 
			
		||||
  T_Gui_skin *gfx;
 | 
			
		||||
  int file_in_command_line;
 | 
			
		||||
  T_Gradient_array initial_gradients;
 | 
			
		||||
  static char main_filename [MAX_PATH_CHARACTERS];
 | 
			
		||||
  static char main_directory[MAX_PATH_CHARACTERS];
 | 
			
		||||
  static char spare_filename [MAX_PATH_CHARACTERS];
 | 
			
		||||
  static char spare_directory[MAX_PATH_CHARACTERS];
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
  #if defined(__MINT__)  
 | 
			
		||||
  printf("===============================\n");
 | 
			
		||||
  printf(" /|\\ GrafX2 %.19s\n", Program_version);
 | 
			
		||||
  printf(" compilation date: %.16s\n", __DATE__);
 | 
			
		||||
  printf("===============================\n");
 | 
			
		||||
  #endif 
 | 
			
		||||
 
 | 
			
		||||
  // On crée dès maintenant les descripteurs des listes de pages pour la page
 | 
			
		||||
  // principale et la page de brouillon afin que leurs champs ne soient pas
 | 
			
		||||
  // invalide lors des appels aux multiples fonctions manipulées à
 | 
			
		||||
@ -431,9 +454,12 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  Set_data_directory(program_directory,Data_directory);
 | 
			
		||||
  // Choose directory for settings (read/write)
 | 
			
		||||
  Set_config_directory(program_directory,Config_directory);
 | 
			
		||||
 | 
			
		||||
  // On détermine le répertoire courant:
 | 
			
		||||
#if defined(__MINT__)
 | 
			
		||||
  strcpy(Main_current_directory,program_directory);
 | 
			
		||||
#else
 | 
			
		||||
// On détermine le répertoire courant:
 | 
			
		||||
  getcwd(Main_current_directory,256);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // On en profite pour le mémoriser dans le répertoire principal:
 | 
			
		||||
  strcpy(Initial_directory,Main_current_directory);
 | 
			
		||||
@ -473,8 +499,6 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  // On initialise d'ot' trucs
 | 
			
		||||
  Main_offset_X=0;
 | 
			
		||||
  Main_offset_Y=0;
 | 
			
		||||
  Old_main_offset_X=0;
 | 
			
		||||
  Old_main_offset_Y=0;
 | 
			
		||||
  Main_separator_position=0;
 | 
			
		||||
  Main_X_zoom=0;
 | 
			
		||||
  Main_separator_proportion=INITIAL_SEPARATOR_PROPORTION;
 | 
			
		||||
@ -486,8 +510,6 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  Main_magnifier_offset_Y=0;
 | 
			
		||||
  Spare_offset_X=0;
 | 
			
		||||
  Spare_offset_Y=0;
 | 
			
		||||
  Old_spare_offset_X=0;
 | 
			
		||||
  Old_spare_offset_Y=0;
 | 
			
		||||
  Spare_separator_position=0;
 | 
			
		||||
  Spare_X_zoom=0;
 | 
			
		||||
  Spare_separator_proportion=INITIAL_SEPARATOR_PROPORTION;
 | 
			
		||||
@ -497,62 +519,27 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  Spare_magnifier_width=0;
 | 
			
		||||
  Spare_magnifier_offset_X=0;
 | 
			
		||||
  Spare_magnifier_offset_Y=0;
 | 
			
		||||
  Keyboard_click_allowed = 0;
 | 
			
		||||
  Keyboard_click_allowed = 1;
 | 
			
		||||
  
 | 
			
		||||
  Main_safety_backup_prefix = 'a';
 | 
			
		||||
  Spare_safety_backup_prefix = 'b';
 | 
			
		||||
  Main_safety_backup_prefix = SAFETYBACKUP_PREFIX_A[0];
 | 
			
		||||
  Spare_safety_backup_prefix = SAFETYBACKUP_PREFIX_B[0];
 | 
			
		||||
  Main_time_of_safety_backup = 0;
 | 
			
		||||
  Spare_time_of_safety_backup = 0;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // SDL
 | 
			
		||||
  if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0)
 | 
			
		||||
  if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0)
 | 
			
		||||
  {
 | 
			
		||||
    // The program can't continue without that anyway
 | 
			
		||||
    printf("Couldn't initialize SDL.\n");
 | 
			
		||||
    return(0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  Joystick = SDL_JoystickOpen(0);
 | 
			
		||||
  SDL_EnableKeyRepeat(250, 32);
 | 
			
		||||
  SDL_EnableUNICODE(SDL_ENABLE);
 | 
			
		||||
  SDL_WM_SetCaption("GrafX2","GrafX2");
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    // Routine pour définir l'icone.
 | 
			
		||||
    char icon_path[MAX_PATH_CHARACTERS];
 | 
			
		||||
    SDL_Surface * icon;
 | 
			
		||||
    sprintf(icon_path, "%s%s", Data_directory, "gfx2.gif");
 | 
			
		||||
    icon = IMG_Load(icon_path);
 | 
			
		||||
    if (icon && icon->w == 32 && icon->h == 32)
 | 
			
		||||
    {
 | 
			
		||||
      Uint32 pink;
 | 
			
		||||
      pink = SDL_MapRGB(icon->format, 255, 0, 255);
 | 
			
		||||
      
 | 
			
		||||
      if (icon->format->BitsPerPixel == 8)
 | 
			
		||||
      {
 | 
			
		||||
        SDL_SetColorKey(icon, SDL_SRCCOLORKEY, pink);
 | 
			
		||||
        SDL_WM_SetIcon(icon,NULL);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        byte *icon_mask;
 | 
			
		||||
        int x,y;
 | 
			
		||||
        
 | 
			
		||||
        icon_mask=malloc(128);
 | 
			
		||||
        memset(icon_mask,0,128);
 | 
			
		||||
        for (y=0;y<32;y++)
 | 
			
		||||
          for (x=0;x<32;x++)
 | 
			
		||||
            if (Get_SDL_pixel_hicolor(icon, x, y) != pink)
 | 
			
		||||
              icon_mask[(y*32+x)/8] |=0x80>>(x&7);
 | 
			
		||||
        SDL_WM_SetIcon(icon,icon_mask);
 | 
			
		||||
        free(icon_mask);
 | 
			
		||||
        icon_mask = NULL;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      SDL_FreeSurface(icon);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  Define_icon();
 | 
			
		||||
  
 | 
			
		||||
  // Texte
 | 
			
		||||
  Init_text();
 | 
			
		||||
@ -574,7 +561,6 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  // Données sur le pinceau:
 | 
			
		||||
  Paintbrush_X=0;
 | 
			
		||||
  Paintbrush_Y=0;
 | 
			
		||||
  Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND;
 | 
			
		||||
  Paintbrush_hidden=0;
 | 
			
		||||
 | 
			
		||||
  // On initialise tout ce qui concerne les opérations et les effets
 | 
			
		||||
@ -634,6 +620,25 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
 | 
			
		||||
  Windows_open=0;
 | 
			
		||||
  
 | 
			
		||||
  // Paintbrush
 | 
			
		||||
  if (!(Paintbrush_sprite=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE))) Error(ERROR_MEMORY);
 | 
			
		||||
  
 | 
			
		||||
  // Load preset paintbrushes (uses Paintbrush_ variables)
 | 
			
		||||
  Init_paintbrushes();
 | 
			
		||||
  
 | 
			
		||||
  // Set a valid paintbrush afterwards
 | 
			
		||||
  *Paintbrush_sprite=1;
 | 
			
		||||
  Paintbrush_width=1;
 | 
			
		||||
  Paintbrush_height=1;
 | 
			
		||||
  Paintbrush_offset_X=0;
 | 
			
		||||
  Paintbrush_offset_Y=0;
 | 
			
		||||
  Paintbrush_shape=PAINTBRUSH_SHAPE_ROUND;
 | 
			
		||||
  
 | 
			
		||||
  #if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
  // Prefer cycling active by default
 | 
			
		||||
  Cycling_mode=1;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  // Charger la configuration des touches
 | 
			
		||||
  Set_config_defaults();
 | 
			
		||||
 | 
			
		||||
@ -662,10 +667,10 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  Help_position=0;
 | 
			
		||||
 | 
			
		||||
  // Load sprites, palette etc.
 | 
			
		||||
  gfx = Load_graphics(Config.Skin_file);
 | 
			
		||||
  gfx = Load_graphics(Config.Skin_file, &initial_gradients);
 | 
			
		||||
  if (gfx == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    gfx = Load_graphics("skin_DPaint.png");
 | 
			
		||||
    gfx = Load_graphics(DEFAULT_SKIN_FILENAME, &initial_gradients);
 | 
			
		||||
    if (gfx == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      printf("%s", Gui_loading_error_message);
 | 
			
		||||
@ -678,7 +683,10 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  // Gfx->Default_palette[MC_Dark] =Config.Fav_menu_colors[1];
 | 
			
		||||
  // Gfx->Default_palette[MC_Light]=Config.Fav_menu_colors[2];
 | 
			
		||||
  // Gfx->Default_palette[MC_White]=Config.Fav_menu_colors[3];
 | 
			
		||||
//  Compute_optimal_menu_colors(Gfx->Default_palette);
 | 
			
		||||
  
 | 
			
		||||
  // Even when using the skin's palette, if RGB range is small
 | 
			
		||||
  // the colors will be unusable.
 | 
			
		||||
  Compute_optimal_menu_colors(Gfx->Default_palette);
 | 
			
		||||
    
 | 
			
		||||
  // Infos sur les trames (Sieve)
 | 
			
		||||
  Sieve_mode=0;
 | 
			
		||||
@ -686,9 +694,9 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
 | 
			
		||||
  // Font
 | 
			
		||||
  if (!(Menu_font=Load_font(Config.Font_file)))
 | 
			
		||||
    if (!(Menu_font=Load_font("font_DPaint.png")))
 | 
			
		||||
    if (!(Menu_font=Load_font(DEFAULT_FONT_FILENAME)))
 | 
			
		||||
      {
 | 
			
		||||
        printf("Unable to open the default font file: %s\n", "font_Classic.png");
 | 
			
		||||
        printf("Unable to open the default font file: %s\n", DEFAULT_FONT_FILENAME);
 | 
			
		||||
        Error(ERROR_GUI_MISSING);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -701,11 +709,6 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  if (!(Brush         =(byte *)malloc(   1*   1))) Error(ERROR_MEMORY);
 | 
			
		||||
  if (!(Smear_brush   =(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE))) Error(ERROR_MEMORY);
 | 
			
		||||
 | 
			
		||||
  // Pinceau
 | 
			
		||||
  if (!(Paintbrush_sprite=(byte *)malloc(MAX_PAINTBRUSH_SIZE*MAX_PAINTBRUSH_SIZE))) Error(ERROR_MEMORY);
 | 
			
		||||
  *Paintbrush_sprite=1;
 | 
			
		||||
  Paintbrush_width=1;
 | 
			
		||||
  Paintbrush_height=1;
 | 
			
		||||
 | 
			
		||||
  starting_videomode=Current_resolution;
 | 
			
		||||
  Horizontal_line_buffer=NULL;
 | 
			
		||||
@ -731,6 +734,9 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
      SetWindowPos(pInfo.window, 0, Config.Window_pos_x, Config.Window_pos_y, 0, 0, SWP_NOSIZE);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Open a console for debugging...
 | 
			
		||||
  //ActivateConsole();
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
  Main_image_width=Screen_width/Pixel_width;
 | 
			
		||||
@ -745,15 +751,29 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  // Nettoyage de l'écran virtuel (les autres recevront celui-ci par copie)
 | 
			
		||||
  memset(Main_screen,0,Main_image_width*Main_image_height);
 | 
			
		||||
 | 
			
		||||
  // Now that the backup system is there, we can store the gradients.
 | 
			
		||||
  memcpy(Main_backups->Pages->Gradients->Range, initial_gradients.Range, sizeof(initial_gradients.Range));
 | 
			
		||||
  memcpy(Spare_backups->Pages->Gradients->Range, initial_gradients.Range, sizeof(initial_gradients.Range));
 | 
			
		||||
 | 
			
		||||
  Gradient_function=Gradient_basic;
 | 
			
		||||
  Gradient_lower_bound=0;
 | 
			
		||||
  Gradient_upper_bound=0;
 | 
			
		||||
  Gradient_random_factor=1;
 | 
			
		||||
  Gradient_bounds_range=1;
 | 
			
		||||
 | 
			
		||||
  Current_gradient=0;
 | 
			
		||||
 | 
			
		||||
  // Initialisation de diverses variables par calcul:
 | 
			
		||||
  Compute_magnifier_data();
 | 
			
		||||
  Compute_limits();
 | 
			
		||||
  Compute_paintbrush_coordinates();
 | 
			
		||||
 | 
			
		||||
  // On affiche le menu:
 | 
			
		||||
  Display_menu();
 | 
			
		||||
  Display_paintbrush_in_menu();
 | 
			
		||||
  Display_sprite_in_menu(BUTTON_PAL_LEFT,18+(Config.Palette_vertical!=0));
 | 
			
		||||
  Display_sprite_in_menu(BUTTON_PAL_LEFT,Config.Palette_vertical?MENU_SPRITE_VERTICAL_PALETTE_SCROLL:-1);
 | 
			
		||||
  Display_menu();
 | 
			
		||||
  Draw_menu_button(BUTTON_PAL_LEFT,BUTTON_RELEASED);
 | 
			
		||||
  Draw_menu_button(BUTTON_PAL_RIGHT,BUTTON_RELEASED);
 | 
			
		||||
 | 
			
		||||
  // On affiche le curseur pour débutter correctement l'état du programme:
 | 
			
		||||
  Display_cursor();
 | 
			
		||||
@ -770,8 +790,11 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
  // On initialise la brosse initiale à 1 pixel blanc:
 | 
			
		||||
  Brush_width=1;
 | 
			
		||||
  Brush_height=1;
 | 
			
		||||
  for (temp=0;temp<256;temp++)
 | 
			
		||||
    Brush_colormap[temp]=temp;
 | 
			
		||||
  Capture_brush(0,0,0,0,0);
 | 
			
		||||
  *Brush=MC_White;
 | 
			
		||||
  *Brush_original_pixels=MC_White;
 | 
			
		||||
  
 | 
			
		||||
  // Test de recuperation de fichiers sauvés
 | 
			
		||||
  switch (Check_recovery())
 | 
			
		||||
@ -843,6 +866,9 @@ int Init_program(int argc,char * argv[])
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Allow_drag_and_drop(1);
 | 
			
		||||
 | 
			
		||||
  return(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -908,6 +934,12 @@ void Program_shutdown(void)
 | 
			
		||||
    Error(ERROR_MISSING_DIRECTORY);
 | 
			
		||||
    
 | 
			
		||||
  SDL_Quit();
 | 
			
		||||
  
 | 
			
		||||
  #if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
  chdir("/usr/gp2x");
 | 
			
		||||
  execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								src/misc.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								src/misc.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
@ -177,7 +178,8 @@ void Wait_end_of_click(void)
 | 
			
		||||
{
 | 
			
		||||
  // On désactive tous les raccourcis clavier
 | 
			
		||||
 | 
			
		||||
  while(Mouse_K) if(!Get_input()) SDL_Delay(20);
 | 
			
		||||
  while(Mouse_K)
 | 
			
		||||
    Get_input(20);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clear_current_image_with_stencil(byte color, byte * stencil)
 | 
			
		||||
@ -339,7 +341,7 @@ void Rotate_270_deg_lowlevel(byte * source, byte * dest, short width, short heig
 | 
			
		||||
 | 
			
		||||
// Replace une couleur par une autre dans un buffer
 | 
			
		||||
 | 
			
		||||
void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width)
 | 
			
		||||
void Remap_general_lowlevel(byte * conversion_table,byte * in_buffer, byte *out_buffer,short width,short height,short buffer_width)
 | 
			
		||||
{
 | 
			
		||||
  int dx,cx;
 | 
			
		||||
 | 
			
		||||
@ -349,17 +351,19 @@ void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,sh
 | 
			
		||||
    // Pour chaque pixel
 | 
			
		||||
    for(cx=width;cx>0;cx--)
 | 
			
		||||
    {
 | 
			
		||||
      *buffer = conversion_table[*buffer];
 | 
			
		||||
      buffer++;
 | 
			
		||||
      *out_buffer = conversion_table[*in_buffer];
 | 
			
		||||
      in_buffer++;
 | 
			
		||||
      out_buffer++;
 | 
			
		||||
    }
 | 
			
		||||
    buffer += buffer_width-width;
 | 
			
		||||
    in_buffer += buffer_width-width;
 | 
			
		||||
    out_buffer += buffer_width-width;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width)
 | 
			
		||||
{
 | 
			
		||||
  byte* src=start_y*image_width+start_x+Main_backups->Pages->Image[Main_current_layer]; //Adr départ image (ESI)
 | 
			
		||||
  byte* dest=Brush; //Adr dest brosse (EDI)
 | 
			
		||||
  byte* dest=Brush_original_pixels; //Adr dest brosse (EDI)
 | 
			
		||||
  int dx;
 | 
			
		||||
 | 
			
		||||
  for (dx=Brush_height;dx!=0;dx--)
 | 
			
		||||
@ -499,6 +503,22 @@ byte Effect_substractive_colorize(word x,word y,byte color)
 | 
			
		||||
    blue<blue_under?blue:blue_under);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
byte Effect_alpha_colorize    (word x,word y,byte color)
 | 
			
		||||
{
 | 
			
		||||
  byte color_under = Read_pixel_from_feedback_screen(x,y);
 | 
			
		||||
  byte blue_under=Main_palette[color_under].B;
 | 
			
		||||
  byte green_under=Main_palette[color_under].G;
 | 
			
		||||
  byte red_under=Main_palette[color_under].R;
 | 
			
		||||
  int factor=(Main_palette[color].R*76 + 
 | 
			
		||||
    Main_palette[color].G*151 + 
 | 
			
		||||
    Main_palette[color].B*28)/255;
 | 
			
		||||
 | 
			
		||||
  return Best_color(
 | 
			
		||||
    (Main_palette[Fore_color].R*factor + red_under*(255-factor))/255,
 | 
			
		||||
    (Main_palette[Fore_color].G*factor + green_under*(255-factor))/255,
 | 
			
		||||
    (Main_palette[Fore_color].B*factor + blue_under*(255-factor))/255);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Check_timer(void)
 | 
			
		||||
{
 | 
			
		||||
  if((SDL_GetTicks()/55)-Timer_delay>Timer_start) Timer_state=1;
 | 
			
		||||
@ -659,17 +679,6 @@ void Rescale(byte *src_buffer, short src_width, short src_height, byte *dst_buff
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Slider_timer(byte speed)
 | 
			
		||||
  //Boucle d'attente pour faire bouger les scrollbars à une vitesse correcte
 | 
			
		||||
{
 | 
			
		||||
  Uint32 end;
 | 
			
		||||
  byte original_mouse_k = Mouse_K;
 | 
			
		||||
  end = SDL_GetTicks() + speed*10;
 | 
			
		||||
  do
 | 
			
		||||
  {
 | 
			
		||||
    if (!Get_input()) SDL_Delay(20);
 | 
			
		||||
  } while (Mouse_K == original_mouse_k && SDL_GetTicks()<end);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Scroll_picture(byte * main_src, byte * main_dest, short x_offset,short y_offset)
 | 
			
		||||
{
 | 
			
		||||
@ -732,13 +741,26 @@ void Zoom_a_line(byte* original_line, byte* zoomed_line,
 | 
			
		||||
  // sysinfo not implemented
 | 
			
		||||
#elif defined(__AROS__) || defined(__amigaos4__) || defined(__MORPHOS__) || defined(__amigaos__)
 | 
			
		||||
  #include <proto/exec.h>
 | 
			
		||||
#elif defined(__MINT__)
 | 
			
		||||
  #include <mint/osbind.h>
 | 
			
		||||
  #include <mint/sysbind.h>
 | 
			
		||||
#elif defined(__SKYOS__)
 | 
			
		||||
  #include <skyos/sysinfo.h>
 | 
			
		||||
#else
 | 
			
		||||
  #include <sys/sysinfo.h> // sysinfo() for free RAM
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
// atari have two kinds of memory
 | 
			
		||||
// standard and fast ram
 | 
			
		||||
void Atari_Memory_free(unsigned long *stRam,unsigned long *ttRam){
 | 
			
		||||
  //TODO: return STRAM/TT-RAM
 | 
			
		||||
  unsigned long mem=0;
 | 
			
		||||
  *stRam=Mxalloc(-1L,0);
 | 
			
		||||
  *ttRam = Mxalloc(-1L,1);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
// Indique quelle est la mémoire disponible
 | 
			
		||||
unsigned long Memory_free(void)
 | 
			
		||||
{
 | 
			
		||||
@ -778,6 +800,8 @@ unsigned long Memory_free(void)
 | 
			
		||||
  return info.freeram*info.mem_unit;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Arrondir un nombre réel à la valeur entière la plus proche
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,7 @@
 | 
			
		||||
#define SWAP_PBYTES(a,b) { byte * c=a; a=b; b=c;}
 | 
			
		||||
 | 
			
		||||
void Copy_image_to_brush(short start_x,short start_y,short Brush_width,short Brush_height,word image_width);
 | 
			
		||||
void Remap_general_lowlevel(byte * conversion_table,byte * buffer,short width,short height,short buffer_width);
 | 
			
		||||
void Remap_general_lowlevel(byte * conversion_table,byte * in_buffer, byte *out_buffer,short width,short height,short buffer_width);
 | 
			
		||||
void Scroll_picture(byte * main_src, byte * main_dest, short x_offset,short y_offset);
 | 
			
		||||
void Wait_end_of_click(void);
 | 
			
		||||
void Set_color(byte color, byte red, byte green, byte blue);
 | 
			
		||||
@ -42,7 +42,6 @@ void Palette_256_to_64(T_Palette palette);
 | 
			
		||||
void Palette_64_to_256(T_Palette palette);
 | 
			
		||||
void Clear_current_image(byte color);
 | 
			
		||||
void Clear_current_image_with_stencil(byte color, byte * stencil);
 | 
			
		||||
void Slider_timer(byte speed);
 | 
			
		||||
dword Round_div(dword numerator,dword divisor);
 | 
			
		||||
word Count_used_colors(dword * usage);
 | 
			
		||||
word Count_used_colors_area(dword* usage, word start_x, word start_y, word width, word height);
 | 
			
		||||
@ -86,6 +85,7 @@ void Replace_colors_within_limits(byte * replace_table);
 | 
			
		||||
byte Effect_interpolated_colorize  (word x,word y,byte color);
 | 
			
		||||
byte Effect_additive_colorize    (word x,word y,byte color);
 | 
			
		||||
byte Effect_substractive_colorize(word x,word y,byte color);
 | 
			
		||||
byte Effect_alpha_colorize(word x,word y,byte color);
 | 
			
		||||
byte Effect_sieve(word x,word y);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2009 Petter Lindquist
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -368,7 +369,8 @@ void Load_PKM(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
          Compteur_de_donnees_packees=0;
 | 
			
		||||
          Compteur_de_pixels=0;
 | 
			
		||||
          Taille_pack=(file_size)-sizeof(T_PKM_Header)-header.Jump;
 | 
			
		||||
          // Header size is 780
 | 
			
		||||
          Taille_pack=(file_size)-780-header.Jump;
 | 
			
		||||
 | 
			
		||||
          // Boucle de décompression:
 | 
			
		||||
          while ( (Compteur_de_pixels<image_size) && (Compteur_de_donnees_packees<Taille_pack) && (!File_error) )
 | 
			
		||||
@ -637,7 +639,6 @@ void Save_PKM(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// CEL ////////////////////////////////////
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  word Width;              // width de l'image
 | 
			
		||||
@ -656,7 +657,6 @@ typedef struct
 | 
			
		||||
  word Y_offset;         // Offset en Y de l'image
 | 
			
		||||
  byte Filler2[16];        // ???
 | 
			
		||||
} T_CEL_Header2;
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
// -- Tester si un fichier est au format CEL --------------------------------
 | 
			
		||||
 | 
			
		||||
@ -689,7 +689,7 @@ void Test_CEL(T_IO_Context * context)
 | 
			
		||||
      //   Vu que ce header n'a pas de signature, il va falloir tester la
 | 
			
		||||
      // cohérence de la dimension de l'image avec celle du fichier.
 | 
			
		||||
      
 | 
			
		||||
      size=file_size-sizeof(T_CEL_Header1);
 | 
			
		||||
      size=file_size-4;
 | 
			
		||||
      if ( (!size) || ( (((header1.Width+1)>>1)*header1.Height)!=size ) )
 | 
			
		||||
      {
 | 
			
		||||
        // Tentative de reconnaissance de la signature des nouveaux fichiers
 | 
			
		||||
@ -735,7 +735,7 @@ void Load_CEL(T_IO_Context * context)
 | 
			
		||||
  short y_pos;
 | 
			
		||||
  byte  last_byte=0;
 | 
			
		||||
  long  file_size;
 | 
			
		||||
  const long int header_size = (long int)(sizeof(header1.Width)+sizeof(header1.Height));
 | 
			
		||||
  const long int header_size = 4;
 | 
			
		||||
 | 
			
		||||
  File_error=0;
 | 
			
		||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
			
		||||
@ -775,7 +775,7 @@ void Load_CEL(T_IO_Context * context)
 | 
			
		||||
        // On réessaye avec le nouveau format
 | 
			
		||||
 | 
			
		||||
        fseek(file,0,SEEK_SET);
 | 
			
		||||
        if (Read_bytes(file,header2.Signature,sizeof(header2.Signature))
 | 
			
		||||
        if (Read_bytes(file,header2.Signature,4)
 | 
			
		||||
        && Read_byte(file,&(header2.Kind))
 | 
			
		||||
        && Read_byte(file,&(header2.Nb_bits))
 | 
			
		||||
        && Read_word_le(file,&(header2.Filler1))
 | 
			
		||||
@ -783,7 +783,7 @@ void Load_CEL(T_IO_Context * context)
 | 
			
		||||
        && Read_word_le(file,&(header2.Height))
 | 
			
		||||
        && Read_word_le(file,&(header2.X_offset))
 | 
			
		||||
        && Read_word_le(file,&(header2.Y_offset))
 | 
			
		||||
        && Read_bytes(file,header2.Filler2,sizeof(header2.Filler2))
 | 
			
		||||
        && Read_bytes(file,header2.Filler2,16)
 | 
			
		||||
        )
 | 
			
		||||
        {
 | 
			
		||||
          // Chargement d'un fichier CEL avec signature (nouveaux fichiers)
 | 
			
		||||
@ -942,7 +942,7 @@ void Save_CEL(T_IO_Context * context)
 | 
			
		||||
      for (x_pos=0;x_pos<16;x_pos++)  // Initialisation du filler 2 (?)
 | 
			
		||||
        header2.Filler2[x_pos]=0;
 | 
			
		||||
 | 
			
		||||
      if (Write_bytes(file,header2.Signature,sizeof(header2.Signature))
 | 
			
		||||
      if (Write_bytes(file,header2.Signature,4)
 | 
			
		||||
      && Write_byte(file,header2.Kind)
 | 
			
		||||
      && Write_byte(file,header2.Nb_bits)
 | 
			
		||||
      && Write_word_le(file,header2.Filler1)
 | 
			
		||||
@ -950,7 +950,7 @@ void Save_CEL(T_IO_Context * context)
 | 
			
		||||
      && Write_word_le(file,header2.Height)
 | 
			
		||||
      && Write_word_le(file,header2.X_offset)
 | 
			
		||||
      && Write_word_le(file,header2.Y_offset)
 | 
			
		||||
      && Write_bytes(file,header2.Filler2,sizeof(header2.Filler2))
 | 
			
		||||
      && Write_bytes(file,header2.Filler2,14)
 | 
			
		||||
      )
 | 
			
		||||
      {
 | 
			
		||||
        // Sauvegarde de l'image
 | 
			
		||||
@ -974,7 +974,6 @@ void Save_CEL(T_IO_Context * context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////// KCF ////////////////////////////////////
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  struct
 | 
			
		||||
@ -986,7 +985,6 @@ typedef struct
 | 
			
		||||
    } color[16];
 | 
			
		||||
  } Palette[10];
 | 
			
		||||
} T_KCF_Header;
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
// -- Tester si un fichier est au format KCF --------------------------------
 | 
			
		||||
 | 
			
		||||
@ -994,7 +992,7 @@ void Test_KCF(T_IO_Context * context)
 | 
			
		||||
{
 | 
			
		||||
  char filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
  FILE *file;
 | 
			
		||||
  T_KCF_Header buffer;
 | 
			
		||||
  T_KCF_Header header1;
 | 
			
		||||
  T_CEL_Header2 header2;
 | 
			
		||||
  int pal_index;
 | 
			
		||||
  int color_index;
 | 
			
		||||
@ -1003,18 +1001,22 @@ void Test_KCF(T_IO_Context * context)
 | 
			
		||||
  Get_full_filename(filename, context->File_name, context->File_directory);
 | 
			
		||||
  if ((file=fopen(filename, "rb")))
 | 
			
		||||
  {
 | 
			
		||||
    if (File_length_file(file)==sizeof(T_KCF_Header))
 | 
			
		||||
    if (File_length_file(file)==320)
 | 
			
		||||
    {
 | 
			
		||||
      Read_bytes(file,&buffer,sizeof(T_KCF_Header));
 | 
			
		||||
      for (pal_index=0;pal_index<10 && !File_error;pal_index++)
 | 
			
		||||
        for (color_index=0;color_index<16 && !File_error;color_index++)
 | 
			
		||||
          if (!Read_byte(file,&header1.Palette[pal_index].color[color_index].Byte1) ||
 | 
			
		||||
              !Read_byte(file,&header1.Palette[pal_index].color[color_index].Byte2))
 | 
			
		||||
            File_error=1;
 | 
			
		||||
      // On vérifie une propriété de la structure de palette:
 | 
			
		||||
      for (pal_index=0;pal_index<10;pal_index++)
 | 
			
		||||
        for (color_index=0;color_index<16;color_index++)
 | 
			
		||||
          if ((buffer.Palette[pal_index].color[color_index].Byte2>>4)!=0)
 | 
			
		||||
          if ((header1.Palette[pal_index].color[color_index].Byte2>>4)!=0)
 | 
			
		||||
            File_error=1;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      if (Read_bytes(file,header2.Signature,sizeof(header2.Signature))
 | 
			
		||||
      if (Read_bytes(file,header2.Signature,4)
 | 
			
		||||
        && Read_byte(file,&(header2.Kind))
 | 
			
		||||
        && Read_byte(file,&(header2.Nb_bits))
 | 
			
		||||
        && Read_word_le(file,&(header2.Filler1))
 | 
			
		||||
@ -1022,7 +1024,7 @@ void Test_KCF(T_IO_Context * context)
 | 
			
		||||
        && Read_word_le(file,&(header2.Height))
 | 
			
		||||
        && Read_word_le(file,&(header2.X_offset))
 | 
			
		||||
        && Read_word_le(file,&(header2.Y_offset))
 | 
			
		||||
        && Read_bytes(file,header2.Filler2,sizeof(header2.Filler2))
 | 
			
		||||
        && Read_bytes(file,header2.Filler2,14)
 | 
			
		||||
        )
 | 
			
		||||
      {
 | 
			
		||||
        if (memcmp(header2.Signature,"KiSS",4)==0)
 | 
			
		||||
@ -1049,7 +1051,7 @@ void Load_KCF(T_IO_Context * context)
 | 
			
		||||
{
 | 
			
		||||
  char filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
  FILE *file;
 | 
			
		||||
  T_KCF_Header buffer;
 | 
			
		||||
  T_KCF_Header header1;
 | 
			
		||||
  T_CEL_Header2 header2;
 | 
			
		||||
  byte bytes[3];
 | 
			
		||||
  int pal_index;
 | 
			
		||||
@ -1063,11 +1065,16 @@ void Load_KCF(T_IO_Context * context)
 | 
			
		||||
  if ((file=fopen(filename, "rb")))
 | 
			
		||||
  {
 | 
			
		||||
    file_size=File_length_file(file);
 | 
			
		||||
    if (file_size==sizeof(T_KCF_Header))
 | 
			
		||||
    if (file_size==320)
 | 
			
		||||
    {
 | 
			
		||||
      // Fichier KCF à l'ancien format
 | 
			
		||||
      for (pal_index=0;pal_index<10 && !File_error;pal_index++)
 | 
			
		||||
        for (color_index=0;color_index<16 && !File_error;color_index++)
 | 
			
		||||
          if (!Read_byte(file,&header1.Palette[pal_index].color[color_index].Byte1) ||
 | 
			
		||||
              !Read_byte(file,&header1.Palette[pal_index].color[color_index].Byte2))
 | 
			
		||||
            File_error=1;
 | 
			
		||||
 | 
			
		||||
      if (Read_bytes(file,&buffer,sizeof(T_KCF_Header)))
 | 
			
		||||
      if (!File_error)
 | 
			
		||||
      {
 | 
			
		||||
        // Pre_load(context, ?); // Pas possible... pas d'image...
 | 
			
		||||
 | 
			
		||||
@ -1079,9 +1086,9 @@ void Load_KCF(T_IO_Context * context)
 | 
			
		||||
          for (color_index=0;color_index<16;color_index++)
 | 
			
		||||
          {
 | 
			
		||||
            index=16+(pal_index*16)+color_index;
 | 
			
		||||
            context->Palette[index].R=((buffer.Palette[pal_index].color[color_index].Byte1 >> 4) << 4);
 | 
			
		||||
            context->Palette[index].B=((buffer.Palette[pal_index].color[color_index].Byte1 & 15) << 4);
 | 
			
		||||
            context->Palette[index].G=((buffer.Palette[pal_index].color[color_index].Byte2 & 15) << 4);
 | 
			
		||||
            context->Palette[index].R=((header1.Palette[pal_index].color[color_index].Byte1 >> 4) << 4);
 | 
			
		||||
            context->Palette[index].B=((header1.Palette[pal_index].color[color_index].Byte1 & 15) << 4);
 | 
			
		||||
            context->Palette[index].G=((header1.Palette[pal_index].color[color_index].Byte2 & 15) << 4);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        for (index=0;index<16;index++)
 | 
			
		||||
@ -1100,7 +1107,7 @@ void Load_KCF(T_IO_Context * context)
 | 
			
		||||
    {
 | 
			
		||||
      // Fichier KCF au nouveau format
 | 
			
		||||
 | 
			
		||||
      if (Read_bytes(file,header2.Signature,sizeof(header2.Signature))
 | 
			
		||||
      if (Read_bytes(file,header2.Signature,4)
 | 
			
		||||
        && Read_byte(file,&(header2.Kind))
 | 
			
		||||
        && Read_byte(file,&(header2.Nb_bits))
 | 
			
		||||
        && Read_word_le(file,&(header2.Filler1))
 | 
			
		||||
@ -1108,7 +1115,7 @@ void Load_KCF(T_IO_Context * context)
 | 
			
		||||
        && Read_word_le(file,&(header2.Height))
 | 
			
		||||
        && Read_word_le(file,&(header2.X_offset))
 | 
			
		||||
        && Read_word_le(file,&(header2.Y_offset))
 | 
			
		||||
        && Read_bytes(file,header2.Filler2,sizeof(header2.Filler2))
 | 
			
		||||
        && Read_bytes(file,header2.Filler2,14)
 | 
			
		||||
        )
 | 
			
		||||
      {
 | 
			
		||||
        // Pre_load(context, ?); // Pas possible... pas d'image...
 | 
			
		||||
@ -1168,7 +1175,7 @@ void Save_KCF(T_IO_Context * context)
 | 
			
		||||
{
 | 
			
		||||
  char filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
  FILE *file;
 | 
			
		||||
  T_KCF_Header buffer;
 | 
			
		||||
  T_KCF_Header header1;
 | 
			
		||||
  T_CEL_Header2 header2;
 | 
			
		||||
  byte bytes[3];
 | 
			
		||||
  int pal_index;
 | 
			
		||||
@ -1196,12 +1203,16 @@ void Save_KCF(T_IO_Context * context)
 | 
			
		||||
        for (color_index=0;color_index<16;color_index++)
 | 
			
		||||
        {
 | 
			
		||||
          index=16+(pal_index*16)+color_index;
 | 
			
		||||
          buffer.Palette[pal_index].color[color_index].Byte1=((context->Palette[index].R>>4)<<4) | (context->Palette[index].B>>4);
 | 
			
		||||
          buffer.Palette[pal_index].color[color_index].Byte2=context->Palette[index].G>>4;
 | 
			
		||||
          header1.Palette[pal_index].color[color_index].Byte1=((context->Palette[index].R>>4)<<4) | (context->Palette[index].B>>4);
 | 
			
		||||
          header1.Palette[pal_index].color[color_index].Byte2=context->Palette[index].G>>4;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (! Write_bytes(file,&buffer,sizeof(T_KCF_Header)))
 | 
			
		||||
        File_error=1;
 | 
			
		||||
      // Write all
 | 
			
		||||
      for (pal_index=0;pal_index<10 && !File_error;pal_index++)
 | 
			
		||||
        for (color_index=0;color_index<16 && !File_error;color_index++)
 | 
			
		||||
          if (!Write_byte(file,header1.Palette[pal_index].color[color_index].Byte1) ||
 | 
			
		||||
              !Write_byte(file,header1.Palette[pal_index].color[color_index].Byte2))
 | 
			
		||||
            File_error=1;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
@ -1218,7 +1229,7 @@ void Save_KCF(T_IO_Context * context)
 | 
			
		||||
      for (index=0;index<16;index++) // Initialisation du filler 2 (?)
 | 
			
		||||
        header2.Filler2[index]=0;
 | 
			
		||||
 | 
			
		||||
      if (!Write_bytes(file,header2.Signature,sizeof(header2.Signature))
 | 
			
		||||
      if (!Write_bytes(file,header2.Signature,4)
 | 
			
		||||
      || !Write_byte(file,header2.Kind)
 | 
			
		||||
      || !Write_byte(file,header2.Nb_bits)
 | 
			
		||||
      || !Write_word_le(file,header2.Filler1)
 | 
			
		||||
@ -1226,7 +1237,7 @@ void Save_KCF(T_IO_Context * context)
 | 
			
		||||
      || !Write_word_le(file,header2.Height)
 | 
			
		||||
      || !Write_word_le(file,header2.X_offset)
 | 
			
		||||
      || !Write_word_le(file,header2.Y_offset)
 | 
			
		||||
      || !Write_bytes(file,header2.Filler2,sizeof(header2.Filler2))
 | 
			
		||||
      || !Write_bytes(file,header2.Filler2,14)
 | 
			
		||||
      )
 | 
			
		||||
        File_error=1;
 | 
			
		||||
 | 
			
		||||
@ -1322,17 +1333,29 @@ void PI1_decode_palette(byte * src,byte * palette)
 | 
			
		||||
  //    Low        High
 | 
			
		||||
  // VVVV RRRR | 0000 BBBB
 | 
			
		||||
  // 0321 0321 |      0321
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  ip=0;
 | 
			
		||||
  for (i=0;i<16;i++)
 | 
			
		||||
  {
 | 
			
		||||
    w=((word)src[(i*2)+1]<<8) | src[(i*2)+0];
 | 
			
		||||
 | 
			
		||||
    // Traitement des couleurs rouge, verte et bleue:
 | 
			
		||||
    palette[ip++]=(((w & 0x0007) <<  1) | ((w & 0x0008) >>  3)) << 4;
 | 
			
		||||
    palette[ip++]=(((w & 0x7000) >> 11) | ((w & 0x8000) >> 15)) << 4;
 | 
			
		||||
    palette[ip++]=(((w & 0x0700) >>  7) | ((w & 0x0800) >> 11)) << 4;
 | 
			
		||||
  }
 | 
			
		||||
    #if SDL_BYTEORDER == SDL_LIL_ENDIAN 
 | 
			
		||||
   
 | 
			
		||||
      w=(((word)src[(i*2)+1]<<8) | (src[(i*2)+0]));
 | 
			
		||||
    
 | 
			
		||||
      // Traitement des couleurs rouge, verte et bleue:
 | 
			
		||||
      palette[ip++]=(((w & 0x0007) <<  1) | ((w & 0x0008) >>  3)) << 4;
 | 
			
		||||
      palette[ip++]=(((w & 0x7000) >> 11) | ((w & 0x8000) >> 15)) << 4;
 | 
			
		||||
      palette[ip++]=(((w & 0x0700) >>  7) | ((w & 0x0800) >> 11)) << 4;
 | 
			
		||||
   
 | 
			
		||||
    #else
 | 
			
		||||
      w=(((word)src[(i*2+1)])|(((word)src[(i*2)])<<8));
 | 
			
		||||
    
 | 
			
		||||
      palette[ip++] = (((w & 0x0700)>>7) | ((w & 0x0800) >> 7))<<4 ;
 | 
			
		||||
      palette[ip++]=(((w & 0x0070)>>3) | ((w & 0x0080) >> 3))<<4 ;
 | 
			
		||||
      palette[ip++] = (((w & 0x0007)<<1) | ((w & 0x0008)))<<4 ;
 | 
			
		||||
    #endif
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
  } 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// CODAGE de la PALETTE ////
 | 
			
		||||
@ -1345,20 +1368,31 @@ void PI1_code_palette(byte * palette,byte * dest)
 | 
			
		||||
 | 
			
		||||
  // Schéma d'un word =
 | 
			
		||||
  //
 | 
			
		||||
  //    Low        High
 | 
			
		||||
  // Low        High
 | 
			
		||||
  // VVVV RRRR | 0000 BBBB
 | 
			
		||||
  // 0321 0321 |      0321
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
  ip=0;
 | 
			
		||||
  for (i=0;i<16;i++)
 | 
			
		||||
  {
 | 
			
		||||
    #if SDL_BYTEORDER == SDL_LIL_ENDIAN
 | 
			
		||||
   
 | 
			
		||||
    // Traitement des couleurs rouge, verte et bleue:
 | 
			
		||||
    w =(((word)(palette[ip]>>2) & 0x38) >> 3) | (((word)(palette[ip]>>2) & 0x04) <<  1); ip++;
 | 
			
		||||
    w|=(((word)(palette[ip]>>2) & 0x38) << 9) | (((word)(palette[ip]>>2) & 0x04) << 13); ip++;
 | 
			
		||||
    w|=(((word)(palette[ip]>>2) & 0x38) << 5) | (((word)(palette[ip]>>2) & 0x04) <<  9); ip++;
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    dest[(i*2)+0]=w & 0x00FF;
 | 
			
		||||
    dest[(i*2)+1]=(w>>8);
 | 
			
		||||
    #else
 | 
			
		||||
   
 | 
			
		||||
     w=(((word)(palette[ip]<<3))&0x0700);ip++;
 | 
			
		||||
     w|=(((word)(palette[ip]>>1))&0x0070);ip++;
 | 
			
		||||
     w|=(((word)(palette[ip]>>5))&0x0007);ip++;
 | 
			
		||||
 
 | 
			
		||||
    dest[(i*2)+1]=w & 0x00FF;
 | 
			
		||||
    dest[(i*2)+0]=(w>>8);
 | 
			
		||||
    #endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2472,13 +2506,13 @@ int Save_C64_window(byte *saveWhat, byte *loadAddr)
 | 
			
		||||
    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); // 3
 | 
			
		||||
    Window_dropdown_clear_items(what);
 | 
			
		||||
    for (i=0; i<sizeof(what_label)/sizeof(char *); i++)
 | 
			
		||||
    for (i=0; i<sizeof(what_label)/sizeof(what_label[0]); i++)
 | 
			
		||||
        Window_dropdown_add_item(what,i,what_label[i]);
 | 
			
		||||
    
 | 
			
		||||
    Print_in_window(113,18,"Address:",MC_Dark,MC_Light);
 | 
			
		||||
    addr=Window_set_dropdown_button(110,28,70,15,70,address_label[*loadAddr/32],1, 0, 1, LEFT_SIDE,0); // 4
 | 
			
		||||
    Window_dropdown_clear_items(addr);
 | 
			
		||||
    for (i=0; i<sizeof(address_label)/sizeof(char *); i++)
 | 
			
		||||
    for (i=0; i<sizeof(address_label)/sizeof(address_label[0]); i++)
 | 
			
		||||
        Window_dropdown_add_item(addr,i,address_label[i]); 
 | 
			
		||||
    
 | 
			
		||||
    Update_window_area(0,0,Window_width,Window_height); 
 | 
			
		||||
 | 
			
		||||
@ -336,12 +336,12 @@ fstype_to_string (int t)
 | 
			
		||||
  #define BROKEN
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2
 | 
			
		||||
 | 
			
		||||
/* Return the device number from MOUNT_OPTIONS, if possible.
 | 
			
		||||
   Otherwise return (dev_t) -1.  */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static dev_t
 | 
			
		||||
dev_from_mount_options (BROKEN char const *mount_options)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										46
									
								
								src/op_c.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/op_c.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2010 Alexander Filyanov
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
 | 
			
		||||
@ -30,6 +31,8 @@
 | 
			
		||||
#include "op_c.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
 | 
			
		||||
int Convert_24b_bitmap_to_256_fast(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette);
 | 
			
		||||
 | 
			
		||||
/// 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)
 | 
			
		||||
@ -165,6 +168,16 @@ void HSL_to_RGB(byte h,byte s,byte l, byte* r, byte* g, byte* b)
 | 
			
		||||
    *b = bf * (255);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Returns a value that is high when color is near white,
 | 
			
		||||
/// and low when it's darker. Used for sorting.
 | 
			
		||||
long Perceptual_lightness(T_Components *color)
 | 
			
		||||
{
 | 
			
		||||
  return 26*color->R*26*color->R +
 | 
			
		||||
         55*color->G*55*color->G +
 | 
			
		||||
         19*color->B*19*color->B;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
@ -1342,6 +1355,10 @@ static const byte precision_24b[]=
 | 
			
		||||
// 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)
 | 
			
		||||
{
 | 
			
		||||
  #if defined(__GP2X__) || defined(__gp2x__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
  return Convert_24b_bitmap_to_256_fast(dest, source, width, height, palette);  
 | 
			
		||||
 | 
			
		||||
  #else
 | 
			
		||||
  T_Conversion_table * table; // table de conversion
 | 
			
		||||
  int                ip;    // index de précision pour la conversion
 | 
			
		||||
 | 
			
		||||
@ -1363,7 +1380,36 @@ int Convert_24b_bitmap_to_256(T_Bitmap256 dest,T_Bitmap24B source,int width,int
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
    return 1;
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//Really small, fast and ugly converter(just for handhelds)
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "limits.h"
 | 
			
		||||
#include "engine.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
 | 
			
		||||
extern void Set_palette_fake_24b(T_Palette palette);
 | 
			
		||||
 | 
			
		||||
/// Really small, fast and dirty convertor(just for handhelds)
 | 
			
		||||
int Convert_24b_bitmap_to_256_fast(T_Bitmap256 dest,T_Bitmap24B source,int width,int height,T_Components * palette)
 | 
			
		||||
{
 | 
			
		||||
  int size;
 | 
			
		||||
 | 
			
		||||
  Set_palette_fake_24b(palette);
 | 
			
		||||
 | 
			
		||||
  size = width*height;
 | 
			
		||||
 | 
			
		||||
  while(size--)
 | 
			
		||||
  {
 | 
			
		||||
    //Set palette color index to destination bitmap
 | 
			
		||||
    *dest = ((source->R >> 5) << 5) |
 | 
			
		||||
            ((source->G >> 5) << 2) |
 | 
			
		||||
            ((source->B >> 6));
 | 
			
		||||
    source++;
 | 
			
		||||
    dest++;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -160,6 +160,7 @@ void CT_set(T_Conversion_table * t,int r,int g,int b,byte i);
 | 
			
		||||
void RGB_to_HSL(int r, int g,int b, byte* h, byte*s, byte* l);
 | 
			
		||||
void HSL_to_RGB(byte h, byte s, byte l, byte* r, byte* g, byte* b);
 | 
			
		||||
 | 
			
		||||
long Perceptual_lightness(T_Components *color);
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
/////////////////////////////// Méthodes de gestion des tables d'occurence //
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										197
									
								
								src/operatio.c
									
									
									
									
									
								
							
							
						
						
									
										197
									
								
								src/operatio.c
									
									
									
									
									
								
							@ -36,6 +36,7 @@
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "brush.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
 | 
			
		||||
// PI is NOT part of math.h according to C standards...
 | 
			
		||||
#if defined(__GP2X__) || defined(__VBCC__)
 | 
			
		||||
@ -53,11 +54,12 @@ void Start_operation_stack(word new_operation)
 | 
			
		||||
  // On mémorise l'opération précédente si on démarre une interruption
 | 
			
		||||
  switch(new_operation)
 | 
			
		||||
  {
 | 
			
		||||
    case OPERATION_MAGNIFY         :
 | 
			
		||||
    case OPERATION_COLORPICK       :
 | 
			
		||||
    case OPERATION_GRAB_BRUSH  :
 | 
			
		||||
    case OPERATION_POLYBRUSH    :
 | 
			
		||||
    case OPERATION_STRETCH_BRUSH :
 | 
			
		||||
    case OPERATION_MAGNIFY:
 | 
			
		||||
    case OPERATION_COLORPICK:
 | 
			
		||||
    case OPERATION_RMB_COLORPICK:
 | 
			
		||||
    case OPERATION_GRAB_BRUSH:
 | 
			
		||||
    case OPERATION_POLYBRUSH:
 | 
			
		||||
    case OPERATION_STRETCH_BRUSH:
 | 
			
		||||
    case OPERATION_ROTATE_BRUSH:
 | 
			
		||||
      Operation_before_interrupt=Current_operation;
 | 
			
		||||
      // On passe à l'operation demandée
 | 
			
		||||
@ -226,6 +228,9 @@ void Freehand_mode1_2_0(void)
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_right;
 | 
			
		||||
@ -322,6 +327,9 @@ void Freehand_mode2_2_0(void)
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_right;
 | 
			
		||||
@ -390,6 +398,9 @@ void Freehand_Mode3_2_0(void)
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_right;
 | 
			
		||||
@ -422,6 +433,9 @@ void Line_12_0(void)
 | 
			
		||||
 | 
			
		||||
//  Début du tracé d'une ligne (premier clic)
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Paintbrush_shape_before_operation=Paintbrush_shape;
 | 
			
		||||
@ -480,9 +494,7 @@ void Line_12_5(void)
 | 
			
		||||
 | 
			
		||||
  // On corrige les coordonnées de la ligne si la touche shift est appuyée...
 | 
			
		||||
  if(SDL_GetModState() & KMOD_SHIFT)
 | 
			
		||||
  {
 | 
			
		||||
    Clamp_coordinates_regular_angle(start_x,start_y,&cursor_x,&cursor_y);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // On vient de bouger
 | 
			
		||||
  if ((cursor_x!=end_x) || (cursor_y!=end_y))
 | 
			
		||||
@ -557,11 +569,11 @@ void Line_0_5(void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////// OPERATION_K_LIGNE
 | 
			
		||||
/////////////////////////////////////////////////////////// OPERATION_K_LINE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void K_line_12_0(void)
 | 
			
		||||
// Opération   : OPERATION_K_LIGNE
 | 
			
		||||
// Opération   : OPERATION_K_LINE
 | 
			
		||||
// Click Souris: 1 ou 2
 | 
			
		||||
// Taille_Pile : 0
 | 
			
		||||
//
 | 
			
		||||
@ -569,6 +581,9 @@ void K_line_12_0(void)
 | 
			
		||||
{
 | 
			
		||||
  byte color;
 | 
			
		||||
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
@ -594,7 +609,7 @@ void K_line_12_0(void)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void K_line_12_6(void)
 | 
			
		||||
// Opération   : OPERATION_K_LIGNE
 | 
			
		||||
// Opération   : OPERATION_K_LINE
 | 
			
		||||
// Click Souris: 1 ou 2 | 0
 | 
			
		||||
// Taille_Pile : 6      | 7
 | 
			
		||||
//
 | 
			
		||||
@ -634,7 +649,7 @@ void K_line_12_6(void)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void K_line_0_6(void)
 | 
			
		||||
// Opération   : OPERATION_K_LIGNE
 | 
			
		||||
// Opération   : OPERATION_K_LINE
 | 
			
		||||
// Click Souris: 0
 | 
			
		||||
// Taille_Pile : 6
 | 
			
		||||
//
 | 
			
		||||
@ -684,7 +699,7 @@ void K_line_0_6(void)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void K_line_12_7(void)
 | 
			
		||||
// Opération   : OPERATION_K_LIGNE
 | 
			
		||||
// Opération   : OPERATION_K_LINE
 | 
			
		||||
// Click Souris: 1 ou 2
 | 
			
		||||
// Taille_Pile : 7
 | 
			
		||||
//
 | 
			
		||||
@ -745,6 +760,9 @@ void Rectangle_12_0(void)
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
 | 
			
		||||
  if ((Config.Coords_rel) && (Menu_is_visible))
 | 
			
		||||
@ -916,6 +934,9 @@ void Circle_12_0(void)
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
 | 
			
		||||
@ -1090,6 +1111,9 @@ void Ellipse_12_0(void)
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
 | 
			
		||||
@ -1284,9 +1308,12 @@ void Fill_2_0(void)
 | 
			
		||||
// Click Souris: 2
 | 
			
		||||
// Taille_Pile : 0
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Oui
 | 
			
		||||
// Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(1))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
  // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas
 | 
			
		||||
  // le Fill, et on se fout de savoir si on est dans la partie gauche ou
 | 
			
		||||
@ -1309,7 +1336,7 @@ void Replace_1_0(void)
 | 
			
		||||
// Click Souris: 1
 | 
			
		||||
// Taille_Pile : 0
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Oui
 | 
			
		||||
// Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
@ -1331,9 +1358,12 @@ void Replace_2_0(void)
 | 
			
		||||
// Click Souris: 2
 | 
			
		||||
// Taille_Pile : 0
 | 
			
		||||
//
 | 
			
		||||
// Souris effacée: Oui
 | 
			
		||||
// Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(1))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
  // Pas besoin d'initialiser le début d'opération car le Smear n'affecte pas
 | 
			
		||||
  // le Replace, et on se fout de savoir si on est dans la partie gauche ou
 | 
			
		||||
@ -1433,6 +1463,9 @@ void Curve_34_points_2_0(void)
 | 
			
		||||
//  Souris effacée: Oui
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_right;
 | 
			
		||||
@ -1711,17 +1744,17 @@ void Compute_3_point_curve(short x1, short y1, short x4, short y4,
 | 
			
		||||
  float cx,cy; // Centre de (x1,y1) et (x4,y4)
 | 
			
		||||
  float bx,by; // Intersect. des dtes ((x1,y1),(x2,y2)) et ((x3,y3),(x4,y4))
 | 
			
		||||
 | 
			
		||||
  cx=(float)(x1+x4)/2.0;           // P1*--_               Légende:
 | 
			
		||||
  cy=(float)(y1+y4)/2.0;           //   ·   \·· P2         -_\|/ : courbe
 | 
			
		||||
                                   //   ·    \ ·*·         * : point important
 | 
			
		||||
  bx=cx+((8.0/3.0)*(Paintbrush_X-cx));//   ·     |   ··       · : pointillÚ
 | 
			
		||||
  cx=(float)(x1+x4)/2.0;              // P1*--_               Legend:
 | 
			
		||||
  cy=(float)(y1+y4)/2.0;              //   ·   \·· P2         -_\|/ : curve
 | 
			
		||||
                                      //   ·    \ ·*·         * : important point
 | 
			
		||||
  bx=cx+((8.0/3.0)*(Paintbrush_X-cx));//   ·     |   ··       · : dotted line
 | 
			
		||||
  by=cy+((8.0/3.0)*(Paintbrush_Y-cy));//   ·     |P    ··  B
 | 
			
		||||
                                   // C *·····*·········*  P=Pos. du pinceau
 | 
			
		||||
  *x2=Round((bx+x1)/2.0);          //   ·     |     ··     C=milieu de [P1,P4]
 | 
			
		||||
  *y2=Round((by+y1)/2.0);          //   ·     |   ··       B=point tel que
 | 
			
		||||
                                   //   ·    / ·*·         C->B=(8/3) * C->P
 | 
			
		||||
  *x3=Round((bx+x4)/2.0);          //   ·  _/·· P3         P2=milieu de [P1,B]
 | 
			
		||||
  *y3=Round((by+y4)/2.0);          // P4*--                P3=milieu de [P4,B]
 | 
			
		||||
                                      // C *·····*·········*  P=Pencil position
 | 
			
		||||
  *x2=Round((bx+x1)/2.0);             //   ·     |     ··     C=middle of [P1,P4]
 | 
			
		||||
  *y2=Round((by+y1)/2.0);             //   ·     |   ··       B=point computed as
 | 
			
		||||
                                      //   ·    / ·*·         C->B=(8/3) * C->P
 | 
			
		||||
  *x3=Round((bx+x4)/2.0);             //   ·  _/·· P3         P2=middle of [P1,B]
 | 
			
		||||
  *y3=Round((by+y4)/2.0);             // P4*--                P3=middle of [P4,B]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1745,8 +1778,11 @@ void Curve_3_points_0_5(void)
 | 
			
		||||
 | 
			
		||||
  Compute_3_point_curve(x1,y1,x4,y4,&x2,&y2,&x3,&y3);
 | 
			
		||||
 | 
			
		||||
  Hide_line_preview(x1,y1,x4,y4);
 | 
			
		||||
  Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
 | 
			
		||||
  if (!Config.Stylus_mode)
 | 
			
		||||
  {
 | 
			
		||||
    Hide_line_preview(x1,y1,x4,y4);
 | 
			
		||||
    Draw_curve_preview(x1,y1,x2,y2,x3,y3,x4,y4,color);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ( (Config.Coords_rel) && (Menu_is_visible) )
 | 
			
		||||
  {
 | 
			
		||||
@ -1765,17 +1801,19 @@ void Curve_3_points_0_5(void)
 | 
			
		||||
  Operation_push(y4);
 | 
			
		||||
  Operation_push(Paintbrush_X);
 | 
			
		||||
  Operation_push(Paintbrush_Y);
 | 
			
		||||
  
 | 
			
		||||
  if (Config.Stylus_mode)
 | 
			
		||||
  {
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    while(!Mouse_K)
 | 
			
		||||
      Get_input(20);
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
    
 | 
			
		||||
    Hide_line_preview(x1,y1,x4,y4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Curve_3_points_0_11(void)
 | 
			
		||||
//
 | 
			
		||||
//  Opération   : OPERATION_3_POINTS_CURVE
 | 
			
		||||
//  Click Souris: 0
 | 
			
		||||
//  Taille_Pile : 11
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
void Curve_drag(void)
 | 
			
		||||
{
 | 
			
		||||
  short x1,y1,x2,y2,x3,y3,x4,y4;
 | 
			
		||||
  short old_x,old_y;
 | 
			
		||||
@ -1817,16 +1855,7 @@ void Curve_3_points_0_11(void)
 | 
			
		||||
  Operation_push(Paintbrush_X);
 | 
			
		||||
  Operation_push(Paintbrush_Y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Curve_3_points_12_11(void)
 | 
			
		||||
//
 | 
			
		||||
//  Opération   : OPERATION_3_POINTS_CURVE
 | 
			
		||||
//  Click Souris: 1 ou 2
 | 
			
		||||
//  Taille_Pile : 11
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Oui
 | 
			
		||||
//
 | 
			
		||||
void Curve_finalize(void)
 | 
			
		||||
{
 | 
			
		||||
  short x1,y1,x2,y2,x3,y3,x4,y4;
 | 
			
		||||
  short old_x,old_y;
 | 
			
		||||
@ -1857,6 +1886,37 @@ void Curve_3_points_12_11(void)
 | 
			
		||||
  Wait_end_of_click();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Curve_3_points_0_11(void)
 | 
			
		||||
//
 | 
			
		||||
//  Opération   : OPERATION_3_POINTS_CURVE
 | 
			
		||||
//  Click Souris: 0
 | 
			
		||||
//  Taille_Pile : 11
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  if (!Config.Stylus_mode)
 | 
			
		||||
    Curve_drag();
 | 
			
		||||
  else
 | 
			
		||||
    Curve_finalize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void Curve_3_points_12_11(void)
 | 
			
		||||
//
 | 
			
		||||
//  Opération   : OPERATION_3_POINTS_CURVE
 | 
			
		||||
//  Click Souris: 1 ou 2
 | 
			
		||||
//  Taille_Pile : 11
 | 
			
		||||
//
 | 
			
		||||
//  Souris effacée: Oui
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  if (!Config.Stylus_mode)
 | 
			
		||||
    Curve_finalize();
 | 
			
		||||
  else
 | 
			
		||||
    Curve_drag();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////// OPERATION_AIRBRUSH
 | 
			
		||||
 | 
			
		||||
@ -1873,8 +1933,11 @@ void Airbrush_1_0(void)
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_left;
 | 
			
		||||
 | 
			
		||||
  Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
 | 
			
		||||
  Airbrush(LEFT_SIDE);
 | 
			
		||||
  if (SDL_GetTicks()>Airbrush_next_time)
 | 
			
		||||
  {
 | 
			
		||||
    Airbrush(LEFT_SIDE);
 | 
			
		||||
    Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Operation_push(Paintbrush_X);
 | 
			
		||||
  Operation_push(Paintbrush_Y);
 | 
			
		||||
@ -1889,11 +1952,17 @@ void Airbrush_2_0(void)
 | 
			
		||||
//  Souris effacée: Non
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  if (Rightclick_colorpick(1))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=Shade_table_right;
 | 
			
		||||
  Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
 | 
			
		||||
  Airbrush(RIGHT_SIDE);
 | 
			
		||||
  if (SDL_GetTicks()>Airbrush_next_time)
 | 
			
		||||
  {
 | 
			
		||||
    Airbrush(RIGHT_SIDE);
 | 
			
		||||
    Airbrush_next_time = SDL_GetTicks()+Airbrush_delay*10;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Operation_push(Paintbrush_X);
 | 
			
		||||
  Operation_push(Paintbrush_Y);
 | 
			
		||||
@ -1909,6 +1978,7 @@ void Airbrush_12_2(void)
 | 
			
		||||
//
 | 
			
		||||
{
 | 
			
		||||
  short old_x,old_y;
 | 
			
		||||
  Uint32 now;
 | 
			
		||||
 | 
			
		||||
  Operation_pop(&old_y);
 | 
			
		||||
  Operation_pop(&old_x);
 | 
			
		||||
@ -1920,9 +1990,13 @@ void Airbrush_12_2(void)
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (SDL_GetTicks()>Airbrush_next_time)
 | 
			
		||||
  now=SDL_GetTicks();
 | 
			
		||||
  if (now>Airbrush_next_time)
 | 
			
		||||
  {
 | 
			
		||||
    Airbrush_next_time+=Airbrush_delay*10;
 | 
			
		||||
    //Airbrush_next_time+=Airbrush_delay*10;
 | 
			
		||||
    // Time is now reset, because the += was death spiral
 | 
			
		||||
    // if drawing took more time than the frequency.
 | 
			
		||||
    Airbrush_next_time=now+Airbrush_delay*10;    
 | 
			
		||||
    Airbrush(Mouse_K_unique);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1956,6 +2030,9 @@ void Polygon_12_0(void)
 | 
			
		||||
{
 | 
			
		||||
  byte color;
 | 
			
		||||
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
@ -2057,6 +2134,9 @@ void Polyfill_12_0(void)
 | 
			
		||||
{
 | 
			
		||||
  byte color;
 | 
			
		||||
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
@ -2255,6 +2335,9 @@ void Polyform_12_0(void)
 | 
			
		||||
{
 | 
			
		||||
  short color;
 | 
			
		||||
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
@ -2413,6 +2496,9 @@ void Filled_polyform_12_0(void)
 | 
			
		||||
{
 | 
			
		||||
  short color;
 | 
			
		||||
 | 
			
		||||
  if (Rightclick_colorpick(0))
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
 | 
			
		||||
  // Cette opération étant également utilisée pour le lasso, on ne fait pas de
 | 
			
		||||
@ -2825,6 +2911,7 @@ void Grad_circle_12_0(void)
 | 
			
		||||
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Load_gradient_data(Current_gradient);
 | 
			
		||||
 | 
			
		||||
  Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
  color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
 | 
			
		||||
@ -3082,6 +3169,8 @@ void Grad_ellipse_12_0(void)
 | 
			
		||||
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Load_gradient_data(Current_gradient);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
  color=(Mouse_K==LEFT_SIDE)?Fore_color:Back_color;
 | 
			
		||||
@ -3306,6 +3395,7 @@ void Grad_rectangle_12_0(void)
 | 
			
		||||
{
 | 
			
		||||
  Init_start_operation();
 | 
			
		||||
  Backup();
 | 
			
		||||
  Load_gradient_data(Current_gradient);
 | 
			
		||||
 | 
			
		||||
  if ((Config.Coords_rel) && (Menu_is_visible))
 | 
			
		||||
    Print_in_menu("\035:   1   \022:   1",0);
 | 
			
		||||
@ -3712,6 +3802,9 @@ void Centered_lines_12_0(void)
 | 
			
		||||
    //
 | 
			
		||||
    //  Souris effacée: Oui
 | 
			
		||||
{
 | 
			
		||||
    if (Rightclick_colorpick(0))
 | 
			
		||||
      return;
 | 
			
		||||
    
 | 
			
		||||
    Init_start_operation();
 | 
			
		||||
    Backup();
 | 
			
		||||
    Shade_table=(Mouse_K==LEFT_SIDE)?Shade_table_left:Shade_table_right;
 | 
			
		||||
 | 
			
		||||
@ -225,3 +225,8 @@ void Centered_lines_0_3(void);
 | 
			
		||||
void Centered_lines_12_7(void);
 | 
			
		||||
void Centered_lines_0_7(void);
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////// OPERATION_RMB_COLORPICK
 | 
			
		||||
 | 
			
		||||
byte Rightclick_colorpick(byte cursor_visible);
 | 
			
		||||
void Rightclick_colorpick_2_1(void);
 | 
			
		||||
void Rightclick_colorpick_0_1(void);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										234
									
								
								src/pages.c
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								src/pages.c
									
									
									
									
									
								
							@ -75,6 +75,7 @@ T_Page * New_page(byte nb_layers)
 | 
			
		||||
    page->Filename[0]='\0';
 | 
			
		||||
    page->File_format=DEFAULT_FILEFORMAT;
 | 
			
		||||
    page->Nb_layers=nb_layers;
 | 
			
		||||
    page->Gradients=NULL;
 | 
			
		||||
    page->Transparent_color=0; // Default transparent color
 | 
			
		||||
    page->Background_transparent=0;
 | 
			
		||||
    page->Next = page->Prev = NULL;
 | 
			
		||||
@ -141,6 +142,24 @@ byte * Dup_layer(byte * layer)
 | 
			
		||||
 | 
			
		||||
// ==============================================================
 | 
			
		||||
 | 
			
		||||
/// Adds a shared reference to the gradient data of another page. Pass NULL for new.
 | 
			
		||||
T_Gradient_array *Dup_gradient(T_Page * page)
 | 
			
		||||
{
 | 
			
		||||
  // new
 | 
			
		||||
  if (page==NULL || page->Gradients==NULL)
 | 
			
		||||
  {
 | 
			
		||||
    T_Gradient_array *array;
 | 
			
		||||
    array=(T_Gradient_array *)calloc(1, sizeof(T_Gradient_array));
 | 
			
		||||
    if (!array)
 | 
			
		||||
      return NULL;
 | 
			
		||||
    array->Used=1;
 | 
			
		||||
    return array;
 | 
			
		||||
  }
 | 
			
		||||
  // shared
 | 
			
		||||
  page->Gradients->Used++;
 | 
			
		||||
  return page->Gradients;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Download_infos_page_main(T_Page * page)
 | 
			
		||||
// Affiche la page à l'écran
 | 
			
		||||
{
 | 
			
		||||
@ -418,6 +437,16 @@ void Clear_page(T_Page * page)
 | 
			
		||||
    Free_layer(page, i);
 | 
			
		||||
    page->Image[i]=NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Free_gradient() : This data is reference-counted
 | 
			
		||||
  if (page->Gradients)
 | 
			
		||||
  {
 | 
			
		||||
    page->Gradients->Used--;
 | 
			
		||||
    if (page->Gradients->Used==0)
 | 
			
		||||
      free(page->Gradients);
 | 
			
		||||
    page->Gradients=NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  page->Width=0;
 | 
			
		||||
  page->Height=0;
 | 
			
		||||
  // On ne se préoccupe pas de ce que deviens le reste des infos de l'image.
 | 
			
		||||
@ -426,6 +455,7 @@ void Clear_page(T_Page * page)
 | 
			
		||||
void Copy_S_page(T_Page * dest,T_Page * source)
 | 
			
		||||
{
 | 
			
		||||
  *dest=*source;
 | 
			
		||||
  dest->Gradients=NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -460,6 +490,10 @@ int Allocate_list_of_pages(T_List_of_pages * list)
 | 
			
		||||
 | 
			
		||||
  list->List_size=1;
 | 
			
		||||
 | 
			
		||||
  page->Gradients=Dup_gradient(NULL);
 | 
			
		||||
  if (!page->Gradients)
 | 
			
		||||
    return 0;
 | 
			
		||||
  
 | 
			
		||||
  return 1; // Succès
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -799,19 +833,10 @@ void Set_number_of_backups(int nb_backups)
 | 
			
		||||
  // (nb_backups = Nombre de backups, sans compter les pages courantes)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
 | 
			
		||||
int Backup_new_image(byte layers,int width,int height)
 | 
			
		||||
{
 | 
			
		||||
  // Retourne 1 si une nouvelle page est disponible (alors pleine de 0) et
 | 
			
		||||
  // 0 sinon.
 | 
			
		||||
 | 
			
		||||
  T_Page * new_page;
 | 
			
		||||
  int return_code=0;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (upload)
 | 
			
		||||
    // On remet à jour l'état des infos de la page courante (pour pouvoir les
 | 
			
		||||
    // retrouver plus tard)
 | 
			
		||||
    Upload_infos_page_main(Main_backups->Pages);
 | 
			
		||||
  // Retourne 1 si une nouvelle page est disponible et 0 sinon
 | 
			
		||||
  T_Page * new_page;  
 | 
			
		||||
 | 
			
		||||
  // On crée un descripteur pour la nouvelle page courante
 | 
			
		||||
  new_page=New_page(layers);
 | 
			
		||||
@ -820,36 +845,161 @@ int Backup_with_new_dimensions(int upload,byte layers,int width,int height)
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  Upload_infos_page_main(new_page);
 | 
			
		||||
  new_page->Width=width;
 | 
			
		||||
  new_page->Height=height;
 | 
			
		||||
  strcpy(new_page->Filename, Main_backups->Pages->Filename);
 | 
			
		||||
  strcpy(new_page->File_directory, Main_backups->Pages->File_directory);
 | 
			
		||||
  if (Create_new_page(new_page,Main_backups,0xFFFFFFFF))
 | 
			
		||||
  new_page->Transparent_color=0;
 | 
			
		||||
  new_page->Gradients=Dup_gradient(NULL);
 | 
			
		||||
  if (!Create_new_page(new_page,Main_backups,0xFFFFFFFF))
 | 
			
		||||
  {
 | 
			
		||||
    for (i=0; i<layers;i++)
 | 
			
		||||
    {
 | 
			
		||||
      memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Update_buffers(width, height);
 | 
			
		||||
 | 
			
		||||
    Download_infos_page_main(Main_backups->Pages);
 | 
			
		||||
    
 | 
			
		||||
    // Same code as in End_of_modification():
 | 
			
		||||
    #ifndef NOLAYERS
 | 
			
		||||
      memcpy(Main_visible_image_backup.Image,
 | 
			
		||||
             Main_visible_image.Image,
 | 
			
		||||
             Main_image_width*Main_image_height);
 | 
			
		||||
    #else
 | 
			
		||||
      Update_screen_targets();
 | 
			
		||||
    #endif
 | 
			
		||||
    Update_FX_feedback(Config.FX_Feedback);
 | 
			
		||||
    // --
 | 
			
		||||
    
 | 
			
		||||
    return_code=1;
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  return return_code;
 | 
			
		||||
  
 | 
			
		||||
  Update_buffers(width, height);
 | 
			
		||||
  
 | 
			
		||||
  Download_infos_page_main(Main_backups->Pages);
 | 
			
		||||
  
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int Backup_with_new_dimensions(int width,int height)
 | 
			
		||||
{
 | 
			
		||||
  // Retourne 1 si une nouvelle page est disponible (alors pleine de 0) et
 | 
			
		||||
  // 0 sinon.
 | 
			
		||||
 | 
			
		||||
  T_Page * new_page;  
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  // On crée un descripteur pour la nouvelle page courante
 | 
			
		||||
  new_page=New_page(Main_backups->Pages->Nb_layers);
 | 
			
		||||
  if (!new_page)
 | 
			
		||||
  {
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  new_page->Width=width;
 | 
			
		||||
  new_page->Height=height;
 | 
			
		||||
  new_page->Transparent_color=0;
 | 
			
		||||
  if (!Create_new_page(new_page,Main_backups,0xFFFFFFFF))
 | 
			
		||||
  {
 | 
			
		||||
    Error(0);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Copy data from previous history step
 | 
			
		||||
  memcpy(Main_backups->Pages->Palette,Main_backups->Pages->Next->Palette,sizeof(T_Palette));
 | 
			
		||||
  strcpy(Main_backups->Pages->Comment,Main_backups->Pages->Next->Comment);
 | 
			
		||||
  Main_backups->Pages->File_format=Main_backups->Pages->Next->File_format;
 | 
			
		||||
  strcpy(Main_backups->Pages->Filename, Main_backups->Pages->Next->Filename);
 | 
			
		||||
  strcpy(Main_backups->Pages->File_directory, Main_backups->Pages->Next->File_directory);
 | 
			
		||||
  Main_backups->Pages->Gradients=Dup_gradient(Main_backups->Pages->Next);
 | 
			
		||||
  Main_backups->Pages->Background_transparent=Main_backups->Pages->Next->Background_transparent;
 | 
			
		||||
  Main_backups->Pages->Transparent_color=Main_backups->Pages->Next->Transparent_color;
 | 
			
		||||
  
 | 
			
		||||
  // Fill with transparent color
 | 
			
		||||
  for (i=0; i<Main_backups->Pages->Nb_layers;i++)
 | 
			
		||||
  {
 | 
			
		||||
    memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  Update_buffers(width, height);
 | 
			
		||||
 | 
			
		||||
  Download_infos_page_main(Main_backups->Pages);
 | 
			
		||||
  
 | 
			
		||||
  // Same code as in End_of_modification(),
 | 
			
		||||
  // Without saving a safety backup:
 | 
			
		||||
  #ifndef NOLAYERS
 | 
			
		||||
    memcpy(Main_visible_image_backup.Image,
 | 
			
		||||
           Main_visible_image.Image,
 | 
			
		||||
           Main_image_width*Main_image_height);
 | 
			
		||||
  #else
 | 
			
		||||
    Update_screen_targets();
 | 
			
		||||
  #endif
 | 
			
		||||
  Update_FX_feedback(Config.FX_Feedback);
 | 
			
		||||
  // --
 | 
			
		||||
  
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Resizes a backup step in-place (doesn't add a Undo/Redo step).
 | 
			
		||||
/// Should only be called after an actual backup, because it loses the current.
 | 
			
		||||
/// pixels. This function is meant to be used from within Lua scripts.
 | 
			
		||||
int Backup_in_place(int width,int height)
 | 
			
		||||
{
 | 
			
		||||
  // Retourne 1 si une nouvelle page est disponible (alors pleine de 0) et
 | 
			
		||||
  // 0 sinon.
 | 
			
		||||
 | 
			
		||||
  int i;
 | 
			
		||||
  byte ** new_layer;
 | 
			
		||||
 | 
			
		||||
  // Perform all allocations first
 | 
			
		||||
  
 | 
			
		||||
  new_layer=calloc(Main_backups->Pages->Nb_layers,1);
 | 
			
		||||
  if (!new_layer)
 | 
			
		||||
    return 0;
 | 
			
		||||
  
 | 
			
		||||
  for (i=0; i<Main_backups->Pages->Nb_layers; i++)
 | 
			
		||||
  {
 | 
			
		||||
    new_layer[i]=New_layer(height*width);
 | 
			
		||||
    if (!new_layer[i])
 | 
			
		||||
    {
 | 
			
		||||
      // Allocation error
 | 
			
		||||
      for (; i>0; i--)
 | 
			
		||||
        free(new_layer[i]);
 | 
			
		||||
      free(new_layer);
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Now ok to proceed
 | 
			
		||||
  
 | 
			
		||||
  for (i=0; i<Main_backups->Pages->Nb_layers; i++)
 | 
			
		||||
  {
 | 
			
		||||
    // Replace layers
 | 
			
		||||
    Free_layer(Main_backups->Pages,i);
 | 
			
		||||
    Main_backups->Pages->Image[i]=new_layer[i];
 | 
			
		||||
    
 | 
			
		||||
    // Fill with transparency
 | 
			
		||||
    memset(Main_backups->Pages->Image[i], Main_backups->Pages->Transparent_color, width*height);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  Main_backups->Pages->Width=width;
 | 
			
		||||
  Main_backups->Pages->Height=height;
 | 
			
		||||
 | 
			
		||||
  Download_infos_page_main(Main_backups->Pages);
 | 
			
		||||
  
 | 
			
		||||
  // The following is part of Update_buffers()
 | 
			
		||||
  // (without changing the backup buffer)
 | 
			
		||||
  #ifndef NOLAYERS
 | 
			
		||||
  // At least one dimension is different
 | 
			
		||||
  if (Main_visible_image.Width*Main_visible_image.Height != width*height)
 | 
			
		||||
  {
 | 
			
		||||
    // Current image
 | 
			
		||||
    free(Main_visible_image.Image);
 | 
			
		||||
    Main_visible_image.Image = (byte *)malloc(width * height);
 | 
			
		||||
    if (Main_visible_image.Image == NULL)
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
  Main_visible_image.Width = width;
 | 
			
		||||
  Main_visible_image.Height = height;
 | 
			
		||||
 | 
			
		||||
  if (Main_visible_image_depth_buffer.Width*Main_visible_image_depth_buffer.Height != width*height)
 | 
			
		||||
  {      
 | 
			
		||||
    // Depth buffer
 | 
			
		||||
    free(Main_visible_image_depth_buffer.Image);
 | 
			
		||||
    Main_visible_image_depth_buffer.Image = (byte *)malloc(width * height);
 | 
			
		||||
    if (Main_visible_image_depth_buffer.Image == NULL)
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
  Main_visible_image_depth_buffer.Width = width;
 | 
			
		||||
  Main_visible_image_depth_buffer.Height = height;
 | 
			
		||||
  
 | 
			
		||||
#endif
 | 
			
		||||
  Update_screen_targets();
 | 
			
		||||
  
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Backup_and_resize_the_spare(int width,int height)
 | 
			
		||||
@ -872,6 +1022,7 @@ int Backup_and_resize_the_spare(int width,int height)
 | 
			
		||||
  
 | 
			
		||||
  // Fill it with a copy of the latest history
 | 
			
		||||
  Copy_S_page(new_page,Spare_backups->Pages);
 | 
			
		||||
  new_page->Gradients=Dup_gradient(Spare_backups->Pages);
 | 
			
		||||
  
 | 
			
		||||
  new_page->Width=width;
 | 
			
		||||
  new_page->Height=height;
 | 
			
		||||
@ -927,6 +1078,7 @@ void Backup_layers(dword layer_mask)
 | 
			
		||||
  
 | 
			
		||||
  // Fill it with a copy of the latest history
 | 
			
		||||
  Copy_S_page(new_page,Main_backups->Pages);
 | 
			
		||||
  new_page->Gradients=Dup_gradient(Main_backups->Pages);
 | 
			
		||||
  Create_new_page(new_page,Main_backups,layer_mask);
 | 
			
		||||
  Download_infos_page_main(new_page);
 | 
			
		||||
 | 
			
		||||
@ -963,6 +1115,7 @@ void Backup_the_spare(dword layer_mask)
 | 
			
		||||
  
 | 
			
		||||
  // Fill it with a copy of the latest history
 | 
			
		||||
  Copy_S_page(new_page,Spare_backups->Pages);
 | 
			
		||||
  new_page->Gradients=Dup_gradient(Spare_backups->Pages);
 | 
			
		||||
  Create_new_page(new_page,Spare_backups,layer_mask);
 | 
			
		||||
 | 
			
		||||
  // Copy the actual pixels from the backup to the latest page
 | 
			
		||||
@ -1099,6 +1252,11 @@ void End_of_modification(void)
 | 
			
		||||
  //Update_buffers(Main_image_width, Main_image_height);
 | 
			
		||||
  
 | 
			
		||||
#ifndef NOLAYERS
 | 
			
		||||
  // Backup buffer can have "wrong" size if a Lua script
 | 
			
		||||
  // performs a resize.
 | 
			
		||||
  Update_buffers(Main_image_width, Main_image_height);
 | 
			
		||||
  //
 | 
			
		||||
 | 
			
		||||
  memcpy(Main_visible_image_backup.Image,
 | 
			
		||||
         Main_visible_image.Image,
 | 
			
		||||
         Main_image_width*Main_image_height);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								src/pages.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/pages.h
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
 | 
			
		||||
@ -39,13 +40,14 @@ extern byte * FX_feedback_screen;
 | 
			
		||||
/////////////////////////// BACKUP ///////////////////////////////////////
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#ifndef NOLAYERS
 | 
			
		||||
/// The pixels of visible layers, flattened copy.
 | 
			
		||||
extern T_Bitmap Main_visible_image;
 | 
			
		||||
/// The pixels of visible layers, flattened copy, used for no-feedback effects.
 | 
			
		||||
extern T_Bitmap Main_visible_image_backup;
 | 
			
		||||
/// The index of visible pixels from ::Visible image. Points to the right layer.
 | 
			
		||||
extern T_Bitmap Main_visible_image_depth_buffer;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/// The pixels of visible layers for the spare page, flattened copy.
 | 
			
		||||
extern T_Bitmap Spare_visible_image;
 | 
			
		||||
 | 
			
		||||
@ -93,7 +95,13 @@ void Free_page_of_a_list(T_List_of_pages * list);
 | 
			
		||||
 | 
			
		||||
int Init_all_backup_lists(int width,int height);
 | 
			
		||||
void Set_number_of_backups(int nb_backups);
 | 
			
		||||
int Backup_with_new_dimensions(int upload,byte layers,int width,int height);
 | 
			
		||||
int Backup_new_image(byte layers,int width,int height);
 | 
			
		||||
int Backup_with_new_dimensions(int width,int height);
 | 
			
		||||
///
 | 
			
		||||
/// Resizes a backup step in-place (doesn't add a Undo/Redo step).
 | 
			
		||||
/// Should only be called after an actual backup, because it loses the current.
 | 
			
		||||
/// pixels. This function is meant to be used from within Lua scripts.
 | 
			
		||||
int Backup_in_place(int width,int height);
 | 
			
		||||
/// Backup the spare image, the one you don't see.
 | 
			
		||||
void Backup_the_spare(dword layer_mask);
 | 
			
		||||
int Backup_and_resize_the_spare(int width,int height);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1167
									
								
								src/palette.c
									
									
									
									
									
								
							
							
						
						
									
										1167
									
								
								src/palette.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -31,6 +31,8 @@ void Button_Secondary_palette(void);
 | 
			
		||||
/// Choose the number of graduations for RGB components, from 2 to 256.
 | 
			
		||||
void Set_palette_RGB_scale(int);
 | 
			
		||||
 | 
			
		||||
int Get_palette_RGB_scale(void);
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Scale a component (R, G or B) according to the current RGB graduations.
 | 
			
		||||
/// Returns the resulting value, in the [0-255] range.
 | 
			
		||||
@ -42,3 +44,17 @@ byte Round_palette_component(byte comp);
 | 
			
		||||
  @param not_picture 0 if the caller is the palette screen, 1 if it's a preview in the file selector.
 | 
			
		||||
*/
 | 
			
		||||
void Set_nice_menu_colors(dword * color_usage,int not_picture);
 | 
			
		||||
 | 
			
		||||
/// Put some colors in the clipboard.
 | 
			
		||||
/// @param nb_colors Number of colors to push
 | 
			
		||||
/// @param colors First color of the input array
 | 
			
		||||
void Set_clipboard_colors(int nb_colors, T_Components *colors);
 | 
			
		||||
 | 
			
		||||
/// Get some RGB colors from clipboard.
 | 
			
		||||
/// @param palette Target palette
 | 
			
		||||
/// @param start_color  Index of first color to replace
 | 
			
		||||
/// @return        Number of colors retrieved (0-256)
 | 
			
		||||
int Get_clipboard_colors(T_Palette palette, byte start_color);
 | 
			
		||||
 | 
			
		||||
/// Get the favorite color to use for GUI's black,dark,light or white.
 | 
			
		||||
const T_Components * Favorite_GUI_color(byte color_index);
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
@ -32,6 +33,7 @@
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "readini.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
void Load_INI_clear_string(char * str, byte keep_comments)
 | 
			
		||||
{
 | 
			
		||||
@ -432,6 +434,13 @@ int Load_INI(T_Config * conf)
 | 
			
		||||
  char   value_label[1024];
 | 
			
		||||
 | 
			
		||||
  Line_number_in_INI_file=0;
 | 
			
		||||
  
 | 
			
		||||
#if defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
  conf->Stylus_mode = 1;
 | 
			
		||||
#else
 | 
			
		||||
  conf->Stylus_mode = 0;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // On alloue les zones de mémoire:
 | 
			
		||||
  buffer=(char *)malloc(1024);
 | 
			
		||||
@ -439,14 +448,14 @@ int Load_INI(T_Config * conf)
 | 
			
		||||
 | 
			
		||||
  // On calcule le nom du fichier qu'on manipule:
 | 
			
		||||
  strcpy(filename,Config_directory);
 | 
			
		||||
  strcat(filename,"gfx2.ini");
 | 
			
		||||
  strcat(filename,INI_FILENAME);
 | 
			
		||||
 | 
			
		||||
  file=fopen(filename,"r");
 | 
			
		||||
  if (file==0)
 | 
			
		||||
  {
 | 
			
		||||
    // Si le fichier ini est absent on le relit depuis gfx2def.ini
 | 
			
		||||
    strcpy(filename,Data_directory);
 | 
			
		||||
    strcat(filename,"gfx2def.ini");
 | 
			
		||||
    strcat(filename,INIDEF_FILENAME);
 | 
			
		||||
    file=fopen(filename,"r");
 | 
			
		||||
    if (file == 0)
 | 
			
		||||
    {
 | 
			
		||||
@ -894,6 +903,39 @@ int Load_INI(T_Config * conf)
 | 
			
		||||
      Menu_bars[index].Visible = (values[0] & (1<<index)) ? 1 : 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  conf->Right_click_colorpick=0;
 | 
			
		||||
  // Optional, right mouse button to pick colors (>=2.3)
 | 
			
		||||
  if (!Load_INI_get_values (file,buffer,"Right_click_colorpick",1,values))
 | 
			
		||||
  {
 | 
			
		||||
    conf->Right_click_colorpick=(values[0]!=0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  conf->Sync_views=1;
 | 
			
		||||
  // Optional, synced view of main and spare (>=2.3)
 | 
			
		||||
  if (!Load_INI_get_values (file,buffer,"Sync_views",1,values))
 | 
			
		||||
  {
 | 
			
		||||
    conf->Sync_views=(values[0]!=0);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  conf->Swap_buttons=0;
 | 
			
		||||
  // Optional, key for swap buttons (>=2.3)
 | 
			
		||||
  if (!Load_INI_get_values (file,buffer,"Swap_buttons",1,values))
 | 
			
		||||
  {
 | 
			
		||||
    switch(values[0])
 | 
			
		||||
    {
 | 
			
		||||
      case 1:
 | 
			
		||||
        conf->Swap_buttons=MOD_CTRL;
 | 
			
		||||
        break;
 | 
			
		||||
      case 2:
 | 
			
		||||
        conf->Swap_buttons=MOD_ALT;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  // Insert new values here
 | 
			
		||||
 | 
			
		||||
  fclose(file);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										302
									
								
								src/readline.c
									
									
									
									
									
								
							
							
						
						
									
										302
									
								
								src/readline.c
									
									
									
									
									
								
							@ -40,6 +40,13 @@
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
 | 
			
		||||
// Virtual keyboard is mandatory on these platforms:
 | 
			
		||||
#if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
  #ifndef VIRT_KEY
 | 
			
		||||
    #define VIRT_KEY 1
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define TEXT_COLOR         MC_Black
 | 
			
		||||
#define BACKGROUND_COLOR          MC_Light
 | 
			
		||||
#define CURSOR_COLOR MC_Black
 | 
			
		||||
@ -98,8 +105,41 @@ int Valid_character(int c)
 | 
			
		||||
 | 
			
		||||
void Display_whole_string(word x_pos,word y_pos,char * str,byte position)
 | 
			
		||||
{
 | 
			
		||||
  Print_in_window(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
 | 
			
		||||
  Print_char_in_window(x_pos+(position<<3),y_pos,str[position],CURSOR_COLOR,CURSOR_BACKGROUND_COLOR);
 | 
			
		||||
  char cursor[2];
 | 
			
		||||
  Print_general(x_pos,y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
 | 
			
		||||
 | 
			
		||||
  cursor[0]=str[position] ? str[position] : ' ';
 | 
			
		||||
  cursor[1]='\0';
 | 
			
		||||
  Print_general(x_pos+(position<<3)*Menu_factor_X,y_pos,cursor,CURSOR_COLOR,CURSOR_BACKGROUND_COLOR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Init_virtual_keyboard(word y_pos, word keyboard_width, word keyboard_height)
 | 
			
		||||
{
 | 
			
		||||
  int h_pos;
 | 
			
		||||
  int v_pos;
 | 
			
		||||
  int parent_window_x=Window_pos_X+2;
 | 
			
		||||
  
 | 
			
		||||
  h_pos= Window_pos_X+(keyboard_width-Window_width)*Menu_factor_X/-2;
 | 
			
		||||
  if (h_pos<0)
 | 
			
		||||
    h_pos=0;
 | 
			
		||||
  else if (h_pos+keyboard_width*Menu_factor_X>Screen_width)
 | 
			
		||||
    h_pos=Screen_width-keyboard_width*Menu_factor_X;
 | 
			
		||||
  v_pos=Window_pos_Y+(y_pos+9)*Menu_factor_Y;
 | 
			
		||||
  if (v_pos+(keyboard_height*Menu_factor_Y)>Screen_height)
 | 
			
		||||
    v_pos=Window_pos_Y+(y_pos-keyboard_height-4)*Menu_factor_Y;
 | 
			
		||||
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
  Open_popup(h_pos,v_pos,keyboard_width,keyboard_height);
 | 
			
		||||
  Window_rectangle(1,0,Window_width-1, Window_height-1, MC_Light);
 | 
			
		||||
  Window_rectangle(0,0,1,Window_height-2, MC_White);
 | 
			
		||||
  // white border on top left angle, when it exceeds border.
 | 
			
		||||
  if (parent_window_x>Window_pos_X)
 | 
			
		||||
    Window_rectangle(0,0,(parent_window_x-Window_pos_X)/Menu_factor_X, 1, MC_White);
 | 
			
		||||
  Window_rectangle(2,Window_height-2,Window_width-2, 2, MC_Black);
 | 
			
		||||
  if(keyboard_width<320)
 | 
			
		||||
  {
 | 
			
		||||
    Window_rectangle(Window_width-2,2,2,Window_height-2, MC_Black);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/****************************************************************************
 | 
			
		||||
@ -143,28 +183,156 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
  byte size;
 | 
			
		||||
  word input_key=0;
 | 
			
		||||
  byte is_authorized;
 | 
			
		||||
 | 
			
		||||
  word window_x=Window_pos_X;
 | 
			
		||||
  word window_y=Window_pos_Y;
 | 
			
		||||
  byte offset=0; // index du premier caractère affiché
 | 
			
		||||
  
 | 
			
		||||
#ifdef VIRT_KEY
 | 
			
		||||
  // Virtual keyboard
 | 
			
		||||
  byte use_virtual_keyboard=0;
 | 
			
		||||
  static byte caps_lock=0;
 | 
			
		||||
  word keymapping[] =
 | 
			
		||||
  {
 | 
			
		||||
    SDLK_CLEAR,SDLK_BACKSPACE,SDLK_RETURN,KEY_ESC,
 | 
			
		||||
    '0','1','2','3','4','5','6','7','8','9','.',',',
 | 
			
		||||
    'Q','W','E','R','T','Y','U','I','O','P',
 | 
			
		||||
    'A','S','D','F','G','H','J','K','L',
 | 
			
		||||
    SDLK_CAPSLOCK,'Z','X','C','V','B','N','M',' ',
 | 
			
		||||
    '-','+','*','/','|','\\',
 | 
			
		||||
    '(',')','{','}','[',']',
 | 
			
		||||
    '_','=','<','>','%','@',
 | 
			
		||||
    ':',';','`','\'','"','~',
 | 
			
		||||
    '!','?','^','&','#','$'
 | 
			
		||||
  };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // Si on a commencé à editer par un clic-droit, on vide la chaine.
 | 
			
		||||
  if (Mouse_K==RIGHT_SIDE)
 | 
			
		||||
    str[0]='\0';
 | 
			
		||||
  else if (input_type==1 && str[0]!='\0')
 | 
			
		||||
  else if (input_type==INPUT_TYPE_INTEGER && str[0]!='\0')
 | 
			
		||||
    snprintf(str,10,"%d",atoi(str)); // On tasse la chaine à gauche
 | 
			
		||||
  else if (input_type==3)
 | 
			
		||||
  else if (input_type==INPUT_TYPE_DECIMAL)
 | 
			
		||||
  {
 | 
			
		||||
    //  Nothing. The caller should have used Sprint_double, with min_positions
 | 
			
		||||
    //  at zero, so there's no spaces on the left and no useless 0s on the right.
 | 
			
		||||
  }
 | 
			
		||||
  else if (input_type==INPUT_TYPE_HEXA)
 | 
			
		||||
  {
 | 
			
		||||
    //  Nothing. The caller should have initialized a valid hexa number.
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Virtual keyboards
 | 
			
		||||
#ifdef VIRT_KEY
 | 
			
		||||
  if (input_type == INPUT_TYPE_STRING || input_type == INPUT_TYPE_FILENAME )
 | 
			
		||||
  {
 | 
			
		||||
    int x,y;
 | 
			
		||||
 | 
			
		||||
  Wait_end_of_click();
 | 
			
		||||
    Init_virtual_keyboard(y_pos, 320, 87);
 | 
			
		||||
    
 | 
			
		||||
    use_virtual_keyboard=1;
 | 
			
		||||
    
 | 
			
		||||
    // The order is important, see the array
 | 
			
		||||
    
 | 
			
		||||
    Window_set_normal_button(  7,67,43,15,"Clr", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 51,67,43,15,"Del", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 95,67,43,15,"OK",  0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(139,67,43,15,"Esc", 0,1,KEY_NONE);
 | 
			
		||||
    Window_display_frame_in(5,65,179,19);
 | 
			
		||||
 | 
			
		||||
    Window_set_normal_button(193,63,17,19,"0", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(193,43,17,19,"1", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(211,43,17,19,"2", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(229,43,17,19,"3", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(193,23,17,19,"4", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(211,23,17,19,"5", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(229,23,17,19,"6", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(193, 3,17,19,"7", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(211, 3,17,19,"8", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(229, 3,17,19,"9", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(211,63,17,19,".", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(229,63,17,19,",", 0,1,KEY_NONE);
 | 
			
		||||
 
 | 
			
		||||
    Window_set_normal_button(  3, 3,18,19,"Q", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 22, 3,18,19,"W", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 41, 3,18,19,"E", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 60, 3,18,19,"R", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 79, 3,18,19,"T", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 98, 3,18,19,"Y", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(117, 3,18,19,"U", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(136, 3,18,19,"I", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(155, 3,18,19,"O", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(174, 3,18,19,"P", 0,1,KEY_NONE);
 | 
			
		||||
 | 
			
		||||
    Window_set_normal_button( 12,23,18,19,"A", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 31,23,18,19,"S", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 50,23,18,19,"D", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 69,23,18,19,"F", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 88,23,18,19,"G", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(107,23,18,19,"H", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(126,23,18,19,"J", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(145,23,18,19,"K", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(164,23,18,19,"L", 0,1,KEY_NONE);
 | 
			
		||||
    
 | 
			
		||||
    Window_set_normal_button(  3,43,18,19,caps_lock?"\036":"\037", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 22,43,18,19,"Z", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 41,43,18,19,"X", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 60,43,18,19,"C", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 79,43,18,19,"V", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 98,43,18,19,"B", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(117,43,18,19,"N", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(136,43,18,19,"M", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(155,43,18,19," ", 0,1,KEY_NONE);
 | 
			
		||||
 | 
			
		||||
    for (y=0; y<5; y++)
 | 
			
		||||
    {
 | 
			
		||||
      for (x=0; x<6; x++)
 | 
			
		||||
      {
 | 
			
		||||
        char label[2]=" ";
 | 
			
		||||
        label[0]=keymapping[x+y*6+44];        
 | 
			
		||||
        Window_set_normal_button(247+x*12, 3+y*16,11,15,label, 0,1,KEY_NONE);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Update_window_area(0,0,Window_width, Window_height);
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }
 | 
			
		||||
  else if (input_type == INPUT_TYPE_INTEGER || input_type == INPUT_TYPE_DECIMAL )
 | 
			
		||||
  {
 | 
			
		||||
    Init_virtual_keyboard(y_pos, 215, 47);
 | 
			
		||||
    
 | 
			
		||||
    use_virtual_keyboard=1;
 | 
			
		||||
    
 | 
			
		||||
    // The order is important, see the array
 | 
			
		||||
    
 | 
			
		||||
    Window_set_normal_button(  7,27,43,15,"Clr", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 51,27,43,15,"Del", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 95,27,43,15,"OK",  0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(139,27,43,15,"Esc", 0,1,KEY_NONE);
 | 
			
		||||
    Window_display_frame_in(5,25,179,19);
 | 
			
		||||
 | 
			
		||||
    Window_set_normal_button(174, 3,18,19,"0", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(  3, 3,18,19,"1", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 22, 3,18,19,"2", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 41, 3,18,19,"3", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 60, 3,18,19,"4", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 79, 3,18,19,"5", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button( 98, 3,18,19,"6", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(117, 3,18,19,"7", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(136, 3,18,19,"8", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(155, 3,18,19,"9", 0,1,KEY_NONE);
 | 
			
		||||
    Window_set_normal_button(193, 3,18,19,".", 0,1,KEY_NONE);
 | 
			
		||||
 | 
			
		||||
    Update_window_area(0,0,Window_width, Window_height);
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  Keyboard_click_allowed = 0;
 | 
			
		||||
  Hide_cursor();
 | 
			
		||||
 | 
			
		||||
  // Effacement de la chaîne
 | 
			
		||||
  Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
  Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
  Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
  Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
 | 
			
		||||
 | 
			
		||||
  // Mise à jour des variables se rapportant à la chaîne en fonction de la chaîne initiale
 | 
			
		||||
@ -182,19 +350,67 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
  if (visible_size + offset + 1 < size )
 | 
			
		||||
    display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER;
 | 
			
		||||
  
 | 
			
		||||
  Display_whole_string(x_pos,y_pos,display_string,position - offset);
 | 
			
		||||
  Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
  Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
 | 
			
		||||
  Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
 | 
			
		||||
  Flush_update();
 | 
			
		||||
 | 
			
		||||
  while ((input_key!=SDLK_RETURN) && (input_key!=KEY_ESC) && Mouse_K == 0)
 | 
			
		||||
  if (Mouse_K)
 | 
			
		||||
  {
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
    do
 | 
			
		||||
    Wait_end_of_click();
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  while ((input_key!=SDLK_RETURN) && (input_key!=KEY_ESC))
 | 
			
		||||
  {
 | 
			
		||||
    Display_cursor();
 | 
			
		||||
#ifdef VIRT_KEY
 | 
			
		||||
    if (use_virtual_keyboard)
 | 
			
		||||
    {
 | 
			
		||||
      if(!Get_input()) SDL_Delay(20);
 | 
			
		||||
      int clicked_button;
 | 
			
		||||
 | 
			
		||||
      clicked_button=Window_clicked_button();
 | 
			
		||||
      input_key=Key_ANSI;
 | 
			
		||||
    } while(input_key==0 && Mouse_K == 0);
 | 
			
		||||
 | 
			
		||||
      if (clicked_button==-1)
 | 
			
		||||
        input_key=SDLK_RETURN;
 | 
			
		||||
      else if (clicked_button>0)
 | 
			
		||||
      {
 | 
			
		||||
        input_key=keymapping[clicked_button-1];
 | 
			
		||||
        if (input_key==SDLK_CAPSLOCK)
 | 
			
		||||
        {
 | 
			
		||||
          // toggle uppercase
 | 
			
		||||
          caps_lock=!caps_lock;
 | 
			
		||||
          Hide_cursor();
 | 
			
		||||
          Print_in_window(8, 49,caps_lock?"\036":"\037", MC_Black,MC_Light);
 | 
			
		||||
          Display_cursor();
 | 
			
		||||
        }
 | 
			
		||||
        else if (input_key==SDLK_BACKSPACE)
 | 
			
		||||
        {
 | 
			
		||||
          // A little hack: the button for backspace will:
 | 
			
		||||
          // - backspace if the cursor is at end of string
 | 
			
		||||
          // - delete otherwise
 | 
			
		||||
          // It's needed for those input boxes that are completely full.
 | 
			
		||||
          if (position<size)
 | 
			
		||||
            input_key = SDLK_DELETE;
 | 
			
		||||
        }
 | 
			
		||||
        else if (input_key>='A' && input_key<='Z' && !caps_lock)
 | 
			
		||||
        {
 | 
			
		||||
          input_key+='a'-'A';
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
      do
 | 
			
		||||
      {
 | 
			
		||||
        Get_input(20);
 | 
			
		||||
        input_key=Key_ANSI;
 | 
			
		||||
        if (Mouse_K)
 | 
			
		||||
          input_key=SDLK_RETURN;
 | 
			
		||||
      } while(input_key==0);
 | 
			
		||||
    }
 | 
			
		||||
    Hide_cursor();
 | 
			
		||||
    switch (input_key)
 | 
			
		||||
    {
 | 
			
		||||
@ -205,7 +421,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
              size--;
 | 
			
		||||
              
 | 
			
		||||
              // Effacement de la chaîne
 | 
			
		||||
              Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
              Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
                    visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
              goto affichage;
 | 
			
		||||
            }
 | 
			
		||||
@ -215,7 +431,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
            {
 | 
			
		||||
              // Effacement de la chaîne
 | 
			
		||||
              if (position==size)
 | 
			
		||||
                Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
                Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
                      visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
              position--;
 | 
			
		||||
              if (offset > 0 && (position == 0 || position < (offset + 1)))
 | 
			
		||||
@ -239,7 +455,7 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
            {
 | 
			
		||||
              // Effacement de la chaîne
 | 
			
		||||
              if (position==size)
 | 
			
		||||
                Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
                Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
                      visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
              position = 0;
 | 
			
		||||
              offset = 0;
 | 
			
		||||
@ -265,11 +481,18 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
          Remove_character(str,position);
 | 
			
		||||
          size--;
 | 
			
		||||
          // Effacement de la chaîne
 | 
			
		||||
          Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
          Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
                visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
          goto affichage;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case  SDLK_CLEAR : // Clear
 | 
			
		||||
        str[0]='\0';
 | 
			
		||||
        position=offset=0;
 | 
			
		||||
        // Effacement de la chaîne
 | 
			
		||||
        Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
              visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
        goto affichage;
 | 
			
		||||
      case SDLK_RETURN :
 | 
			
		||||
        break;
 | 
			
		||||
        
 | 
			
		||||
@ -285,15 +508,15 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
          is_authorized=0; // On commence par supposer qu'elle est interdite
 | 
			
		||||
          switch(input_type)
 | 
			
		||||
          {
 | 
			
		||||
            case 0 : // N'importe quelle chaîne:
 | 
			
		||||
            case INPUT_TYPE_STRING :
 | 
			
		||||
              if (input_key>=' ' && input_key<= 255)
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              break;
 | 
			
		||||
            case 1 : // Nombre
 | 
			
		||||
            case INPUT_TYPE_INTEGER :
 | 
			
		||||
              if ( (input_key>='0') && (input_key<='9') )
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              break;
 | 
			
		||||
            case 3: // Decimal number
 | 
			
		||||
            case INPUT_TYPE_DECIMAL:
 | 
			
		||||
              if ( (input_key>='0') && (input_key<='9') )
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              else if (input_key=='-' && position==0 && str[0]!='-')
 | 
			
		||||
@ -301,10 +524,18 @@ byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_siz
 | 
			
		||||
              else if (input_key=='.')
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              break;
 | 
			
		||||
            default : // Nom de fichier
 | 
			
		||||
            case INPUT_TYPE_FILENAME:
 | 
			
		||||
              // On regarde si la touche est autorisée
 | 
			
		||||
              if ( Valid_character(input_key))
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
            case INPUT_TYPE_HEXA:
 | 
			
		||||
              if ( (input_key>='0') && (input_key<='9') )
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              else if ( (input_key>='A') && (input_key<='F') )
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              else if ( (input_key>='a') && (input_key<='f') )
 | 
			
		||||
                is_authorized=1;
 | 
			
		||||
              break;
 | 
			
		||||
          } // End du "switch(input_type)"
 | 
			
		||||
 | 
			
		||||
          // Si la touche était autorisée...
 | 
			
		||||
@ -337,20 +568,29 @@ affichage:
 | 
			
		||||
        if (visible_size + offset + 0 < size )
 | 
			
		||||
          display_string[visible_size-1]=RIGHT_TRIANGLE_CHARACTER;
 | 
			
		||||
        
 | 
			
		||||
        Display_whole_string(x_pos,y_pos,display_string,position - offset);
 | 
			
		||||
        Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        Display_whole_string(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),display_string,position - offset);
 | 
			
		||||
        Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
 | 
			
		||||
    } // End du "switch(input_key)"
 | 
			
		||||
    Flush_update();
 | 
			
		||||
 | 
			
		||||
  } // End du "while"
 | 
			
		||||
  Keyboard_click_allowed = 1;
 | 
			
		||||
 | 
			
		||||
  #ifdef VIRT_KEY
 | 
			
		||||
  if (use_virtual_keyboard)
 | 
			
		||||
  {
 | 
			
		||||
    byte old_mouse_k = Mouse_K;
 | 
			
		||||
    Close_popup();
 | 
			
		||||
    Mouse_K=old_mouse_k;
 | 
			
		||||
    Input_sticky_control=0;
 | 
			
		||||
  }
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
  // Effacement de la chaîne
 | 
			
		||||
  Block(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
  Block(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3),BACKGROUND_COLOR);
 | 
			
		||||
  // On raffiche la chaine correctement
 | 
			
		||||
  if (input_type==1)
 | 
			
		||||
  if (input_type==INPUT_TYPE_INTEGER)
 | 
			
		||||
  {
 | 
			
		||||
    if (str[0]=='\0')
 | 
			
		||||
    {
 | 
			
		||||
@ -359,7 +599,7 @@ affichage:
 | 
			
		||||
    }
 | 
			
		||||
    Print_in_window(x_pos+((max_size-size)<<3),y_pos,str,TEXT_COLOR,BACKGROUND_COLOR);
 | 
			
		||||
  }
 | 
			
		||||
  else if (input_type==3)
 | 
			
		||||
  else if (input_type==INPUT_TYPE_DECIMAL)
 | 
			
		||||
  {
 | 
			
		||||
    double value;
 | 
			
		||||
    // Discard extra digits
 | 
			
		||||
@ -377,10 +617,10 @@ affichage:
 | 
			
		||||
  {
 | 
			
		||||
    Print_in_window_limited(x_pos,y_pos,str,visible_size,TEXT_COLOR,BACKGROUND_COLOR);
 | 
			
		||||
  }
 | 
			
		||||
  Update_rect(Window_pos_X+(x_pos*Menu_factor_X),Window_pos_Y+(y_pos*Menu_factor_Y),
 | 
			
		||||
  Update_rect(window_x+(x_pos*Menu_factor_X),window_y+(y_pos*Menu_factor_Y),
 | 
			
		||||
        visible_size*(Menu_factor_X<<3),(Menu_factor_Y<<3));
 | 
			
		||||
 | 
			
		||||
  return (input_key==SDLK_RETURN || Mouse_K != 0);
 | 
			
		||||
  return (input_key==SDLK_RETURN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Sprint_double(char *str, double value, byte decimal_places, byte min_positions)
 | 
			
		||||
 | 
			
		||||
@ -24,13 +24,22 @@
 | 
			
		||||
/// Text input functions.
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
enum INPUT_TYPE
 | 
			
		||||
{
 | 
			
		||||
  INPUT_TYPE_STRING=0,  ///< Any string
 | 
			
		||||
  INPUT_TYPE_INTEGER=1, ///< Decimal integer
 | 
			
		||||
  INPUT_TYPE_FILENAME=2,///< Filename
 | 
			
		||||
  INPUT_TYPE_DECIMAL=3, ///< Decimal value
 | 
			
		||||
  INPUT_TYPE_HEXA=4,    ///< Hexadecimal integer
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///
 | 
			
		||||
/// Lets the user input a line of text, exit by Esc or Return.
 | 
			
		||||
/// @param x_pos        Coordinates of input, in window coordinates before scaling.
 | 
			
		||||
/// @param y_pos        Coordinates of input, in window coordinates before scaling.
 | 
			
		||||
/// @param str          The original string value (will be modified, unless user cancels.
 | 
			
		||||
/// @param visible_size Number of characters visible and editable.
 | 
			
		||||
/// @param input_type   0=string, 1=number, 2=filename (255 editable characters)
 | 
			
		||||
/// @param input_type   one of enum ::INPUT_TYPE
 | 
			
		||||
/// @return             0 if user cancelled (esc), 1 if accepted (return)
 | 
			
		||||
byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type);
 | 
			
		||||
 | 
			
		||||
@ -41,7 +50,7 @@ byte Readline(word x_pos,word y_pos,char * str,byte visible_size,byte input_type
 | 
			
		||||
/// @param str          The original string value (will be modified, unless user cancels.
 | 
			
		||||
/// @param visible_size Number of characters visible.
 | 
			
		||||
/// @param max_size     Number of characters editable.
 | 
			
		||||
/// @param input_type   0=string, 1=integer, 2=filename (255 editable characters) 3=decimal
 | 
			
		||||
/// @param input_type   one of enum ::INPUT_TYPE
 | 
			
		||||
/// @param decimal_places Number of decimal places (used only with decimal type)
 | 
			
		||||
/// @return             0 if user cancelled (esc), 1 if accepted (return)
 | 
			
		||||
byte Readline_ex(word x_pos,word y_pos,char * str,byte visible_size,byte max_size, byte input_type, byte decimal_places);
 | 
			
		||||
 | 
			
		||||
@ -6,8 +6,11 @@
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#if defined(__AROS__)
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__AROS__) || defined(__BEOS__) || defined(__MORPHOS__) || defined(__GP2X__) || defined(__amigaos__)
 | 
			
		||||
#if defined(__AROS__) || defined(__BEOS__) || defined(__MORPHOS__) || defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__) || defined(__amigaos__)
 | 
			
		||||
// These platforms don't have realpath().
 | 
			
		||||
// We use the following implementation, found in:
 | 
			
		||||
// http://amiga.sourceforge.net/amigadevhelp/FUNCTIONS/GeekGadgets/realpath/ex02_realpath.c
 | 
			
		||||
@ -17,7 +20,7 @@
 | 
			
		||||
// the path. So this implementation is limited, it's really better to
 | 
			
		||||
// use realpath() if your platform has it.
 | 
			
		||||
  
 | 
			
		||||
    #if defined(__GP2X__) || defined(__amigaos__)
 | 
			
		||||
    #if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__) || defined(__amigaos__)
 | 
			
		||||
        // This is a random default value ...
 | 
			
		||||
        #define PATH_MAX 32768
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										169
									
								
								src/saveini.c
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								src/saveini.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
@ -30,6 +31,7 @@
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "saveini.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
int Save_INI_reach_group(FILE * old_file,FILE * new_file,char * buffer,char * group)
 | 
			
		||||
{
 | 
			
		||||
@ -393,8 +395,8 @@ void Save_INI_flush(FILE * old_file,FILE * new_file,char * buffer)
 | 
			
		||||
 | 
			
		||||
int Save_INI(T_Config * conf)
 | 
			
		||||
{
 | 
			
		||||
  FILE * Ancien_fichier;
 | 
			
		||||
  FILE * Nouveau_fichier;
 | 
			
		||||
  FILE * old_file;
 | 
			
		||||
  FILE * new_file;
 | 
			
		||||
  char * buffer;
 | 
			
		||||
  int    values[3];
 | 
			
		||||
  char   filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
@ -409,13 +411,13 @@ int Save_INI(T_Config * conf)
 | 
			
		||||
  
 | 
			
		||||
  // On calcule les noms des fichiers qu'on manipule:
 | 
			
		||||
  strcpy(filename,Config_directory);
 | 
			
		||||
  strcat(filename,"gfx2.ini");
 | 
			
		||||
  strcat(filename,INI_FILENAME);
 | 
			
		||||
 | 
			
		||||
  // On vérifie si le fichier INI existe
 | 
			
		||||
  if ((ini_file_exists = File_exists(filename)))
 | 
			
		||||
  {
 | 
			
		||||
    strcpy(temp_filename,Config_directory);
 | 
			
		||||
    strcat(temp_filename,"gfx2.$$$");
 | 
			
		||||
    strcat(temp_filename,INISAVE_FILENAME);
 | 
			
		||||
    
 | 
			
		||||
    // On renome l'ancienne version du fichier INI vers un fichier temporaire:
 | 
			
		||||
    if (rename(filename,temp_filename)!=0)
 | 
			
		||||
@ -425,237 +427,237 @@ int Save_INI(T_Config * conf)
 | 
			
		||||
  }
 | 
			
		||||
  // On récupère un fichier INI "propre" à partir de gfx2def.ini
 | 
			
		||||
  strcpy(ref_ini_file,Data_directory);
 | 
			
		||||
  strcat(ref_ini_file,"gfx2def.ini");
 | 
			
		||||
  Ancien_fichier=fopen(ref_ini_file,"rb");
 | 
			
		||||
  if (Ancien_fichier==0)
 | 
			
		||||
  strcat(ref_ini_file,INIDEF_FILENAME);
 | 
			
		||||
  old_file=fopen(ref_ini_file,"rb");
 | 
			
		||||
  if (old_file==0)
 | 
			
		||||
  {
 | 
			
		||||
    fclose(Ancien_fichier);
 | 
			
		||||
    fclose(old_file);
 | 
			
		||||
    free(buffer);
 | 
			
		||||
    return ERROR_INI_MISSING;
 | 
			
		||||
  }
 | 
			
		||||
  Nouveau_fichier=fopen(filename,"wb");
 | 
			
		||||
  if (Nouveau_fichier==0)
 | 
			
		||||
  new_file=fopen(filename,"wb");
 | 
			
		||||
  if (new_file==0)
 | 
			
		||||
  {
 | 
			
		||||
    free(buffer);
 | 
			
		||||
    return ERROR_SAVING_INI;
 | 
			
		||||
  }
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(Ancien_fichier,Nouveau_fichier,buffer,"[MOUSE]")))
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(old_file,new_file,buffer,"[MOUSE]")))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Mouse_sensitivity_index_x;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"X_sensitivity",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"X_sensitivity",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Mouse_sensitivity_index_y;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Y_sensitivity",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Y_sensitivity",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=0;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"X_correction_factor",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"X_correction_factor",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=0;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Y_correction_factor",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Y_correction_factor",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Cursor)+1;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Cursor_aspect",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Cursor_aspect",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(Ancien_fichier,Nouveau_fichier,buffer,"[MENU]")))
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(old_file,new_file,buffer,"[MENU]")))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Fav_menu_colors[2].R>>2;
 | 
			
		||||
  values[1]=conf->Fav_menu_colors[2].G>>2;
 | 
			
		||||
  values[2]=conf->Fav_menu_colors[2].B>>2;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Light_color",3,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Light_color",3,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Fav_menu_colors[1].R>>2;
 | 
			
		||||
  values[1]=conf->Fav_menu_colors[1].G>>2;
 | 
			
		||||
  values[2]=conf->Fav_menu_colors[1].B>>2;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Dark_color",3,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Dark_color",3,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Ratio;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Menu_ratio",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Menu_ratio",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(Ancien_fichier,Nouveau_fichier,buffer,"[FILE_SELECTOR]")))
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(old_file,new_file,buffer,"[FILE_SELECTOR]")))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Show_hidden_files?1:0;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Show_hidden_files",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Show_hidden_files",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Show_hidden_directories?1:0;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Show_hidden_directories",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Show_hidden_directories",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
/*  values[0]=conf->Show_system_directories?1:0;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Show_system_directories",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Show_system_directories",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
*/
 | 
			
		||||
  values[0]=conf->Timer_delay;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Preview_delay",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Preview_delay",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Maximize_preview;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Maximize_preview",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Maximize_preview",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Find_file_fast;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Find_file_fast",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Find_file_fast",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(Ancien_fichier,Nouveau_fichier,buffer,"[LOADING]")))
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(old_file,new_file,buffer,"[LOADING]")))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Auto_set_res;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Auto_set_resolution",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Auto_set_resolution",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Set_resolution_according_to;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Set_resolution_according_to",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Set_resolution_according_to",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Clear_palette;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Clear_palette",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Clear_palette",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(Ancien_fichier,Nouveau_fichier,buffer,"[MISCELLANEOUS]")))
 | 
			
		||||
  if ((return_code=Save_INI_reach_group(old_file,new_file,buffer,"[MISCELLANEOUS]")))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Display_image_limits;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Draw_limits",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Draw_limits",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Adjust_brush_pick;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Adjust_brush_pick",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Adjust_brush_pick",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=2-conf->Coords_rel;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Coordinates",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Coordinates",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Backup;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Backup",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Backup",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Max_undo_pages;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Undo_pages",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Undo_pages",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Delay_left_click_on_slider;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Gauges_scrolling_speed_Left",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Gauges_scrolling_speed_Left",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Delay_right_click_on_slider;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Gauges_scrolling_speed_Right",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Gauges_scrolling_speed_Right",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Auto_save;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Auto_save",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Auto_save",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Nb_max_vertices_per_polygon;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Vertices_per_polygon",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Vertices_per_polygon",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Fast_zoom;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Fast_zoom",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Fast_zoom",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Separate_colors;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Separate_colors",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Separate_colors",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->FX_Feedback;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"FX_feedback",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"FX_feedback",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Safety_colors;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Safety_colors",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Safety_colors",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Opening_message;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Opening_message",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Opening_message",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Clear_with_stencil;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Clear_with_stencil",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Clear_with_stencil",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Auto_discontinuous;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Auto_discontinuous",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Auto_discontinuous",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Screen_size_in_GIF;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Save_screen_size_in_GIF",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Save_screen_size_in_GIF",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Auto_nb_used;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Auto_nb_colors_used",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Auto_nb_colors_used",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  if ((return_code=Save_INI_set_strings (Ancien_fichier,Nouveau_fichier,buffer,"Default_video_mode",Mode_label(conf->Default_resolution))))
 | 
			
		||||
  if ((return_code=Save_INI_set_strings (old_file,new_file,buffer,"Default_video_mode",Mode_label(conf->Default_resolution))))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=Video_mode[0].Width;
 | 
			
		||||
  values[1]=Video_mode[0].Height;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Default_window_size",2,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Default_window_size",2,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Mouse_merge_movement);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Merge_movement",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Merge_movement",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Palette_cells_X);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Palette_cells_X",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Palette_cells_X",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Palette_cells_Y);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Palette_cells_Y",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Palette_cells_Y",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  for (index=0;index<NB_BOOKMARKS;index++)
 | 
			
		||||
  {
 | 
			
		||||
    if ((return_code=Save_INI_set_strings (Ancien_fichier,Nouveau_fichier,buffer,"Bookmark_label",conf->Bookmark_label[index])))
 | 
			
		||||
    if ((return_code=Save_INI_set_strings (old_file,new_file,buffer,"Bookmark_label",conf->Bookmark_label[index])))
 | 
			
		||||
      goto Erreur_Retour;
 | 
			
		||||
    if ((return_code=Save_INI_set_strings (Ancien_fichier,Nouveau_fichier,buffer,"Bookmark_directory",conf->Bookmark_directory[index])))
 | 
			
		||||
    if ((return_code=Save_INI_set_strings (old_file,new_file,buffer,"Bookmark_directory",conf->Bookmark_directory[index])))
 | 
			
		||||
      goto Erreur_Retour;
 | 
			
		||||
  }
 | 
			
		||||
  values[0]=(conf->Palette_vertical);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Palette_vertical",1,values,1)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Palette_vertical",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=conf->Window_pos_x;
 | 
			
		||||
  values[1]=conf->Window_pos_y;
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Window_position",2,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Window_position",2,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Double_click_speed);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Double_click_speed",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Double_click_speed",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
    
 | 
			
		||||
  values[0]=(conf->Double_key_speed);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Double_key_speed",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Double_key_speed",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  if ((return_code=Save_INI_set_strings (Ancien_fichier,Nouveau_fichier,buffer,"Skin_file",conf->Skin_file)))
 | 
			
		||||
  if ((return_code=Save_INI_set_strings (old_file,new_file,buffer,"Skin_file",conf->Skin_file)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
    
 | 
			
		||||
  if ((return_code=Save_INI_set_strings (Ancien_fichier,Nouveau_fichier,buffer,"Font_file",conf->Font_file)))
 | 
			
		||||
  if ((return_code=Save_INI_set_strings (old_file,new_file,buffer,"Font_file",conf->Font_file)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Grid_XOR_color);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Grid_XOR_color",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Grid_XOR_color",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(Pixel_ratio);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Pixel_ratio",1,values,0))) {
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Pixel_ratio",1,values,0))) {
 | 
			
		||||
    DEBUG("saving pixel ratio",return_code);
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
  }
 | 
			
		||||
@ -670,14 +672,37 @@ int Save_INI(T_Config * conf)
 | 
			
		||||
  for (; index<8;index++)
 | 
			
		||||
    values[0] |= (1<<index);
 | 
			
		||||
    
 | 
			
		||||
  if ((return_code=Save_INI_set_values (Ancien_fichier,Nouveau_fichier,buffer,"Menubars_visible",1,values,0)))
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Menubars_visible",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
 | 
			
		||||
  values[0]=(conf->Right_click_colorpick);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Right_click_colorpick",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
    
 | 
			
		||||
  values[0]=(conf->Sync_views);
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Sync_views",1,values,1)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
    
 | 
			
		||||
  switch(conf->Swap_buttons)
 | 
			
		||||
  {
 | 
			
		||||
      case MOD_CTRL:
 | 
			
		||||
        values[0]=1;
 | 
			
		||||
        break;
 | 
			
		||||
      case MOD_ALT:
 | 
			
		||||
        values[0]=2;
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        values[0]=0;
 | 
			
		||||
  }
 | 
			
		||||
  if ((return_code=Save_INI_set_values (old_file,new_file,buffer,"Swap_buttons",1,values,0)))
 | 
			
		||||
    goto Erreur_Retour;
 | 
			
		||||
  
 | 
			
		||||
  // Insert new values here
 | 
			
		||||
  
 | 
			
		||||
  Save_INI_flush(old_file,new_file,buffer);
 | 
			
		||||
 | 
			
		||||
  Save_INI_flush(Ancien_fichier,Nouveau_fichier,buffer);
 | 
			
		||||
 | 
			
		||||
  fclose(Nouveau_fichier);
 | 
			
		||||
  fclose(Ancien_fichier);
 | 
			
		||||
  fclose(new_file);
 | 
			
		||||
  fclose(old_file);
 | 
			
		||||
 | 
			
		||||
  // On efface le fichier temporaire <=> Ancienne version du .INI
 | 
			
		||||
  if (ini_file_exists)
 | 
			
		||||
@ -689,8 +714,8 @@ int Save_INI(T_Config * conf)
 | 
			
		||||
 | 
			
		||||
  Erreur_Retour:
 | 
			
		||||
 | 
			
		||||
    fclose(Nouveau_fichier);
 | 
			
		||||
    fclose(Ancien_fichier);
 | 
			
		||||
    fclose(new_file);
 | 
			
		||||
    fclose(old_file);
 | 
			
		||||
    free(buffer);
 | 
			
		||||
    return return_code;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
@ -23,6 +24,15 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
#include <SDL_endian.h>
 | 
			
		||||
#if defined(__WIN32__)
 | 
			
		||||
    #include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
// There is no WM on the GP2X...
 | 
			
		||||
#ifndef __GP2X__
 | 
			
		||||
    #include <SDL_syswm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
@ -42,14 +52,21 @@
 | 
			
		||||
#ifndef UPDATE_METHOD
 | 
			
		||||
  #if defined(__macosx__)
 | 
			
		||||
    #define UPDATE_METHOD     UPDATE_METHOD_FULL_PAGE
 | 
			
		||||
  #elif defined(__MINT__)
 | 
			
		||||
    #define UPDATE_METHOD     UPDATE_METHOD_CUMULATED
 | 
			
		||||
  #else
 | 
			
		||||
    #define UPDATE_METHOD     UPDATE_METHOD_CUMULATED
 | 
			
		||||
  #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
volatile int Allow_colorcycling=1;
 | 
			
		||||
 | 
			
		||||
/// Sets the new screen/window dimensions.
 | 
			
		||||
void Set_mode_SDL(int *width, int *height, int fullscreen)
 | 
			
		||||
{
 | 
			
		||||
  static SDL_Cursor* cur = NULL;
 | 
			
		||||
  static byte cursorData = 0;
 | 
			
		||||
 | 
			
		||||
  Screen_SDL=SDL_SetVideoMode(*width,*height,8,(fullscreen?SDL_FULLSCREEN:0)|SDL_RESIZABLE);
 | 
			
		||||
  if(Screen_SDL != NULL)
 | 
			
		||||
  {
 | 
			
		||||
@ -66,7 +83,15 @@ void Set_mode_SDL(int *width, int *height, int fullscreen)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG("Error: Unable to change video mode!",0);
 | 
			
		||||
  }
 | 
			
		||||
  SDL_ShowCursor(0); // Hide the SDL mouse cursor, we use our own
 | 
			
		||||
 | 
			
		||||
  // Trick borrowed to Barrage (http://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg737265.html) :
 | 
			
		||||
  // Showing the cursor but setting it to fully transparent allows us to get absolute mouse coordinates,
 | 
			
		||||
  // this means we can use tablet in fullscreen mode.
 | 
			
		||||
  SDL_ShowCursor(1); // Hide the SDL mouse cursor, we use our own
 | 
			
		||||
 | 
			
		||||
  SDL_FreeCursor(cur);
 | 
			
		||||
  cur = SDL_CreateCursor(&cursorData, &cursorData, 1,1,0,0);
 | 
			
		||||
  SDL_SetCursor(cur);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if (UPDATE_METHOD == UPDATE_METHOD_CUMULATED)
 | 
			
		||||
@ -194,16 +219,36 @@ byte Get_SDL_pixel_8(SDL_Surface *bmp, int x, int y)
 | 
			
		||||
  return ((byte *)(bmp->pixels))[(y*bmp->pitch+x)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Writes a pixel in a 8-bit SDL surface.
 | 
			
		||||
void Set_SDL_pixel_8(SDL_Surface *bmp, int x, int y, byte color)
 | 
			
		||||
{
 | 
			
		||||
  ((byte *)(bmp->pixels))[(y*bmp->pitch+x)]=color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Reads a pixel in a multi-byte SDL surface.
 | 
			
		||||
dword Get_SDL_pixel_hicolor(SDL_Surface *bmp, int x, int y)
 | 
			
		||||
{
 | 
			
		||||
  byte * ptr;
 | 
			
		||||
  
 | 
			
		||||
  switch(bmp->format->BytesPerPixel)
 | 
			
		||||
  {
 | 
			
		||||
    case 4:
 | 
			
		||||
    default:
 | 
			
		||||
      return *((dword *)((byte *)bmp->pixels+(y*bmp->pitch+x*4)));
 | 
			
		||||
    case 3:
 | 
			
		||||
      return *(((dword *)((byte *)bmp->pixels+(y*bmp->pitch+x*3)))) & 0xFFFFFF;
 | 
			
		||||
      // Reading a 4-byte number starting at an address that isn't a multiple
 | 
			
		||||
      // of 2 (or 4?) is not supported on Caanoo console at least (ARM CPU)
 | 
			
		||||
      // So instead, we will read the 3 individual bytes, and re-construct the
 | 
			
		||||
      // "dword" expected by SDL.
 | 
			
		||||
      ptr = ((byte *)bmp->pixels)+(y*bmp->pitch+x*3);
 | 
			
		||||
      #ifdef SDL_LIL_ENDIAN
 | 
			
		||||
      // Read ABC, output _CBA : Most Significant Byte is zero.
 | 
			
		||||
      return (*ptr) | (*(ptr+1)<<8) | (*(ptr+2)<<16);
 | 
			
		||||
      #else
 | 
			
		||||
      // Read ABC, output ABC_ : Least Significant Byte is zero.
 | 
			
		||||
      return ((*ptr)<<24) | (*(ptr+1)<<16) | (*(ptr+2)<<8);
 | 
			
		||||
      #endif
 | 
			
		||||
    case 2:
 | 
			
		||||
      return *((word *)((byte *)bmp->pixels+(y*bmp->pitch+x*2)));
 | 
			
		||||
  }
 | 
			
		||||
@ -257,3 +302,18 @@ void Clear_border(byte color)
 | 
			
		||||
  }  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Activates or desactivates file drag-dropping in program window.
 | 
			
		||||
void Allow_drag_and_drop(int flag)
 | 
			
		||||
{
 | 
			
		||||
  // Inform Windows that we accept drag-n-drop events or not
 | 
			
		||||
  #ifdef __WIN32__
 | 
			
		||||
	SDL_SysWMinfo wminfo;
 | 
			
		||||
	HWND hwnd;
 | 
			
		||||
	
 | 
			
		||||
	SDL_VERSION(&wminfo.version);
 | 
			
		||||
	SDL_GetWMInfo(&wminfo);
 | 
			
		||||
	hwnd = wminfo.window;
 | 
			
		||||
	DragAcceptFiles(hwnd,flag?TRUE:FALSE);
 | 
			
		||||
	SDL_EventState (SDL_SYSWMEVENT,flag?SDL_ENABLE:SDL_DISABLE );
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
@ -56,6 +56,8 @@ SDL_Color Color_to_SDL_color(byte);
 | 
			
		||||
byte Get_SDL_pixel_8(SDL_Surface *bmp, int x, int y);
 | 
			
		||||
/// Reads a pixel in a multi-byte SDL surface.
 | 
			
		||||
dword Get_SDL_pixel_hicolor(SDL_Surface *bmp, int x, int y);
 | 
			
		||||
/// Writes a pixel in a 8-bit SDL surface.
 | 
			
		||||
void Set_SDL_pixel_8(SDL_Surface *bmp, int x, int y, byte color);
 | 
			
		||||
/// Convert a SDL Palette to a grafx2 palette
 | 
			
		||||
void Get_SDL_Palette(const SDL_Palette * sdl_palette, T_Palette palette);
 | 
			
		||||
 | 
			
		||||
@ -65,4 +67,9 @@ void Get_SDL_Palette(const SDL_Palette * sdl_palette, T_Palette palette);
 | 
			
		||||
/// size, eg: 3x3 pixels in 1024x768 leaves 1 column on the right, 0 rows on bottom.
 | 
			
		||||
void Clear_border(byte color);
 | 
			
		||||
  
 | 
			
		||||
extern volatile int Allow_colorcycling;
 | 
			
		||||
 | 
			
		||||
/// Activates or desactivates file drag-dropping in program window.
 | 
			
		||||
void Allow_drag_and_drop(int flag);
 | 
			
		||||
 | 
			
		||||
#endif // SDLSCREEN_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								src/setup.c
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								src/setup.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -35,6 +36,9 @@
 | 
			
		||||
  #import <sys/param.h>
 | 
			
		||||
#elif defined(__FreeBSD__)
 | 
			
		||||
  #import <sys/param.h>
 | 
			
		||||
#elif defined(__MINT__)
 | 
			
		||||
    #include <mint/osbind.h>
 | 
			
		||||
    #include <mint/sysbind.h>
 | 
			
		||||
#elif defined(__linux__)
 | 
			
		||||
  #include <limits.h>
 | 
			
		||||
  #include <unistd.h>
 | 
			
		||||
@ -44,7 +48,7 @@
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__GP2X__)
 | 
			
		||||
#if defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
    // This is a random default value ...
 | 
			
		||||
    #define PATH_MAX 32768
 | 
			
		||||
#endif
 | 
			
		||||
@ -84,7 +88,16 @@ void Set_program_directory(ARG_UNUSED const char * argv0,char * program_dir)
 | 
			
		||||
  // AmigaOS and alike: hard-coded volume name.
 | 
			
		||||
  #elif defined(__amigaos4__) || defined(__AROS__) || defined(__MORPHOS__) || defined(__amigaos__)
 | 
			
		||||
    strcpy(program_dir,"PROGDIR:");
 | 
			
		||||
  #elif defined(__MINT__)
 | 
			
		||||
 | 
			
		||||
  static char path[1024]={0};
 | 
			
		||||
  char currentDrive='A';
 | 
			
		||||
  currentDrive=currentDrive+Dgetdrv();
 | 
			
		||||
  
 | 
			
		||||
  Dgetpath(path,0);
 | 
			
		||||
  sprintf(program_dir,"%c:\%s",currentDrive,path);
 | 
			
		||||
  // Append trailing slash
 | 
			
		||||
  strcat(program_dir,PATH_SEPARATOR);
 | 
			
		||||
  // Linux: argv[0] unreliable
 | 
			
		||||
  #elif defined(__linux__)
 | 
			
		||||
  if (argv0[0]!='/')
 | 
			
		||||
@ -115,9 +128,14 @@ void Set_data_directory(const char * program_dir, char * data_dir)
 | 
			
		||||
  #if defined(__macosx__)
 | 
			
		||||
    strcat(data_dir,"Contents/Resources/");
 | 
			
		||||
  // On GP2X, executable is not in bin/
 | 
			
		||||
  #elif defined (__gp2x__)
 | 
			
		||||
  #elif defined (__GP2X__) || defined (__gp2x__) || defined (__WIZ__) || defined (__CAANOO__)
 | 
			
		||||
    strcat(data_dir,"share/grafx2/");
 | 
			
		||||
  //on tos the same directory
 | 
			
		||||
  #elif defined (__MINT__)
 | 
			
		||||
    strcpy(data_dir, program_dir);
 | 
			
		||||
  // All other targets, program is in a "bin" subdirectory
 | 
			
		||||
  #elif defined (__AROS__)
 | 
			
		||||
    strcat(data_dir,"/share/grafx2/");
 | 
			
		||||
  #else
 | 
			
		||||
    strcat(data_dir,"../share/grafx2/");
 | 
			
		||||
  #endif
 | 
			
		||||
@ -140,21 +158,23 @@ void Set_config_directory(const char * program_dir, char * config_dir)
 | 
			
		||||
  #if defined(__amigaos4__) || defined(__AROS__)
 | 
			
		||||
    strcpy(config_dir,"PROGDIR:");
 | 
			
		||||
  // GP2X
 | 
			
		||||
  #elif defined(__GP2X__)
 | 
			
		||||
  #elif defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__)
 | 
			
		||||
    // On the GP2X, the program is installed to the sdcard, and we don't want to mess with the system tree which is
 | 
			
		||||
    // on an internal flash chip. So, keep these settings locals.
 | 
			
		||||
    strcpy(config_dir,program_dir);
 | 
			
		||||
  #elif defined(__MINT__)  
 | 
			
		||||
    strcpy(config_dir,program_dir);
 | 
			
		||||
  #else
 | 
			
		||||
    char filename[MAX_PATH_CHARACTERS];
 | 
			
		||||
 | 
			
		||||
    // In priority: check root directory
 | 
			
		||||
    strcpy(config_dir, program_dir);
 | 
			
		||||
    // On all these targets except OSX and GP2X, the executable is in ./bin
 | 
			
		||||
    #if !defined(__macosx__) && !defined(__gp2x__)
 | 
			
		||||
      strcat(config_dir, "../");
 | 
			
		||||
    // On all the remaining targets except OSX, the executable is in ./bin
 | 
			
		||||
    #if !defined(__macosx__)
 | 
			
		||||
    strcat(config_dir, "../");
 | 
			
		||||
    #endif
 | 
			
		||||
    strcpy(filename, config_dir);
 | 
			
		||||
    strcat(filename, "gfx2.cfg");
 | 
			
		||||
    strcat(filename, CONFIG_FILENAME);
 | 
			
		||||
 | 
			
		||||
    if (!File_exists(filename))
 | 
			
		||||
    {
 | 
			
		||||
@ -171,6 +191,10 @@ void Set_config_directory(const char * program_dir, char * config_dir)
 | 
			
		||||
        // "~/Library/Preferences/com.googlecode.grafx2"
 | 
			
		||||
        const char* Config_SubDir = "Library/Preferences/com.googlecode.grafx2";
 | 
			
		||||
        config_parent_dir = getenv("HOME");
 | 
			
		||||
      #elif defined(__MINT__)
 | 
			
		||||
         const char* Config_SubDir = "";
 | 
			
		||||
         printf("GFX2.CFG not found in %s\n",filename);
 | 
			
		||||
         strcpy(config_parent_dir, config_dir);
 | 
			
		||||
      #else
 | 
			
		||||
        // "~/.grafx2"      
 | 
			
		||||
        const char* Config_SubDir = ".grafx2";
 | 
			
		||||
@ -203,7 +227,7 @@ void Set_config_directory(const char * program_dir, char * config_dir)
 | 
			
		||||
          {
 | 
			
		||||
            // Echec: on se rabat sur le repertoire de l'executable.
 | 
			
		||||
            strcpy(config_dir,program_dir);
 | 
			
		||||
            #if !defined(__macosx__) && !defined(__gp2x__)
 | 
			
		||||
            #if defined(__macosx__)
 | 
			
		||||
              strcat(config_dir, "../");
 | 
			
		||||
            #endif
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										103
									
								
								src/setup.h
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								src/setup.h
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Peter Gordon
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
@ -53,4 +54,104 @@ void Set_data_directory(const char * program_dir, char * data_dir);
 | 
			
		||||
/// IN: The directory containing the executable
 | 
			
		||||
/// OUT: Write into config_dir. Trailing / or \ is kept.
 | 
			
		||||
void Set_config_directory(const char * program_dir, char * config_dir);
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Name of the subdirectory containing fonts, under the data directory (::Set_data_directory())
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define FONTS_SUBDIRECTORY "FONTS"
 | 
			
		||||
#else
 | 
			
		||||
  #define FONTS_SUBDIRECTORY "fonts"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the subdirectory containing fonts, under the data directory (::Set_data_directory())
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define SKINS_SUBDIRECTORY "SKINS"
 | 
			
		||||
#else
 | 
			
		||||
  #define SKINS_SUBDIRECTORY "skins"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the binary file containing some configuration settings.
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define CONFIG_FILENAME "GFX2.CFG"
 | 
			
		||||
#else
 | 
			
		||||
  #define CONFIG_FILENAME "gfx2.cfg"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the text file containing some settings in INI format.
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define INI_FILENAME "GFX2.INI"
 | 
			
		||||
#else
 | 
			
		||||
  #define INI_FILENAME "gfx2.ini"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the backup of the INI file.
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define INISAVE_FILENAME "GFX2.$$$"
 | 
			
		||||
#else
 | 
			
		||||
  #define INISAVE_FILENAME "gfx2.$$$"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the default .INI file (read-only: gives .INI format and defaults)
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define INIDEF_FILENAME "GFX2DEF.INI"
 | 
			
		||||
#else
 | 
			
		||||
  #define INIDEF_FILENAME "gfx2def.ini"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Prefix for filenames of safety backups (main)
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define SAFETYBACKUP_PREFIX_A "A"
 | 
			
		||||
#else
 | 
			
		||||
  #define SAFETYBACKUP_PREFIX_A "a"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Prefix for filenames of safety backups (spare)
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define SAFETYBACKUP_PREFIX_B "B"
 | 
			
		||||
#else
 | 
			
		||||
  #define SAFETYBACKUP_PREFIX_B "b"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the image file that serves as an application icon.
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define GFX2_ICON_FILENAME "GFX2.GIF"
 | 
			
		||||
#else
 | 
			
		||||
  #define GFX2_ICON_FILENAME "gfx2.gif"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the image file for the default (and fallback) GUI skin.
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define DEFAULT_SKIN_FILENAME "SDPAINT.PNG"
 | 
			
		||||
#else
 | 
			
		||||
  #define DEFAULT_SKIN_FILENAME "skin_DPaint.png"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// Name of the image file for the default (and fallback) 8x8 font.
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define DEFAULT_FONT_FILENAME "FDPAINT.PNG"
 | 
			
		||||
#else
 | 
			
		||||
  #define DEFAULT_FONT_FILENAME "font_DPaint.png"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// File extension for safety backups
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define BACKUP_FILE_EXTENSION ".BKP"
 | 
			
		||||
#else
 | 
			
		||||
  #define BACKUP_FILE_EXTENSION ".bkp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// File prefix for fonts
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define FONT_PREFIX "F"
 | 
			
		||||
#else
 | 
			
		||||
  #define FONT_PREFIX "font_"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// File prefix for skins
 | 
			
		||||
#if defined (__MINT__)
 | 
			
		||||
  #define SKIN_PREFIX "S"
 | 
			
		||||
#else
 | 
			
		||||
  #define SKIN_PREFIX "skin_"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -348,7 +348,7 @@ short Wait_click_in_shade_table()
 | 
			
		||||
 | 
			
		||||
  while (selected_cell<0)
 | 
			
		||||
  {
 | 
			
		||||
    Get_input();
 | 
			
		||||
    Get_input(20);
 | 
			
		||||
 | 
			
		||||
    if ( (Mouse_K==LEFT_SIDE)
 | 
			
		||||
      && ( ( (Window_click_in_rectangle(8,127,263,179)) && (((((Mouse_Y-Window_pos_Y)/Menu_factor_Y)-127)%7)<4) )
 | 
			
		||||
@ -837,7 +837,7 @@ int Menu_shade(void)
 | 
			
		||||
 | 
			
		||||
      case 15 : // Saisie du pas
 | 
			
		||||
        Num2str(Shade_list[Shade_current].Step,str,3);
 | 
			
		||||
        Readline(276,176,str,3,1);
 | 
			
		||||
        Readline(276,176,str,3,INPUT_TYPE_INTEGER);
 | 
			
		||||
        temp=atoi(str);
 | 
			
		||||
        // On corrige le pas
 | 
			
		||||
        if (!temp)
 | 
			
		||||
@ -1089,7 +1089,7 @@ void Button_Quick_shade_menu(void)
 | 
			
		||||
 | 
			
		||||
      case 4 : // Saisie du pas
 | 
			
		||||
        Num2str(Quick_shade_step,str,3);
 | 
			
		||||
        Readline(42,21,str,3,1);
 | 
			
		||||
        Readline(42,21,str,3,INPUT_TYPE_INTEGER);
 | 
			
		||||
        temp=atoi(str);
 | 
			
		||||
        // On corrige le pas
 | 
			
		||||
        if (!temp)
 | 
			
		||||
 | 
			
		||||
@ -431,6 +431,9 @@ void Transparency_set(byte amount)
 | 
			
		||||
        break;
 | 
			
		||||
      case 2 :
 | 
			
		||||
        Effect_function=Effect_substractive_colorize;
 | 
			
		||||
        break;
 | 
			
		||||
      case 3 :
 | 
			
		||||
        Effect_function=Effect_alpha_colorize;
 | 
			
		||||
    }
 | 
			
		||||
    Shade_mode=0;
 | 
			
		||||
    Quick_shade_mode=0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										124
									
								
								src/struct.h
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								src/struct.h
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2007 Adrien Destugues
 | 
			
		||||
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
 | 
			
		||||
@ -73,14 +74,23 @@ typedef void (* Func_draw_brush) (byte *,word,word,word,word,word,word,byte,word
 | 
			
		||||
typedef void (* Func_draw_list_item) (word,word,word,byte); ///< Draw an item inside a list button. This is done with a callback so it is possible to draw anything, as the list itself doesn't handle the content
 | 
			
		||||
 | 
			
		||||
/// A set of RGB values.
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  byte R; ///< Red
 | 
			
		||||
  byte G; ///< Green
 | 
			
		||||
  byte B; ///< Blue
 | 
			
		||||
} __attribute__((__packed__)) T_Components, T_Palette[256] ; ///< A complete 256-entry RGB palette (768 bytes).
 | 
			
		||||
#else
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  byte R; ///< Red
 | 
			
		||||
  byte G; ///< Green
 | 
			
		||||
  byte B; ///< Blue
 | 
			
		||||
} T_Components, T_Palette[256]; ///< A complete 256-entry RGB palette (768 bytes).
 | 
			
		||||
} T_Components, T_Palette[256] ; ///< A complete 256-entry RGB palette (768 bytes).
 | 
			
		||||
#pragma pack()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/// A normal rectangular button in windows and menus.
 | 
			
		||||
typedef struct T_Normal_button
 | 
			
		||||
@ -105,17 +115,18 @@ typedef struct T_Palette_button
 | 
			
		||||
  struct T_Palette_button * Next;///< Pointer to the next palette of current window.
 | 
			
		||||
} T_Palette_button;
 | 
			
		||||
 | 
			
		||||
/// A window control that represents a vertical scrollbar, with a slider, and two arrow buttons.
 | 
			
		||||
/// A window control that represents a scrollbar, with a slider, and two arrow buttons.
 | 
			
		||||
typedef struct T_Scroller_button
 | 
			
		||||
{
 | 
			
		||||
  short Number;                   ///< Unique identifier for all controls
 | 
			
		||||
  byte Is_horizontal;             ///< Boolean: True if slider is horizontal instead of vertical.
 | 
			
		||||
  word Pos_X;                     ///< Coordinate for top of button, relative to the window, before scaling.
 | 
			
		||||
  word Pos_Y;                     ///< Coordinate for left of button, relative to the window, before scaling.
 | 
			
		||||
  word Height;                    ///< Height before scaling.
 | 
			
		||||
  word Length;                    ///< Length before scaling.
 | 
			
		||||
  word Nb_elements;               ///< Number of distinct values it can take.
 | 
			
		||||
  word Nb_visibles;               ///< If this slider is meant to show several elements of a collection, this is their number (otherwise, it's 1).
 | 
			
		||||
  word Position;                  ///< Current position of the slider: which item it's pointing.
 | 
			
		||||
  word Cursor_height;             ///< Vertical dimension of the slider, in pixels before scaling.
 | 
			
		||||
  word Cursor_length;             ///< Dimension of the slider, in pixels before scaling.
 | 
			
		||||
  struct T_Scroller_button * Next;///< Pointer to the next scroller of current window.
 | 
			
		||||
} T_Scroller_button;
 | 
			
		||||
 | 
			
		||||
@ -162,12 +173,20 @@ typedef struct T_Dropdown_button
 | 
			
		||||
/// Data for one item (file, directory) in a fileselector.
 | 
			
		||||
typedef struct T_Fileselector_item
 | 
			
		||||
{
 | 
			
		||||
  char Short_name[19]; ///< Name to display.
 | 
			
		||||
  char Full_name[256]; ///< Filesystem value.
 | 
			
		||||
  byte Type;           ///< Type of item: 0 = File, 1 = Directory, 2 = Drive
 | 
			
		||||
  byte Icon;           ///< One of ::ICON_TYPES, ICON_NONE for none.
 | 
			
		||||
 | 
			
		||||
  struct T_Fileselector_item * Next;    ///< Pointer to next item of the current fileselector.
 | 
			
		||||
  struct T_Fileselector_item * Previous;///< Pointer to previous item of the current fileselector.
 | 
			
		||||
  
 | 
			
		||||
  word  Length_short_name; ///< Number of bytes allocated for :Short_name
 | 
			
		||||
  #if __GNUC__ < 3
 | 
			
		||||
  char Short_name[0]; ///< Name to display.
 | 
			
		||||
#else
 | 
			
		||||
  char Short_name[]; ///< Name to display.
 | 
			
		||||
#endif
 | 
			
		||||
  // No field after Short_name[] ! Dynamic allocation according to name length.
 | 
			
		||||
} T_Fileselector_item;
 | 
			
		||||
 | 
			
		||||
/// Data for a fileselector
 | 
			
		||||
@ -201,6 +220,25 @@ typedef struct T_List_button
 | 
			
		||||
  struct T_List_button * Next;    ///< Pointer to the next list button of current window.
 | 
			
		||||
} T_List_button;
 | 
			
		||||
 | 
			
		||||
/// A stackable window (editor screen)
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  word Pos_X;
 | 
			
		||||
  word Pos_Y;
 | 
			
		||||
  word Width;
 | 
			
		||||
  word Height;
 | 
			
		||||
  word Nb_buttons;
 | 
			
		||||
  T_Normal_button   *Normal_button_list;
 | 
			
		||||
  T_Palette_button  *Palette_button_list;
 | 
			
		||||
  T_Scroller_button *Scroller_button_list;
 | 
			
		||||
  T_Special_button  *Special_button_list;
 | 
			
		||||
  T_Dropdown_button *Dropdown_button_list;
 | 
			
		||||
  T_List_button     *List_button_list;
 | 
			
		||||
  int Attribute1;
 | 
			
		||||
  int Attribute2;
 | 
			
		||||
  byte Draggable;
 | 
			
		||||
} T_Window;
 | 
			
		||||
 | 
			
		||||
/// Data for one line of the "Help" screens.
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char Line_type;     ///< Kind of line: 'N' for normal line, 'S' for a bold line, 'K' for a line with keyboard shortcut, 'T' and '-' for upper and lower titles.
 | 
			
		||||
@ -223,7 +261,15 @@ typedef struct
 | 
			
		||||
  dword Inverse;  ///< Boolean, true if the gradient goes in descending order
 | 
			
		||||
  dword Mix;      ///< Amount of randomness to add to the mix (0-255)
 | 
			
		||||
  dword Technique;///< Gradient technique: 0 (no pattern) 1 (dithering), or 2 (big dithering)
 | 
			
		||||
} T_Gradient_array;
 | 
			
		||||
  byte  Speed;    ///< Speed of cycling. 0 for disabled, 1-64 otherwise.
 | 
			
		||||
} T_Gradient_range;
 | 
			
		||||
 | 
			
		||||
/// Data for a full set of gradients.
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  int Used; ///< Reference count
 | 
			
		||||
  T_Gradient_range Range[16];
 | 
			
		||||
}  T_Gradient_array;
 | 
			
		||||
 | 
			
		||||
/// Data for one setting of shade. Warning, this one is saved/loaded as binary.
 | 
			
		||||
typedef struct
 | 
			
		||||
@ -233,7 +279,6 @@ typedef struct
 | 
			
		||||
  byte Mode;      ///< Shade mode: Normal, Loop, or No-saturation see ::SHADE_MODES
 | 
			
		||||
} T_Shade;
 | 
			
		||||
 | 
			
		||||
#pragma pack(1) // is it useful ?
 | 
			
		||||
/// Data for one fullscreen video mode in configuration file. Warning, this one is saved/loaded as binary.
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
@ -242,8 +287,7 @@ typedef struct
 | 
			
		||||
  word Height;///< Videomode height in pixels. 
 | 
			
		||||
} T_Config_video_mode;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Header for gfx2.cfg. Warning, this one is saved/loaded as binary.
 | 
			
		||||
/// Header for gfx2.cfg
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  char Signature[3]; ///< Signature for the file format. "CFG".
 | 
			
		||||
@ -253,24 +297,22 @@ typedef struct
 | 
			
		||||
  byte Beta2;        ///< Major beta version number (ex: 5)
 | 
			
		||||
} T_Config_header;
 | 
			
		||||
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
/// Header for a config chunk in for gfx2.cfg. Warning, this one is saved/loaded as binary.
 | 
			
		||||
/// Header for a config chunk in for gfx2.cfg
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  byte Number; ///< Section identfier. Possible values are in enum ::CHUNKS_CFG
 | 
			
		||||
  word Size;   ///< Size of the configuration block that follows, in bytes.
 | 
			
		||||
} T_Config_chunk;
 | 
			
		||||
 | 
			
		||||
#pragma pack(1)
 | 
			
		||||
/// Configuration for one keyboard shortcut in gfx2.cfg. Warning, this one is saved/loaded as binary.
 | 
			
		||||
 | 
			
		||||
/// Configuration for one keyboard shortcut in gfx2.cfg
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  word Number; ///< Indicates the shortcut action. This is a number starting from 0, which matches ::T_Key_config.Number
 | 
			
		||||
  word Key;    ///< Keyboard shortcut: SDLK_something, or -1 for none
 | 
			
		||||
  word Key2;   ///< Alternate keyboard shortcut: SDLK_something, or -1 for none
 | 
			
		||||
} T_Config_shortcut_info;
 | 
			
		||||
#pragma pack()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// This structure holds all the settings saved and loaded as gfx2.ini.
 | 
			
		||||
typedef struct
 | 
			
		||||
@ -321,6 +363,10 @@ typedef struct
 | 
			
		||||
  word Double_click_speed;               ///< Maximum delay for double-click, in ms.
 | 
			
		||||
  word Double_key_speed;                 ///< Maximum delay for double-keypress, in ms.
 | 
			
		||||
  byte Grid_XOR_color;                   ///< XOR value to apply for grid color.
 | 
			
		||||
  byte Right_click_colorpick;            ///< Boolean, true to enable a "tablet" mode, where RMB acts as instant colorpicker
 | 
			
		||||
  byte Sync_views;                       ///< Boolean, true when the Main and Spare should share their viewport settings.
 | 
			
		||||
  byte Stylus_mode;                      ///< Boolean, true to tweak some tools (eg:Curve) for single-button stylus.
 | 
			
		||||
  word Swap_buttons;                     ///< Sets which key swaps mouse buttons : 0=none, or MOD_CTRL, or MOD_ALT.
 | 
			
		||||
} T_Config;
 | 
			
		||||
 | 
			
		||||
// Structures utilisées pour les descriptions de pages et de liste de pages.
 | 
			
		||||
@ -347,6 +393,7 @@ typedef struct T_Page
 | 
			
		||||
  byte      File_format;                        ///< File format, in enum ::FILE_FORMATS
 | 
			
		||||
  struct T_Page *Next; ///< Pointer to the next backup
 | 
			
		||||
  struct T_Page *Prev; ///< Pointer to the previous backup
 | 
			
		||||
  T_Gradient_array *Gradients; ///< Pointer to the gradients used by the image.
 | 
			
		||||
  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
 | 
			
		||||
@ -381,6 +428,7 @@ typedef struct
 | 
			
		||||
  word Height;
 | 
			
		||||
  byte * Brush; /// < Color brush (if any)
 | 
			
		||||
  T_Palette Palette;
 | 
			
		||||
  byte Colormap[256];
 | 
			
		||||
  byte Transp_color;
 | 
			
		||||
} T_Brush_template;
 | 
			
		||||
 | 
			
		||||
@ -396,21 +444,6 @@ typedef struct
 | 
			
		||||
  /// Graphic resources for the mouse cursor.
 | 
			
		||||
  byte Cursor_sprite[NB_CURSOR_SPRITES][CURSOR_SPRITE_HEIGHT][CURSOR_SPRITE_WIDTH];
 | 
			
		||||
 | 
			
		||||
  // Preset paintbrushes
 | 
			
		||||
  
 | 
			
		||||
  /// Graphic resources for the preset paintbrushes.
 | 
			
		||||
  byte  Paintbrush_sprite [NB_PAINTBRUSH_SPRITES][PAINTBRUSH_HEIGHT][PAINTBRUSH_WIDTH];
 | 
			
		||||
  /// Width of the preset paintbrushes.
 | 
			
		||||
  word  Preset_paintbrush_width[NB_PAINTBRUSH_SPRITES];
 | 
			
		||||
  /// Height of the preset paintbrushes.
 | 
			
		||||
  word  Preset_paintbrush_height[NB_PAINTBRUSH_SPRITES];
 | 
			
		||||
  /// Type of the preset paintbrush: index in enum PAINTBRUSH_SHAPES
 | 
			
		||||
  byte  Paintbrush_type[NB_PAINTBRUSH_SPRITES];
 | 
			
		||||
  /// Brush handle for the preset brushes. Generally ::Preset_paintbrush_width[]/2
 | 
			
		||||
  word  Preset_paintbrush_offset_X[NB_PAINTBRUSH_SPRITES];
 | 
			
		||||
  /// Brush handle for the preset brushes. Generally ::Preset_paintbrush_height[]/2
 | 
			
		||||
  word  Preset_paintbrush_offset_Y[NB_PAINTBRUSH_SPRITES];
 | 
			
		||||
 | 
			
		||||
  // Sieve patterns
 | 
			
		||||
  
 | 
			
		||||
  /// Preset sieve patterns, stored as binary (one word per line)
 | 
			
		||||
@ -419,13 +452,13 @@ typedef struct
 | 
			
		||||
  // Menu and other graphics
 | 
			
		||||
  
 | 
			
		||||
  /// Bitmap data for the menu, a single rectangle.
 | 
			
		||||
  byte Menu_block[35][MENU_WIDTH];
 | 
			
		||||
  byte Layerbar_block[10][144];
 | 
			
		||||
  byte Statusbar_block[9][20];
 | 
			
		||||
  byte Menu_block[3][35][MENU_WIDTH];
 | 
			
		||||
  byte Layerbar_block[3][10][144];
 | 
			
		||||
  byte Statusbar_block[3][9][20];
 | 
			
		||||
  /// Bitmap data for the icons that are displayed over the menu.
 | 
			
		||||
  byte Menu_sprite[NB_MENU_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH];
 | 
			
		||||
  byte Menu_sprite[2][NB_MENU_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH];
 | 
			
		||||
  /// Bitmap data for the different "effects" icons.
 | 
			
		||||
  byte Effect_sprite[NB_EFFECTS_SPRITES][MENU_SPRITE_HEIGHT][MENU_SPRITE_WIDTH];
 | 
			
		||||
  byte Effect_sprite[NB_EFFECTS_SPRITES][EFFECT_SPRITE_HEIGHT][EFFECT_SPRITE_WIDTH];
 | 
			
		||||
  /// Bitmap data for the different Layer icons.
 | 
			
		||||
  byte Layer_sprite[3][16][LAYER_SPRITE_HEIGHT][LAYER_SPRITE_WIDTH];
 | 
			
		||||
  /// Bitmap data for the Grafx2 logo that appears on splash screen. All 256 colors allowed.
 | 
			
		||||
@ -458,16 +491,33 @@ typedef struct
 | 
			
		||||
  /// Transparent GUI color index in skin file
 | 
			
		||||
  byte Color_trans;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} T_Gui_skin;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  // Preset paintbrushes
 | 
			
		||||
  
 | 
			
		||||
  /// Graphic resources for the preset paintbrushes.
 | 
			
		||||
  byte  Sprite[PAINTBRUSH_HEIGHT][PAINTBRUSH_WIDTH];
 | 
			
		||||
  /// Width of the preset paintbrushes.
 | 
			
		||||
  word  Width;
 | 
			
		||||
  /// Height of the preset paintbrushes.
 | 
			
		||||
  word  Height;
 | 
			
		||||
  /// Type of the preset paintbrush: index in enum PAINTBRUSH_SHAPES
 | 
			
		||||
  byte  Shape;
 | 
			
		||||
  /// Brush handle for the preset brushes. Generally ::Width[]/2
 | 
			
		||||
  word  Offset_X;
 | 
			
		||||
  /// Brush handle for the preset brushes. Generally ::Height[]/2
 | 
			
		||||
  word  Offset_Y;
 | 
			
		||||
 | 
			
		||||
} T_Paintbrush;
 | 
			
		||||
 | 
			
		||||
// A menubar.
 | 
			
		||||
typedef struct {
 | 
			
		||||
  word Width;
 | 
			
		||||
  word Height;
 | 
			
		||||
  byte Visible;
 | 
			
		||||
  word Top; ///< Relative to the top line of the menu, hidden bars don't count.
 | 
			
		||||
  byte* Skin;
 | 
			
		||||
  byte* Skin[3]; ///< [0] has normal buttons, [1] has selected buttons, [2] is current.
 | 
			
		||||
  word Skin_width;
 | 
			
		||||
  byte Last_button_index;
 | 
			
		||||
} T_Menu_Bar;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										245
									
								
								src/text.c
									
									
									
									
									
								
							
							
						
						
									
										245
									
								
								src/text.c
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2011 Pawel Góralski
 | 
			
		||||
    Copyright 2008 Yves Rizoud
 | 
			
		||||
    Copyright 2008 Franck Charlet
 | 
			
		||||
    Copyright 2008 Adrien Destugues
 | 
			
		||||
@ -36,19 +37,18 @@
 | 
			
		||||
  #include <SDL_ttf.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(__linux__)
 | 
			
		||||
#if defined(__macosx__)
 | 
			
		||||
#if defined(__CAANOO__) || defined(__WIZ__) || defined(__GP2X__)
 | 
			
		||||
// No X11
 | 
			
		||||
#elif defined(__macosx__)
 | 
			
		||||
  #include <Carbon/Carbon.h>
 | 
			
		||||
  #import <corefoundation/corefoundation.h>
 | 
			
		||||
  #import <sys/param.h>
 | 
			
		||||
#else
 | 
			
		||||
#elif defined(__linux__)
 | 
			
		||||
  #include <X11/Xlib.h>
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <SDL_image.h>
 | 
			
		||||
// SFont
 | 
			
		||||
#include "SFont.h"
 | 
			
		||||
 | 
			
		||||
#include "struct.h"
 | 
			
		||||
@ -56,6 +56,9 @@
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "errors.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "setup.h"
 | 
			
		||||
 | 
			
		||||
typedef struct T_Font
 | 
			
		||||
{
 | 
			
		||||
@ -282,7 +285,7 @@ void Init_text(void)
 | 
			
		||||
  Nb_fonts=0;
 | 
			
		||||
  // Parcours du répertoire "fonts"
 | 
			
		||||
  strcpy(directory_name, Data_directory);
 | 
			
		||||
  strcat(directory_name, "fonts");
 | 
			
		||||
  strcat(directory_name, FONTS_SUBDIRECTORY);
 | 
			
		||||
  For_each_file(directory_name, Add_font);
 | 
			
		||||
  
 | 
			
		||||
  #if defined(__WIN32__)
 | 
			
		||||
@ -321,6 +324,8 @@ void Init_text(void)
 | 
			
		||||
      CFRelease(url);
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
  #elif defined(__CAANOO__) || defined(__WIZ__) || defined(__GP2X__)
 | 
			
		||||
  // No X11 : Only use fonts from Grafx2
 | 
			
		||||
  #elif defined(__linux__)
 | 
			
		||||
    #ifndef NOTTF
 | 
			
		||||
       #define USE_XLIB
 | 
			
		||||
@ -343,15 +348,22 @@ void Init_text(void)
 | 
			
		||||
    #ifndef NOTTF
 | 
			
		||||
      For_each_file( "FONTS:_TrueType", Add_font );
 | 
			
		||||
    #endif
 | 
			
		||||
  #elif defined(__BEOS__) || defined(__HAIKU__)
 | 
			
		||||
  #elif defined(__BEOS__)
 | 
			
		||||
    #ifndef NOTTF
 | 
			
		||||
      For_each_file("/etc/fonts/ttfonts", Add_font);
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
  #elif defined(__HAIKU__)
 | 
			
		||||
    #ifndef NOTTF
 | 
			
		||||
      For_each_file("/boot/system/data/fonts/ttfonts/", Add_font);
 | 
			
		||||
    #endif
 | 
			
		||||
  #elif defined(__SKYOS__)
 | 
			
		||||
    #ifndef NOTTF
 | 
			
		||||
      For_each_file("/boot/system/fonts", Add_font);
 | 
			
		||||
    #endif
 | 
			
		||||
  #elif defined(__MINT__)
 | 
			
		||||
    #ifndef NOTTF
 | 
			
		||||
      For_each_file("C:/BTFONTS", Add_font);
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
  #endif
 | 
			
		||||
}
 | 
			
		||||
@ -368,17 +380,15 @@ int TrueType_is_supported()
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
#ifndef NOTTF
 | 
			
		||||
byte *Render_text_TTF(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height)
 | 
			
		||||
byte *Render_text_TTF(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height, T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
 TTF_Font *font;
 | 
			
		||||
  SDL_Surface * TexteColore;
 | 
			
		||||
  SDL_Surface * Texte8Bit;
 | 
			
		||||
  TTF_Font *font;
 | 
			
		||||
  SDL_Surface * text_surface;
 | 
			
		||||
  byte * new_brush;
 | 
			
		||||
  int index;
 | 
			
		||||
  int style;
 | 
			
		||||
  
 | 
			
		||||
  SDL_Color Couleur_Avant;
 | 
			
		||||
  SDL_Color Couleur_Arriere;
 | 
			
		||||
  SDL_Color fg_color;
 | 
			
		||||
  SDL_Color bg_color;
 | 
			
		||||
 | 
			
		||||
  // Chargement de la fonte
 | 
			
		||||
  font=TTF_OpenFont(Font_name(font_number), size);
 | 
			
		||||
@ -386,6 +396,7 @@ byte *Render_text_TTF(const char *str, int font_number, int size, int antialias,
 | 
			
		||||
  {
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Style
 | 
			
		||||
  style=0;
 | 
			
		||||
  if (italic)
 | 
			
		||||
@ -393,82 +404,170 @@ byte *Render_text_TTF(const char *str, int font_number, int size, int antialias,
 | 
			
		||||
  if (bold)
 | 
			
		||||
    style|=TTF_STYLE_BOLD;
 | 
			
		||||
  TTF_SetFontStyle(font, style);
 | 
			
		||||
  // Couleurs
 | 
			
		||||
  if (antialias)
 | 
			
		||||
  {
 | 
			
		||||
    Couleur_Avant = Color_to_SDL_color(Fore_color);
 | 
			
		||||
    Couleur_Arriere = Color_to_SDL_color(Back_color);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    Couleur_Avant = Color_to_SDL_color(MC_White);
 | 
			
		||||
    Couleur_Arriere = Color_to_SDL_color(MC_Black);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  // Rendu du texte: crée une surface SDL RGB 24bits
 | 
			
		||||
  // Colors: Text will be generated as white on black.
 | 
			
		||||
  fg_color.r=fg_color.g=fg_color.b=255;
 | 
			
		||||
  bg_color.r=bg_color.g=bg_color.b=0;
 | 
			
		||||
  // The following is alpha, supposedly unused
 | 
			
		||||
  bg_color.unused=fg_color.unused=255;
 | 
			
		||||
  
 | 
			
		||||
  // Text rendering: creates a 8bit surface with its dedicated palette
 | 
			
		||||
  if (antialias)
 | 
			
		||||
    TexteColore=TTF_RenderText_Shaded(font, str, Couleur_Avant, Couleur_Arriere );
 | 
			
		||||
    text_surface=TTF_RenderText_Shaded(font, str, fg_color, bg_color );
 | 
			
		||||
  else
 | 
			
		||||
    TexteColore=TTF_RenderText_Solid(font, str, Couleur_Avant);
 | 
			
		||||
  if (!TexteColore)
 | 
			
		||||
    text_surface=TTF_RenderText_Solid(font, str, fg_color);
 | 
			
		||||
  if (!text_surface)
 | 
			
		||||
  {
 | 
			
		||||
    TTF_CloseFont(font);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  Texte8Bit=SDL_DisplayFormat(TexteColore);
 | 
			
		||||
 | 
			
		||||
  SDL_FreeSurface(TexteColore);
 | 
			
		||||
    
 | 
			
		||||
  new_brush=Surface_to_bytefield(Texte8Bit, NULL);
 | 
			
		||||
  new_brush=Surface_to_bytefield(text_surface, NULL);
 | 
			
		||||
  if (!new_brush)
 | 
			
		||||
  {
 | 
			
		||||
    SDL_FreeSurface(TexteColore);
 | 
			
		||||
    SDL_FreeSurface(Texte8Bit);
 | 
			
		||||
    SDL_FreeSurface(text_surface);
 | 
			
		||||
    TTF_CloseFont(font);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (!antialias)
 | 
			
		||||
  
 | 
			
		||||
  // Import palette
 | 
			
		||||
  Get_SDL_Palette(text_surface->format->palette, palette);
 | 
			
		||||
  
 | 
			
		||||
  if (antialias)
 | 
			
		||||
  {
 | 
			
		||||
    // Mappage des couleurs
 | 
			
		||||
    for (index=0; index < Texte8Bit->w * Texte8Bit->h; index++)
 | 
			
		||||
    int black_col;
 | 
			
		||||
    // Shaded text: X-Swap the color that is pure black with the BG color number,
 | 
			
		||||
    // so that the brush is immediately 'transparent'
 | 
			
		||||
    
 | 
			
		||||
    // Find black (c)
 | 
			
		||||
    for (black_col=0; black_col<256; black_col++)
 | 
			
		||||
    {
 | 
			
		||||
      if (*(new_brush+index) == MC_Black)
 | 
			
		||||
      *(new_brush+index)=Back_color;
 | 
			
		||||
      else if (*(new_brush+index) == MC_White)
 | 
			
		||||
      *(new_brush+index)=Fore_color;
 | 
			
		||||
      if (palette[black_col].R==0 && palette[black_col].G==0 && palette[black_col].B==0)
 | 
			
		||||
        break;
 | 
			
		||||
    } // If not found: c = 256 = 0 (byte)
 | 
			
		||||
    
 | 
			
		||||
    if (black_col != Back_color)
 | 
			
		||||
    {
 | 
			
		||||
      int c;
 | 
			
		||||
      byte colmap[256];
 | 
			
		||||
      // Swap palette entries
 | 
			
		||||
      
 | 
			
		||||
      SWAP_BYTES(palette[black_col].R, palette[Back_color].R)
 | 
			
		||||
      SWAP_BYTES(palette[black_col].G, palette[Back_color].G)
 | 
			
		||||
      SWAP_BYTES(palette[black_col].B, palette[Back_color].B)
 | 
			
		||||
      
 | 
			
		||||
      // Define a colormap
 | 
			
		||||
      for (c=0; c<256; c++)
 | 
			
		||||
        colmap[c]=c;
 | 
			
		||||
      
 | 
			
		||||
      // The swap
 | 
			
		||||
      colmap[black_col]=Back_color;
 | 
			
		||||
      colmap[Back_color]=black_col;
 | 
			
		||||
      
 | 
			
		||||
      Remap_general_lowlevel(colmap, new_brush, new_brush, text_surface->w,text_surface->h, text_surface->w);
 | 
			
		||||
      
 | 
			
		||||
      // Also, make the BG color in brush palette have same RGB values as
 | 
			
		||||
      // the current BG color : this will help for remaps.
 | 
			
		||||
      palette[Back_color].R=Main_palette[Back_color].R;
 | 
			
		||||
      palette[Back_color].G=Main_palette[Back_color].G;
 | 
			
		||||
      palette[Back_color].B=Main_palette[Back_color].B;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  *width=Texte8Bit->w;
 | 
			
		||||
  *height=Texte8Bit->h;
 | 
			
		||||
  SDL_FreeSurface(Texte8Bit);
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    // Solid text: Was rendered as white on black. Now map colors:
 | 
			
		||||
    // White becomes FG color, black becomes BG. 2-color palette.
 | 
			
		||||
    // Exception: if BG==FG, FG will be set to black or white - any different color.
 | 
			
		||||
    long index;
 | 
			
		||||
    byte new_fore=Fore_color;
 | 
			
		||||
 | 
			
		||||
    if (Fore_color==Back_color)
 | 
			
		||||
    {
 | 
			
		||||
      if (Main_palette[Back_color].R+Main_palette[Back_color].G+Main_palette[Back_color].B > 128*3)
 | 
			
		||||
        // Back color is rather light:
 | 
			
		||||
        new_fore=MC_Black;
 | 
			
		||||
      else
 | 
			
		||||
        // Back color is rather dark:
 | 
			
		||||
        new_fore=MC_White;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    for (index=0; index < text_surface->w * text_surface->h; index++)
 | 
			
		||||
    {
 | 
			
		||||
      if (palette[*(new_brush+index)].G < 128)
 | 
			
		||||
        *(new_brush+index)=Back_color;
 | 
			
		||||
      else
 | 
			
		||||
        *(new_brush+index)=new_fore;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Now copy the current palette to brushe's, for consistency
 | 
			
		||||
    // with the indices.
 | 
			
		||||
    memcpy(palette, Main_palette, sizeof(T_Palette));
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
  *width=text_surface->w;
 | 
			
		||||
  *height=text_surface->h;
 | 
			
		||||
  SDL_FreeSurface(text_surface);
 | 
			
		||||
  TTF_CloseFont(font);
 | 
			
		||||
  return new_brush;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte *Render_text_SFont(const char *str, int font_number, int *width, int *height)
 | 
			
		||||
byte *Render_text_SFont(const char *str, int font_number, int *width, int *height, T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
  SFont_Font *font;
 | 
			
		||||
  SDL_Surface * TexteColore;
 | 
			
		||||
  SDL_Surface * Texte8Bit;
 | 
			
		||||
  SDL_Surface *Surface_fonte;
 | 
			
		||||
  SDL_Surface * text_surface;
 | 
			
		||||
  SDL_Surface *font_surface;
 | 
			
		||||
  byte * new_brush;
 | 
			
		||||
  SDL_Rect rectangle;
 | 
			
		||||
 | 
			
		||||
  // Chargement de la fonte
 | 
			
		||||
  Surface_fonte=IMG_Load(Font_name(font_number));
 | 
			
		||||
  if (!Surface_fonte)
 | 
			
		||||
  font_surface=IMG_Load(Font_name(font_number));
 | 
			
		||||
  if (!font_surface)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG("Font loading failed",0);
 | 
			
		||||
    Verbose_message("Warning","Error loading font.\nThe file may be corrupt.");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  font=SFont_InitFont(Surface_fonte);
 | 
			
		||||
  // Font is 24bit: Perform a color reduction
 | 
			
		||||
  if (font_surface->format->BitsPerPixel>8)
 | 
			
		||||
  {
 | 
			
		||||
    SDL_Surface * reduced_surface;
 | 
			
		||||
    int x,y,color;
 | 
			
		||||
    SDL_Color rgb;
 | 
			
		||||
    
 | 
			
		||||
    reduced_surface=SDL_CreateRGBSurface(SDL_SWSURFACE, font_surface->w, font_surface->h, 8, 0, 0, 0, 0);
 | 
			
		||||
    if (!reduced_surface)
 | 
			
		||||
    {
 | 
			
		||||
      SDL_FreeSurface(font_surface);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    // Set the quick palette
 | 
			
		||||
    for (color=0;color<256;color++)
 | 
			
		||||
    {
 | 
			
		||||
      rgb.r=((color & 0xE0)>>5)<<5;
 | 
			
		||||
      rgb.g=((color & 0x1C)>>2)<<5;
 | 
			
		||||
      rgb.b=((color & 0x03)>>0)<<6;
 | 
			
		||||
      SDL_SetColors(reduced_surface, &rgb, color, 1);
 | 
			
		||||
    }
 | 
			
		||||
    // Perform reduction
 | 
			
		||||
    for (y=0; y<font_surface->h; y++)
 | 
			
		||||
      for (x=0; x<font_surface->w; x++)
 | 
			
		||||
      {
 | 
			
		||||
        SDL_GetRGB(Get_SDL_pixel_hicolor(font_surface, x, y), font_surface->format, &rgb.r, &rgb.g, &rgb.b);
 | 
			
		||||
        color=((rgb.r >> 5) << 5) |
 | 
			
		||||
                ((rgb.g >> 5) << 2) |
 | 
			
		||||
                ((rgb.b >> 6));
 | 
			
		||||
        Set_SDL_pixel_8(reduced_surface, x, y, color);
 | 
			
		||||
      }
 | 
			
		||||
    
 | 
			
		||||
    SDL_FreeSurface(font_surface);
 | 
			
		||||
    font_surface=reduced_surface;
 | 
			
		||||
  }
 | 
			
		||||
  font=SFont_InitFont(font_surface);
 | 
			
		||||
  if (!font)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG("Font init failed",1);
 | 
			
		||||
    SDL_FreeSurface(font_surface);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
@ -476,40 +575,36 @@ byte *Render_text_SFont(const char *str, int font_number, int *width, int *heigh
 | 
			
		||||
  *height=SFont_TextHeight(font);
 | 
			
		||||
  *width=SFont_TextWidth(font, str);
 | 
			
		||||
  // Allocation d'une surface SDL
 | 
			
		||||
  TexteColore=SDL_CreateRGBSurface(SDL_SWSURFACE, *width, *height, 24, 0, 0, 0, 0);
 | 
			
		||||
  text_surface=SDL_CreateRGBSurface(SDL_SWSURFACE, *width, *height, 8, 0, 0, 0, 0);
 | 
			
		||||
  // Copy palette
 | 
			
		||||
  SDL_SetPalette(text_surface, SDL_LOGPAL, font_surface->format->palette->colors, 0, 256);
 | 
			
		||||
  // Fill with backcolor
 | 
			
		||||
  rectangle.x=0;
 | 
			
		||||
  rectangle.y=0;
 | 
			
		||||
  rectangle.w=*width;
 | 
			
		||||
  rectangle.h=*height;
 | 
			
		||||
  SDL_FillRect(TexteColore, &rectangle, SDL_MapRGB(
 | 
			
		||||
    TexteColore->format, 
 | 
			
		||||
    Main_palette[Back_color].R, 
 | 
			
		||||
    Main_palette[Back_color].G, 
 | 
			
		||||
    Main_palette[Back_color].B
 | 
			
		||||
    ));
 | 
			
		||||
  SDL_FillRect(text_surface, &rectangle, Back_color);
 | 
			
		||||
  // Rendu du texte
 | 
			
		||||
  SFont_Write(TexteColore, font, 0, 0, str);
 | 
			
		||||
  if (!TexteColore)
 | 
			
		||||
  SFont_Write(text_surface, font, 0, 0, str);
 | 
			
		||||
  if (!text_surface)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG("Rendering failed",2);
 | 
			
		||||
    SFont_FreeFont(font);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  Texte8Bit=SDL_DisplayFormat(TexteColore);
 | 
			
		||||
  SDL_FreeSurface(TexteColore);
 | 
			
		||||
    
 | 
			
		||||
  new_brush=Surface_to_bytefield(Texte8Bit, NULL);
 | 
			
		||||
  new_brush=Surface_to_bytefield(text_surface, NULL);
 | 
			
		||||
  if (!new_brush)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG("Converting failed",3);
 | 
			
		||||
    SDL_FreeSurface(TexteColore);
 | 
			
		||||
    SDL_FreeSurface(Texte8Bit);
 | 
			
		||||
    SDL_FreeSurface(text_surface);
 | 
			
		||||
    SFont_FreeFont(font);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  SDL_FreeSurface(Texte8Bit);
 | 
			
		||||
 | 
			
		||||
  Get_SDL_Palette(font_surface->format->palette, palette);
 | 
			
		||||
 | 
			
		||||
  SDL_FreeSurface(text_surface);
 | 
			
		||||
  SFont_FreeFont(font);
 | 
			
		||||
 | 
			
		||||
  return new_brush;
 | 
			
		||||
@ -524,7 +619,7 @@ byte *Render_text_SFont(const char *str, int font_number, int *width, int *heigh
 | 
			
		||||
// Crée une brosse à partir des paramètres de texte demandés.
 | 
			
		||||
// Si cela réussit, la fonction place les dimensions dans width et height, 
 | 
			
		||||
// et retourne l'adresse du bloc d'octets.
 | 
			
		||||
byte *Render_text(const char *str, int font_number, TTFONLY int size, int TTFONLY antialias, TTFONLY int bold, TTFONLY int italic, int *width, int *height)
 | 
			
		||||
byte *Render_text(const char *str, int font_number, TTFONLY int size, int TTFONLY antialias, TTFONLY int bold, TTFONLY int italic, int *width, int *height, T_Palette palette)
 | 
			
		||||
{
 | 
			
		||||
  T_Font *font = font_list_start;
 | 
			
		||||
  int index=font_number;
 | 
			
		||||
@ -538,14 +633,14 @@ byte *Render_text(const char *str, int font_number, TTFONLY int size, int TTFONL
 | 
			
		||||
  if (font->Is_truetype)
 | 
			
		||||
  {
 | 
			
		||||
  #ifndef NOTTF 
 | 
			
		||||
    return Render_text_TTF(str, font_number, size, antialias, bold, italic, width, height);
 | 
			
		||||
    return Render_text_TTF(str, font_number, size, antialias, bold, italic, width, height, palette);
 | 
			
		||||
  #else
 | 
			
		||||
    return NULL;
 | 
			
		||||
  #endif
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    return Render_text_SFont(str, font_number, width, height);
 | 
			
		||||
    return Render_text_SFont(str, font_number, width, height, palette);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,15 +41,16 @@ void Add_font(const char *name);
 | 
			
		||||
/// @param italic      Boolean, true to use italic rendering in TrueType
 | 
			
		||||
/// @param width       Returns the width of the created brush, in pixels.
 | 
			
		||||
/// @param height      Returns the height of the created brush, in pixels.
 | 
			
		||||
/// @param palette     Returns the custom palette for the brush.
 | 
			
		||||
/// Returns true on success.
 | 
			
		||||
byte *Render_text(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height);
 | 
			
		||||
byte *Render_text(const char *str, int font_number, int size, int antialias, int bold, int italic, int *width, int *height, T_Palette palette);
 | 
			
		||||
 | 
			
		||||
/// Finds a label to display for a font declared with ::Add_font().
 | 
			
		||||
char * Font_label(int index);
 | 
			
		||||
/// Finds the filename of a font declared with ::Add_font().
 | 
			
		||||
char * Font_name(int index);
 | 
			
		||||
/// Returns true if the font of this number is TrueType, false if it's a SFont bitmap.
 | 
			
		||||
char * TrueType_font(int index);
 | 
			
		||||
int TrueType_font(int index);
 | 
			
		||||
///
 | 
			
		||||
/// Number of fonts declared with a series of ::Add_font(). This is public for
 | 
			
		||||
/// convenience, but functionaly it is read-only.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										114
									
								
								src/tiles.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/tiles.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,114 @@
 | 
			
		||||
/* vim:expandtab:ts=2 sw=2:
 | 
			
		||||
*/
 | 
			
		||||
/*  Grafx2 - The Ultimate 256-color bitmap paint program
 | 
			
		||||
 | 
			
		||||
    Copyright 2010 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 <http://www.gnu.org/licenses/>
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/// \file Handle tiles.
 | 
			
		||||
 | 
			
		||||
/// Build the tile-area from the current picture 
 | 
			
		||||
void build_tile_area()
 | 
			
		||||
{
 | 
			
		||||
	word tileAreaWidth = Main_image_width / Snap_width + 1;
 | 
			
		||||
	word tileAreaHeight = Main_image_height / Snap_height + 1;
 | 
			
		||||
 | 
			
		||||
	int* tileArea = malloc(tileAreaWidth*tileAreaHeight*sizeof(int));
 | 
			
		||||
 | 
			
		||||
	word tile_x, tile_y, pixel_x, pixel_y;
 | 
			
		||||
 | 
			
		||||
	// For each tile, we have to crawl up to the top of the picture and
 | 
			
		||||
	// find the first identical tile
 | 
			
		||||
	for (tile_y = 0; tile_y < tileAreaWidth; tile_y++)
 | 
			
		||||
		for(tile_x = 0; tile_x < tileAreaHeight; tile_x++)
 | 
			
		||||
		{
 | 
			
		||||
			// So, this is the "for each tile"
 | 
			
		||||
			word ctx, cty;
 | 
			
		||||
			// First we compare the tile with the others one in the same line at the left
 | 
			
		||||
			for(ctx = tile_x - 1; ctx >= 0; ctx--)
 | 
			
		||||
			if(compare_tiles(tile_x*Snap_width, tile_y*Snap_height, ctx*Snap_width, tile_y*Snap_height))
 | 
			
		||||
			{
 | 
			
		||||
				// We found a match !
 | 
			
		||||
				tileArea[tile_y*tileAreaWidth+tile_x] = tile_y*tileAreaWidth+ctx;
 | 
			
		||||
				goto found;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Then we look at all the lines above
 | 
			
		||||
			for(cty = tile_y - 1; cty >= 0; cty--)
 | 
			
		||||
			for(ctx = tileAreaWidth - 1; ctx >= 0; ctx--)
 | 
			
		||||
			if(compare_tiles(tile_x*Snap_width, tile_y*Snap_height, ctx*Snap_width, cty*Snap_height))
 | 
			
		||||
			{
 | 
			
		||||
				// We found a match !
 | 
			
		||||
				tileArea[tile_y*tileAreaWidth+tile_x] = cty*tileAreaWidth+ctx;
 | 
			
		||||
				goto found;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Then we look at all the lines below
 | 
			
		||||
			for(cty = tileAreaHeight - 1; cty >= tile_y; cty--)
 | 
			
		||||
			for(ctx = tileAreaWidth - 1; ctx >= 0; ctx--)
 | 
			
		||||
			if(compare_tiles(tile_x*Snap_width, tile_y*Snap_height, ctx*Snap_width, cty*Snap_height))
 | 
			
		||||
			{
 | 
			
		||||
				// We found a match !
 | 
			
		||||
				tileArea[tile_y*tileAreaWidth+tile_x] = cty*tileAreaWidth+ctx;
 | 
			
		||||
				goto found;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// Then we look at the tiles at the right of this one
 | 
			
		||||
			// (including the tile itself, so we are sure we match something this time)
 | 
			
		||||
			for(ctx = tileAreaHeight; ctx >= tile_x; ctx--)
 | 
			
		||||
			if(compare_tiles(tile_x*Snap_width, tile_y*Snap_height, ctx*Snap_width, tile_y*Snap_height))
 | 
			
		||||
			{
 | 
			
		||||
				// We found a match !
 | 
			
		||||
				tileArea[tile_y*tileAreaWidth+tile_x] = tile_y*tileAreaWidth+ctx;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
found:
 | 
			
		||||
		}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Compare tiles
 | 
			
		||||
// The parameters are in pixel-space.
 | 
			
		||||
void compare_tiles(word x1, word y1, word x2, word y2)
 | 
			
		||||
{
 | 
			
		||||
	word pixel_x, pixel_y;
 | 
			
		||||
	byte c1, c2;
 | 
			
		||||
 | 
			
		||||
	for (pixel_y = 0; pixel_y < Snap_width; pixel_y++)
 | 
			
		||||
	for (pixel_x = 0; pixel_x < Snap_height; pixel_x++)
 | 
			
		||||
	{
 | 
			
		||||
		c1 = Main_screen + (y1+pixel_y) * Main_image_width + (x1+pixel_x);
 | 
			
		||||
		c2 = Main_screen + (y2+pixel_y) * Main_image_width + (x2+pixel_x);
 | 
			
		||||
		if (c1 != c2) return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Copy a tile pixeldata to all the identical ones
 | 
			
		||||
// Call this after the end of an operation
 | 
			
		||||
void update_tile(word pixel_x, word pixel_y)
 | 
			
		||||
{
 | 
			
		||||
	int tileOffset = (pixel_y/Snap_height)*tileAreaHeight + pixel_x/Snap_width;
 | 
			
		||||
	int firstTileOffset = tileOffset + 1; // to make sure they are not equal
 | 
			
		||||
 | 
			
		||||
	while(firstTileOffset != tileOffset)
 | 
			
		||||
	{
 | 
			
		||||
		tileOffset = tileArea[tileOffset];
 | 
			
		||||
		
 | 
			
		||||
		//do the copy of a block starting at (pixel_x, pixel_y)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -273,7 +273,7 @@ void Button_Transform_menu(void)
 | 
			
		||||
          input_button[clicked_button-10]->Pos_Y+2,
 | 
			
		||||
          buffer,
 | 
			
		||||
          4,
 | 
			
		||||
          1))
 | 
			
		||||
          INPUT_TYPE_INTEGER))
 | 
			
		||||
        {
 | 
			
		||||
          // Accept entered value
 | 
			
		||||
          *(input_value[clicked_button-10])=atoi(buffer);
 | 
			
		||||
@ -369,8 +369,9 @@ void Button_Transform_menu(void)
 | 
			
		||||
    old_width=Main_image_width;
 | 
			
		||||
    old_height=Main_image_height;
 | 
			
		||||
    
 | 
			
		||||
    Upload_infos_page_main(Main_backups->Pages);
 | 
			
		||||
    // Allocate a new page
 | 
			
		||||
    if (Backup_with_new_dimensions(1,Main_backups->Pages->Nb_layers,new_width,new_height))
 | 
			
		||||
    if (Backup_with_new_dimensions(new_width,new_height))
 | 
			
		||||
    {
 | 
			
		||||
      // The new image is allocated, the new dimensions are already updated.
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										540
									
								
								src/windows.c
									
									
									
									
									
								
							
							
						
						
									
										540
									
								
								src/windows.c
									
									
									
									
									
								
							@ -36,8 +36,11 @@
 | 
			
		||||
#include "graph.h"
 | 
			
		||||
#include "input.h"
 | 
			
		||||
#include "misc.h"
 | 
			
		||||
#include "op_c.h"
 | 
			
		||||
#include "readline.h"
 | 
			
		||||
#include "sdlscreen.h"
 | 
			
		||||
#include "palette.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// Width of one layer button, in pixels before scaling
 | 
			
		||||
word Layer_button_width = 1;
 | 
			
		||||
@ -67,7 +70,7 @@ void Pixel_in_menu(word bar, word x, word y, byte color)
 | 
			
		||||
void Pixel_in_menu_and_skin(word bar, word x, word y, byte color)
 | 
			
		||||
{
 | 
			
		||||
  Pixel_in_menu(bar, x, y, color);
 | 
			
		||||
  Menu_bars[bar].Skin[y*Menu_bars[bar].Skin_width + x] = color;  
 | 
			
		||||
  Menu_bars[bar].Skin[2][y*Menu_bars[bar].Skin_width + x] = color;  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Affichage d'un pixel dans la fenêtre (la fenêtre doit être visible)
 | 
			
		||||
@ -454,7 +457,7 @@ void Draw_bar_remainder(word current_menu, word x_off)
 | 
			
		||||
 | 
			
		||||
  for (y_pos=0;y_pos<Menu_bars[current_menu].Height;y_pos++)
 | 
			
		||||
    for (x_pos=x_off;x_pos<Screen_width/Menu_factor_X;x_pos++)
 | 
			
		||||
      Pixel_in_menu(current_menu, x_pos, y_pos, Menu_bars[current_menu].Skin[y_pos * Menu_bars[current_menu].Skin_width + Menu_bars[current_menu].Skin_width - 2 + (x_pos&1)]);
 | 
			
		||||
      Pixel_in_menu(current_menu, x_pos, y_pos, Menu_bars[current_menu].Skin[0][y_pos * Menu_bars[current_menu].Skin_width + Menu_bars[current_menu].Skin_width - 2 + (x_pos&1)]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
@ -491,7 +494,7 @@ void Display_layerbar(void)
 | 
			
		||||
  x_off=Menu_bars[MENUBAR_LAYERS].Skin_width;
 | 
			
		||||
  for (current_button=0; current_button<button_number; current_button++)
 | 
			
		||||
  {
 | 
			
		||||
    word x_pos;
 | 
			
		||||
    word x_pos=0;
 | 
			
		||||
    word y_pos;
 | 
			
		||||
    word sprite_index;
 | 
			
		||||
    
 | 
			
		||||
@ -566,7 +569,7 @@ void Display_menu(void)
 | 
			
		||||
        // Skinned area
 | 
			
		||||
        for (y_pos=0;y_pos<Menu_bars[current_menu].Height;y_pos++)
 | 
			
		||||
          for (x_pos=0;x_pos<Menu_bars[current_menu].Skin_width;x_pos++)
 | 
			
		||||
            Pixel_in_menu(current_menu, x_pos, y_pos, Menu_bars[current_menu].Skin[y_pos * Menu_bars[current_menu].Skin_width + x_pos]);
 | 
			
		||||
            Pixel_in_menu(current_menu, x_pos, y_pos, Menu_bars[current_menu].Skin[2][y_pos * Menu_bars[current_menu].Skin_width + x_pos]);
 | 
			
		||||
 | 
			
		||||
        if (current_menu == MENUBAR_LAYERS)
 | 
			
		||||
        {
 | 
			
		||||
@ -706,6 +709,7 @@ void Print_coordinates(void)
 | 
			
		||||
  if (Menu_is_visible && !Cursor_in_menu)
 | 
			
		||||
  {
 | 
			
		||||
    if ( (Current_operation==OPERATION_COLORPICK)
 | 
			
		||||
      || (Current_operation==OPERATION_RMB_COLORPICK)
 | 
			
		||||
      || (Current_operation==OPERATION_REPLACE) )
 | 
			
		||||
    {
 | 
			
		||||
      if ( (Paintbrush_X>=0) && (Paintbrush_Y>=0)
 | 
			
		||||
@ -1073,7 +1077,7 @@ int Requester_window(char* message, int initial_value)
 | 
			
		||||
  {
 | 
			
		||||
    clicked_button = Window_clicked_button();
 | 
			
		||||
    if (clicked_button == 1)
 | 
			
		||||
      Readline(11, 39, str, 4, 1);
 | 
			
		||||
      Readline(11, 39, str, 4, INPUT_TYPE_INTEGER);
 | 
			
		||||
    if (Key == SDLK_ESCAPE) clicked_button = 2;
 | 
			
		||||
  }
 | 
			
		||||
  while (clicked_button <= 0);
 | 
			
		||||
@ -1179,90 +1183,34 @@ void Verbose_message(const char *caption, const char * message )
 | 
			
		||||
 | 
			
		||||
  // -- Redessiner le sprite d'un bouton dans le menu --
 | 
			
		||||
 | 
			
		||||
void Display_sprite_in_menu(int btn_number,int sprite_number)
 | 
			
		||||
void Display_sprite_in_menu(int btn_number,char sprite_number)
 | 
			
		||||
{
 | 
			
		||||
  word x_pos;
 | 
			
		||||
  word y_pos;
 | 
			
		||||
  word menu_x_pos;
 | 
			
		||||
  word menu_y_pos;
 | 
			
		||||
  byte color;
 | 
			
		||||
  Buttons_Pool[btn_number].Icon=sprite_number;
 | 
			
		||||
 | 
			
		||||
  menu_y_pos=Buttons_Pool[btn_number].Y_offset;
 | 
			
		||||
  menu_x_pos=Buttons_Pool[btn_number].X_offset;
 | 
			
		||||
  if (Buttons_Pool[btn_number].Shape != BUTTON_SHAPE_TRIANGLE_BOTTOM_RIGHT)
 | 
			
		||||
  {
 | 
			
		||||
    menu_y_pos+=1;
 | 
			
		||||
    menu_x_pos+=1;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  for (y_pos=0;y_pos<MENU_SPRITE_HEIGHT;y_pos++)
 | 
			
		||||
    for (x_pos=0;x_pos<MENU_SPRITE_WIDTH;x_pos++)
 | 
			
		||||
    {
 | 
			
		||||
      color=Gfx->Menu_sprite[sprite_number][y_pos][x_pos];
 | 
			
		||||
      Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos+x_pos, menu_y_pos+y_pos, color);
 | 
			
		||||
    }
 | 
			
		||||
if (Menu_is_visible && Menu_bars[MENUBAR_TOOLS].Visible)
 | 
			
		||||
  Update_rect(Menu_factor_X*(Buttons_Pool[btn_number].X_offset+1),
 | 
			
		||||
    (Buttons_Pool[btn_number].Y_offset+1+Menu_bars[MENUBAR_TOOLS].Top)*Menu_factor_Y+Menu_Y,
 | 
			
		||||
    MENU_SPRITE_WIDTH*Menu_factor_X,MENU_SPRITE_HEIGHT*Menu_factor_Y);
 | 
			
		||||
  if (Buttons_Pool[btn_number].Shape == BUTTON_SHAPE_TRIANGLE_TOP_LEFT)
 | 
			
		||||
    Buttons_Pool[btn_number+1].Icon=sprite_number;
 | 
			
		||||
 | 
			
		||||
  else if (Buttons_Pool[btn_number].Shape == BUTTON_SHAPE_TRIANGLE_BOTTOM_RIGHT)
 | 
			
		||||
    Buttons_Pool[btn_number-1].Icon=sprite_number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  // -- Redessiner la forme du pinceau dans le menu --
 | 
			
		||||
 | 
			
		||||
void Display_paintbrush_in_menu(void)
 | 
			
		||||
{
 | 
			
		||||
  short x_pos,y_pos;
 | 
			
		||||
  short start_x;
 | 
			
		||||
  short menu_x_pos,menu_y_pos;
 | 
			
		||||
  short menu_start_x;
 | 
			
		||||
  byte color;
 | 
			
		||||
    
 | 
			
		||||
  switch (Paintbrush_shape)
 | 
			
		||||
  switch(Paintbrush_shape)
 | 
			
		||||
  {
 | 
			
		||||
    case PAINTBRUSH_SHAPE_COLOR_BRUSH    : // Brush en couleur
 | 
			
		||||
    case PAINTBRUSH_SHAPE_MONO_BRUSH : // Brush monochrome
 | 
			
		||||
      for (menu_y_pos=2,y_pos=0;y_pos<MENU_SPRITE_HEIGHT;menu_y_pos++,y_pos++)
 | 
			
		||||
        for (menu_x_pos=1,x_pos=0;x_pos<MENU_SPRITE_WIDTH;menu_x_pos++,x_pos++)
 | 
			
		||||
        {
 | 
			
		||||
          color=Gfx->Menu_sprite[4][y_pos][x_pos];
 | 
			
		||||
          Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos, menu_y_pos, color);
 | 
			
		||||
        }
 | 
			
		||||
    case PAINTBRUSH_SHAPE_COLOR_BRUSH:
 | 
			
		||||
      Display_sprite_in_menu(BUTTON_PAINTBRUSHES, MENU_SPRITE_COLOR_BRUSH);
 | 
			
		||||
      break;
 | 
			
		||||
    case PAINTBRUSH_SHAPE_MONO_BRUSH:
 | 
			
		||||
      Display_sprite_in_menu(BUTTON_PAINTBRUSHES, MENU_SPRITE_MONO_BRUSH);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      Display_sprite_in_menu(BUTTON_PAINTBRUSHES, -1);
 | 
			
		||||
      break;
 | 
			
		||||
    default : // Pinceau
 | 
			
		||||
      // On efface le pinceau précédent
 | 
			
		||||
      for (menu_y_pos=2,y_pos=0;y_pos<MENU_SPRITE_HEIGHT;menu_y_pos++,y_pos++)
 | 
			
		||||
        for (menu_x_pos=1,x_pos=0;x_pos<MENU_SPRITE_WIDTH;menu_x_pos++,x_pos++)
 | 
			
		||||
        {
 | 
			
		||||
          Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos, menu_y_pos, MC_Light);
 | 
			
		||||
        }
 | 
			
		||||
      // On affiche le nouveau
 | 
			
		||||
      menu_start_x=8-Paintbrush_offset_X;
 | 
			
		||||
      if (menu_start_x<1)
 | 
			
		||||
      {
 | 
			
		||||
        start_x=Paintbrush_offset_X-7;
 | 
			
		||||
        menu_start_x=1;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
        start_x=0;
 | 
			
		||||
 | 
			
		||||
      menu_y_pos=9-Paintbrush_offset_Y;
 | 
			
		||||
      if (menu_y_pos<2)
 | 
			
		||||
      {
 | 
			
		||||
        y_pos=Paintbrush_offset_Y-7;
 | 
			
		||||
        menu_y_pos=2;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
        y_pos=0;
 | 
			
		||||
 | 
			
		||||
      for (;((y_pos<Paintbrush_height) && (menu_y_pos<16));menu_y_pos++,y_pos++)
 | 
			
		||||
        for (menu_x_pos=menu_start_x,x_pos=start_x;((x_pos<Paintbrush_width) && (menu_x_pos<15));menu_x_pos++,x_pos++)
 | 
			
		||||
        {
 | 
			
		||||
          color=(Paintbrush_sprite[(y_pos*MAX_PAINTBRUSH_SIZE)+x_pos])?MC_Black:MC_Light;
 | 
			
		||||
          Pixel_in_menu_and_skin(MENUBAR_TOOLS, menu_x_pos, menu_y_pos, color);
 | 
			
		||||
        }
 | 
			
		||||
  }
 | 
			
		||||
  if (Menu_is_visible && Menu_bars[MENUBAR_TOOLS].Visible)
 | 
			
		||||
    Update_rect(0,Menu_Y + Menu_bars[MENUBAR_TOOLS].Top*Menu_factor_Y,MENU_SPRITE_WIDTH*Menu_factor_X+3,MENU_SPRITE_HEIGHT*Menu_factor_Y+3);
 | 
			
		||||
  Draw_menu_button(BUTTON_PAINTBRUSHES,BUTTON_RELEASED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  // -- Dessiner un pinceau prédéfini dans la fenêtre --
 | 
			
		||||
@ -1278,6 +1226,8 @@ void Display_paintbrush_in_window(word x,word y,int number)
 | 
			
		||||
  int y_size;
 | 
			
		||||
  word origin_x;
 | 
			
		||||
  word origin_y;
 | 
			
		||||
  word width;
 | 
			
		||||
  word height;
 | 
			
		||||
 | 
			
		||||
  x_size=Menu_factor_X/Pixel_height;
 | 
			
		||||
  if (x_size<1)
 | 
			
		||||
@ -1286,18 +1236,22 @@ void Display_paintbrush_in_window(word x,word y,int number)
 | 
			
		||||
  if (y_size<1)
 | 
			
		||||
    y_size=1;
 | 
			
		||||
 | 
			
		||||
  origin_x = (x + 8)*Menu_factor_X - (Gfx->Preset_paintbrush_offset_X[number])*x_size+Window_pos_X;
 | 
			
		||||
  origin_y = (y + 8)*Menu_factor_Y - (Gfx->Preset_paintbrush_offset_Y[number])*y_size+Window_pos_Y;
 | 
			
		||||
  width=Min(Paintbrush[number].Width,PAINTBRUSH_WIDTH);
 | 
			
		||||
  height=Min(Paintbrush[number].Height,PAINTBRUSH_WIDTH);
 | 
			
		||||
  
 | 
			
		||||
  origin_x = (x + 8)*Menu_factor_X - (width/2)*x_size+Window_pos_X;
 | 
			
		||||
  origin_y = (y + 8)*Menu_factor_Y - (height/2)*y_size+Window_pos_Y;
 | 
			
		||||
 | 
			
		||||
  for (window_y_pos=0,y_pos=0; y_pos<Gfx->Preset_paintbrush_height[number]; window_y_pos++,y_pos++)
 | 
			
		||||
    for (window_x_pos=0,x_pos=0; x_pos<Gfx->Preset_paintbrush_width[number]; window_x_pos++,x_pos++)
 | 
			
		||||
      Block(origin_x+window_x_pos*x_size,origin_y+window_y_pos*y_size,x_size,y_size,(Gfx->Paintbrush_sprite[number][y_pos][x_pos])?MC_Black:MC_Light);
 | 
			
		||||
  for (window_y_pos=0,y_pos=0; y_pos<height; window_y_pos++,y_pos++)
 | 
			
		||||
    for (window_x_pos=0,x_pos=0; x_pos<width; window_x_pos++,x_pos++)
 | 
			
		||||
      if (Paintbrush[number].Sprite[y_pos][x_pos])
 | 
			
		||||
        Block(origin_x+window_x_pos*x_size,origin_y+window_y_pos*y_size,x_size,y_size,MC_Black);
 | 
			
		||||
  // On n'utilise pas Pixel_in_window() car on ne dessine pas
 | 
			
		||||
  // forcément avec la même taille de pixel.
 | 
			
		||||
 | 
			
		||||
  Update_rect( ToWinX(origin_x), ToWinY(origin_y),
 | 
			
		||||
        ToWinL(Gfx->Preset_paintbrush_width[number]),
 | 
			
		||||
        ToWinH(Gfx->Preset_paintbrush_height[number])
 | 
			
		||||
        ToWinL(Paintbrush[number].Width),
 | 
			
		||||
        ToWinH(Paintbrush[number].Height)
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1553,6 +1507,7 @@ void Compute_paintbrush_coordinates(void)
 | 
			
		||||
  {
 | 
			
		||||
    // Operations that don't implement it
 | 
			
		||||
    case OPERATION_LINE:
 | 
			
		||||
	case OPERATION_ROTATE_BRUSH:
 | 
			
		||||
      Snap_axis=0;
 | 
			
		||||
      break;
 | 
			
		||||
    // Operations that implement it
 | 
			
		||||
@ -1857,7 +1812,36 @@ void Change_magnifier_factor(byte factor_index, byte point_at_mouse)
 | 
			
		||||
  Compute_paintbrush_coordinates();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Copy_view_to_spare(void)
 | 
			
		||||
{
 | 
			
		||||
  
 | 
			
		||||
  // Don't do anything if the pictures have different dimensions
 | 
			
		||||
  if (Main_image_width!=Spare_image_width || Main_image_height!=Spare_image_height)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  // Copie des décalages de la fenêtre principale (non zoomée) de l'image
 | 
			
		||||
  Spare_offset_X=Main_offset_X;
 | 
			
		||||
  Spare_offset_Y=Main_offset_Y;
 | 
			
		||||
 | 
			
		||||
  // Copie du booléen "Mode loupe" de l'image
 | 
			
		||||
  Spare_magnifier_mode=Main_magnifier_mode;
 | 
			
		||||
 | 
			
		||||
  // Copie du facteur de zoom du brouillon
 | 
			
		||||
  Spare_magnifier_factor=Main_magnifier_factor;
 | 
			
		||||
 | 
			
		||||
  // Copie des dimensions de la fenêtre de zoom
 | 
			
		||||
  Spare_magnifier_width=Main_magnifier_width;
 | 
			
		||||
  Spare_magnifier_height=Main_magnifier_height;
 | 
			
		||||
 | 
			
		||||
  // Copie des décalages de la fenêtre de zoom
 | 
			
		||||
  Spare_magnifier_offset_X=Main_magnifier_offset_X;
 | 
			
		||||
  Spare_magnifier_offset_Y=Main_magnifier_offset_Y;
 | 
			
		||||
 | 
			
		||||
  // Copie des données du split du zoom
 | 
			
		||||
  Spare_separator_position=Main_separator_position;
 | 
			
		||||
  Spare_X_zoom=Main_X_zoom;
 | 
			
		||||
  Spare_separator_proportion=Main_separator_proportion;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  // -- Afficher la barre de séparation entre les parties zoomées ou non en
 | 
			
		||||
  //    mode Loupe --
 | 
			
		||||
@ -2629,7 +2613,7 @@ void Display_all_screen(void)
 | 
			
		||||
 | 
			
		||||
byte Best_color(byte r,byte g,byte b)
 | 
			
		||||
{
 | 
			
		||||
  short col;
 | 
			
		||||
  int col;
 | 
			
		||||
  int   delta_r,delta_g,delta_b;
 | 
			
		||||
  int   dist;
 | 
			
		||||
  int   best_dist=0x7FFFFFFF;
 | 
			
		||||
@ -2663,7 +2647,7 @@ byte Best_color(byte r,byte g,byte b)
 | 
			
		||||
 | 
			
		||||
byte Best_color_nonexcluded(byte red,byte green,byte blue)
 | 
			
		||||
{
 | 
			
		||||
  short col;
 | 
			
		||||
  int   col;  
 | 
			
		||||
  int   delta_r,delta_g,delta_b;
 | 
			
		||||
  int   dist;
 | 
			
		||||
  int   best_dist=0x7FFFFFFF;
 | 
			
		||||
@ -2692,65 +2676,50 @@ byte Best_color_nonexcluded(byte red,byte green,byte blue)
 | 
			
		||||
  return best_color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Compute_4_best_colors_for_1_menu_color
 | 
			
		||||
     (byte red, byte green, byte blue, T_Components * palette, byte * table)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte Best_color_perceptual(byte r,byte g,byte b)
 | 
			
		||||
{
 | 
			
		||||
  short col;
 | 
			
		||||
  int   delta_r,delta_g,delta_b;
 | 
			
		||||
  int   dist;
 | 
			
		||||
  int   best_dist[4]={0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF};
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  int col;  
 | 
			
		||||
  float best_diff=255.0*1.56905;
 | 
			
		||||
  byte  best_color=0;
 | 
			
		||||
  float target_bri;
 | 
			
		||||
  float bri;
 | 
			
		||||
  float diff_b, diff_c, diff;
 | 
			
		||||
 | 
			
		||||
  // Similar to Perceptual_lightness();
 | 
			
		||||
  target_bri = sqrt(0.26*r*0.26*r + 0.55*g*0.55*g + 0.19*b*0.19*b);
 | 
			
		||||
  
 | 
			
		||||
  for (col=0; col<256; col++)
 | 
			
		||||
  {
 | 
			
		||||
    delta_r=(int)palette[col].R-red;
 | 
			
		||||
    delta_g=(int)palette[col].G-green;
 | 
			
		||||
    delta_b=(int)palette[col].B-blue;
 | 
			
		||||
    if (Exclude_color[col])
 | 
			
		||||
      continue;
 | 
			
		||||
 | 
			
		||||
    dist=(delta_r*delta_r*30)+(delta_g*delta_g*59)+(delta_b*delta_b*11);
 | 
			
		||||
    diff_c = sqrt(
 | 
			
		||||
      (0.26*(Main_palette[col].R-r))*
 | 
			
		||||
      (0.26*(Main_palette[col].R-r))+
 | 
			
		||||
      (0.55*(Main_palette[col].G-g))*
 | 
			
		||||
      (0.55*(Main_palette[col].G-g))+
 | 
			
		||||
      (0.19*(Main_palette[col].B-b))*
 | 
			
		||||
      (0.19*(Main_palette[col].B-b)));
 | 
			
		||||
    // Exact match
 | 
			
		||||
    if (diff_c==0)
 | 
			
		||||
      return col;
 | 
			
		||||
 | 
			
		||||
    if (dist<best_dist[0])
 | 
			
		||||
    bri = sqrt(0.26*Main_palette[col].R*0.26*Main_palette[col].R + 0.55*Main_palette[col].G*0.55*Main_palette[col].G + 0.19*Main_palette[col].B*0.19*Main_palette[col].B);
 | 
			
		||||
    diff_b = abs(target_bri-bri);
 | 
			
		||||
 | 
			
		||||
    diff=0.25*(diff_b-diff_c)+diff_c;
 | 
			
		||||
    if (diff<best_diff)
 | 
			
		||||
    {
 | 
			
		||||
      best_dist[3]=best_dist[2];
 | 
			
		||||
      best_dist[2]=best_dist[1];
 | 
			
		||||
      best_dist[1]=best_dist[0];
 | 
			
		||||
      best_dist[0]=dist;
 | 
			
		||||
      table[3]=table[2];
 | 
			
		||||
      table[2]=table[1];
 | 
			
		||||
      table[1]=table[0];
 | 
			
		||||
      table[0]=col;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      if (dist<best_dist[1])
 | 
			
		||||
      {
 | 
			
		||||
        best_dist[3]=best_dist[2];
 | 
			
		||||
        best_dist[2]=best_dist[1];
 | 
			
		||||
        best_dist[1]=dist;
 | 
			
		||||
        table[3]=table[2];
 | 
			
		||||
        table[2]=table[1];
 | 
			
		||||
        table[1]=col;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
        if (dist<best_dist[2])
 | 
			
		||||
        {
 | 
			
		||||
          best_dist[3]=best_dist[2];
 | 
			
		||||
          best_dist[2]=dist;
 | 
			
		||||
          table[3]=table[2];
 | 
			
		||||
          table[2]=col;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        if (dist<best_dist[3])
 | 
			
		||||
        {
 | 
			
		||||
          best_dist[3]=dist;
 | 
			
		||||
          table[3]=col;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
      best_diff=diff;
 | 
			
		||||
      best_color=col;
 | 
			
		||||
    } 
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  return best_color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
byte Old_black;
 | 
			
		||||
@ -2835,11 +2804,32 @@ void Remap_screen_after_menu_colors_change(void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int Same_color(T_Components * palette, byte c1, byte c2)
 | 
			
		||||
{
 | 
			
		||||
  if (palette[c1].R==palette[c2].R &&
 | 
			
		||||
    palette[c1].G==palette[c2].G &&
 | 
			
		||||
    palette[c1].B==palette[c2].B)
 | 
			
		||||
    return 1;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Compute_optimal_menu_colors(T_Components * palette)
 | 
			
		||||
{
 | 
			
		||||
  byte table[4];
 | 
			
		||||
  int i;
 | 
			
		||||
  byte l[256];
 | 
			
		||||
  byte s[256];
 | 
			
		||||
  byte h;
 | 
			
		||||
  int max_l = -1, min_l = 256;
 | 
			
		||||
  int low_l, hi_l;
 | 
			
		||||
  int delta_low = 999999;
 | 
			
		||||
  int delta_high = 999999;
 | 
			
		||||
  const int tolerence=16;
 | 
			
		||||
  const T_Components cpc_colors[4] = {
 | 
			
		||||
    {  0,  0,  0},
 | 
			
		||||
    {  0,  0,128}, // Dark blue
 | 
			
		||||
    {128,128,128}, // Grey
 | 
			
		||||
    {255,255,255}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Old_black =MC_Black;
 | 
			
		||||
  Old_dark = MC_Dark;
 | 
			
		||||
@ -2847,62 +2837,208 @@ void Compute_optimal_menu_colors(T_Components * palette)
 | 
			
		||||
  Old_white = MC_White;
 | 
			
		||||
  Old_trans = MC_Trans;
 | 
			
		||||
 | 
			
		||||
  // Recherche du noir
 | 
			
		||||
  Compute_4_best_colors_for_1_menu_color
 | 
			
		||||
    (Gfx->Default_palette[Gfx->Color[0]].R, Gfx->Default_palette[Gfx->Color[0]].G, Gfx->Default_palette[Gfx->Color[0]].B,palette,table);
 | 
			
		||||
  MC_Black=table[0];
 | 
			
		||||
 | 
			
		||||
  // Recherche du blanc
 | 
			
		||||
  Compute_4_best_colors_for_1_menu_color
 | 
			
		||||
    (Gfx->Default_palette[Gfx->Color[3]].R, Gfx->Default_palette[Gfx->Color[3]].G, Gfx->Default_palette[Gfx->Color[3]].B,palette,table);
 | 
			
		||||
  if (MC_Black!=table[0])
 | 
			
		||||
    MC_White=table[0];
 | 
			
		||||
  else
 | 
			
		||||
    MC_White=table[1];
 | 
			
		||||
 | 
			
		||||
  // Recherche du gris clair
 | 
			
		||||
  Compute_4_best_colors_for_1_menu_color
 | 
			
		||||
    (Gfx->Default_palette[Gfx->Color[2]].R, Gfx->Default_palette[Gfx->Color[2]].G, Gfx->Default_palette[Gfx->Color[2]].B,palette,table);
 | 
			
		||||
  if ( (MC_Black!=table[0]) && (MC_White!=table[0]) )
 | 
			
		||||
    MC_Light=table[0];
 | 
			
		||||
  else
 | 
			
		||||
  // First method:
 | 
			
		||||
  // If all close matches for the ideal colors exist, pick them.
 | 
			
		||||
  for (i=255; i>=0; i--)
 | 
			
		||||
  {
 | 
			
		||||
    if ( (MC_Black!=table[1]) && (MC_White!=table[1]) )
 | 
			
		||||
      MC_Light=table[1];
 | 
			
		||||
    else
 | 
			
		||||
      MC_Light=table[2];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Recherche du gris foncé
 | 
			
		||||
  Compute_4_best_colors_for_1_menu_color
 | 
			
		||||
    (Gfx->Default_palette[Gfx->Color[1]].R, Gfx->Default_palette[Gfx->Color[1]].G, Gfx->Default_palette[Gfx->Color[1]].B,palette,table);
 | 
			
		||||
  if ( (MC_Black!=table[0]) && (MC_White!=table[0]) && (MC_Light!=table[0]) )
 | 
			
		||||
    MC_Dark=table[0];
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    if ( (MC_Black!=table[1]) && (MC_White!=table[1]) && (MC_Light!=table[1]) )
 | 
			
		||||
      MC_Dark=table[1];
 | 
			
		||||
    else
 | 
			
		||||
    
 | 
			
		||||
    if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[3]].R/tolerence
 | 
			
		||||
     && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[3]].G/tolerence
 | 
			
		||||
     && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[3]].B/tolerence)
 | 
			
		||||
    {
 | 
			
		||||
      if ( (MC_Black!=table[2]) && (MC_White!=table[2]) && (MC_Light!=table[2]) )
 | 
			
		||||
        MC_Dark=table[2];
 | 
			
		||||
      else
 | 
			
		||||
        MC_Dark=table[3];
 | 
			
		||||
      MC_White=i;
 | 
			
		||||
      for (i=255; i>=0; i--)
 | 
			
		||||
      {
 | 
			
		||||
        if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[2]].R/tolerence
 | 
			
		||||
         && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[2]].G/tolerence
 | 
			
		||||
         && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[2]].B/tolerence)
 | 
			
		||||
        {
 | 
			
		||||
          MC_Light=i;
 | 
			
		||||
          for (i=255; i>=0; i--)
 | 
			
		||||
          {
 | 
			
		||||
            if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[1]].R/tolerence
 | 
			
		||||
             && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[1]].G/tolerence
 | 
			
		||||
             && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[1]].B/tolerence)
 | 
			
		||||
            {
 | 
			
		||||
              MC_Dark=i;
 | 
			
		||||
              for (i=255; i>=0; i--)
 | 
			
		||||
              {
 | 
			
		||||
                if (Round_palette_component(palette[i].R)/tolerence==Gfx->Default_palette[Gfx->Color[0]].R/tolerence
 | 
			
		||||
                 && Round_palette_component(palette[i].G)/tolerence==Gfx->Default_palette[Gfx->Color[0]].G/tolerence
 | 
			
		||||
                 && Round_palette_component(palette[i].B)/tolerence==Gfx->Default_palette[Gfx->Color[0]].B/tolerence)
 | 
			
		||||
                {
 | 
			
		||||
                  MC_Black=i;
 | 
			
		||||
                  // On cherche une couleur de transparence différente des 4 autres.
 | 
			
		||||
                  for (MC_Trans=0; ((MC_Trans==MC_Black) || (MC_Trans==MC_Dark) ||
 | 
			
		||||
                                   (MC_Trans==MC_Light) || (MC_Trans==MC_White)); MC_Trans++);
 | 
			
		||||
                  // Easy case
 | 
			
		||||
                  MC_OnBlack=MC_Dark;
 | 
			
		||||
                  MC_Window=MC_Light;
 | 
			
		||||
                  MC_Lighter=MC_White;
 | 
			
		||||
                  MC_Darker=MC_Dark;
 | 
			
		||||
                  Remap_menu_sprites();
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // C'est peu probable mais il est possible que MC_Light soit plus foncée que
 | 
			
		||||
  // MC_Dark. Dans ce cas, on les inverse.
 | 
			
		||||
  if ( ((palette[MC_Light].R*30)+(palette[MC_Light].G*59)+(palette[MC_Light].B*11)) <
 | 
			
		||||
       ((palette[MC_Dark].R*30)+(palette[MC_Dark].G*59)+(palette[MC_Dark].B*11)) )
 | 
			
		||||
  // Second method: For CPC 27-color modes only
 | 
			
		||||
  // Try to find colors that just work
 | 
			
		||||
  if (Get_palette_RGB_scale()==3)
 | 
			
		||||
  for (i=255; i>=0; i--)
 | 
			
		||||
  {
 | 
			
		||||
    SWAP_BYTES(MC_Light, MC_Dark);
 | 
			
		||||
    
 | 
			
		||||
    if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[3].R/tolerence
 | 
			
		||||
     && Round_palette_component(palette[i].G)/tolerence==cpc_colors[3].G/tolerence
 | 
			
		||||
     && Round_palette_component(palette[i].B)/tolerence==cpc_colors[3].B/tolerence)
 | 
			
		||||
    {
 | 
			
		||||
      MC_White=i;
 | 
			
		||||
      for (i=255; i>=0; i--)
 | 
			
		||||
      {
 | 
			
		||||
        if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[2].R/tolerence
 | 
			
		||||
         && Round_palette_component(palette[i].G)/tolerence==cpc_colors[2].G/tolerence
 | 
			
		||||
         && Round_palette_component(palette[i].B)/tolerence==cpc_colors[2].B/tolerence)
 | 
			
		||||
        {
 | 
			
		||||
          MC_Light=i;
 | 
			
		||||
          for (i=255; i>=0; i--)
 | 
			
		||||
          {
 | 
			
		||||
            if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[1].R/tolerence
 | 
			
		||||
             && Round_palette_component(palette[i].G)/tolerence==cpc_colors[1].G/tolerence
 | 
			
		||||
             && Round_palette_component(palette[i].B)/tolerence==cpc_colors[1].B/tolerence)
 | 
			
		||||
            {
 | 
			
		||||
              MC_Dark=i;
 | 
			
		||||
              for (i=255; i>=0; i--)
 | 
			
		||||
              {
 | 
			
		||||
                if (Round_palette_component(palette[i].R)/tolerence==cpc_colors[0].R/tolerence
 | 
			
		||||
                 && Round_palette_component(palette[i].G)/tolerence==cpc_colors[0].G/tolerence
 | 
			
		||||
                 && Round_palette_component(palette[i].B)/tolerence==cpc_colors[0].B/tolerence)
 | 
			
		||||
                {
 | 
			
		||||
                  MC_Black=i;
 | 
			
		||||
                  // On cherche une couleur de transparence différente des 4 autres.
 | 
			
		||||
                  for (MC_Trans=0; ((MC_Trans==MC_Black) || (MC_Trans==MC_Dark) ||
 | 
			
		||||
                                   (MC_Trans==MC_Light) || (MC_Trans==MC_White)); MC_Trans++);
 | 
			
		||||
                  // Easy case
 | 
			
		||||
                  MC_OnBlack=MC_Dark;
 | 
			
		||||
                  MC_Window=MC_Light;
 | 
			
		||||
                  MC_Lighter=MC_White;
 | 
			
		||||
                  MC_Darker=MC_Dark;
 | 
			
		||||
                  Remap_menu_sprites();
 | 
			
		||||
                  return;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Third method:
 | 
			
		||||
 | 
			
		||||
  // Compute luminance for whole palette
 | 
			
		||||
  // Take the darkest as black, the brightest white
 | 
			
		||||
  for(i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    RGB_to_HSL(palette[i].R, palette[i].G, palette[i].B, &h, &s[i], &l[i]);
 | 
			
		||||
    // Another formula for lightness, in 0-255 range
 | 
			
		||||
    //l[i]=Perceptual_lightness(&palette[i])/4062/255;
 | 
			
		||||
    if (l[i] > max_l)
 | 
			
		||||
    {
 | 
			
		||||
      max_l = l[i];
 | 
			
		||||
      MC_White = i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  for(i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (l[i] < min_l && i!=MC_White)
 | 
			
		||||
    {
 | 
			
		||||
      min_l = l[i];
 | 
			
		||||
      MC_Black = i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Alter the S values according to the L range - this is for the future
 | 
			
		||||
  // comparisons, so that highly variable saturation doesn't weigh
 | 
			
		||||
  // too heavily when the the lightness is in a narrow range.
 | 
			
		||||
  for(i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    s[i]=s[i]*(max_l-min_l)/255;
 | 
			
		||||
  }
 | 
			
		||||
  for(i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    // Adjust (reduce) perceived saturation at both ends of L spectrum
 | 
			
		||||
    if (l[i]>192)
 | 
			
		||||
      s[i]=s[i]*(255-l[i])/64;
 | 
			
		||||
    else if (l[i]<64)
 | 
			
		||||
      s[i]=s[i]*l[i]/64;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Find color nearest to min+2(max-min)/3
 | 
			
		||||
  // but at the same time we try to minimize the saturation so that the menu
 | 
			
		||||
  // still looks grey
 | 
			
		||||
  hi_l = min_l + 2*(max_l - min_l)/3;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if ( abs(l[i] - hi_l) + s[i]/2 < delta_high && i!=MC_White && i!=MC_Black)
 | 
			
		||||
    {
 | 
			
		||||
      delta_high = abs(l[i] - hi_l) + s[i]/2;
 | 
			
		||||
      MC_Light = i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Target "Dark color" is 2/3 between Light and Black
 | 
			
		||||
  low_l = ((int)l[MC_Light]*2+l[MC_Black])/3;
 | 
			
		||||
  for (i = 0; i < 256; i++)
 | 
			
		||||
  {
 | 
			
		||||
    if ( abs((int)l[i] - low_l) + s[i]/6 < delta_low && i!=MC_White && i!=MC_Black && i!=MC_Light)
 | 
			
		||||
    {
 | 
			
		||||
      delta_low = abs((int)l[i] - low_l)+ s[i]/6;
 | 
			
		||||
      MC_Dark = i;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  //if (l[MC_Light]<l[MC_Dark])
 | 
			
		||||
  //{
 | 
			
		||||
  //  // Not sure if that can happen, but just in case:
 | 
			
		||||
  //  SWAP_BYTES(MC_Light, MC_Dark)
 | 
			
		||||
  //}
 | 
			
		||||
 | 
			
		||||
  // Si deux des couleurs choisies ont le même index, c'est destructif car 
 | 
			
		||||
  // on fait ensuite un remap de l'image. Donc on évite ce problème (un
 | 
			
		||||
  // peu brutalement)
 | 
			
		||||
  // On commence par déplacer les gris, comme ça on a plus de chances de garder au moins
 | 
			
		||||
  // le blanc et le noir
 | 
			
		||||
  //while (MC_Dark == MC_Light || MC_Dark == MC_White || MC_Black == MC_Dark || Same_color(palette, MC_Dark, MC_White)) MC_Dark--;
 | 
			
		||||
  //while (MC_White == MC_Light || MC_Dark == MC_Light || MC_Black == MC_Light || Same_color(palette, MC_Light, MC_Black)) MC_Light--;
 | 
			
		||||
  //while (MC_White == MC_Light || MC_Dark == MC_White || MC_Black == MC_White) MC_White--;
 | 
			
		||||
 | 
			
		||||
  // On cherche une couleur de transparence différente des 4 autres.
 | 
			
		||||
  for (MC_Trans=0; ((MC_Trans==MC_Black) || (MC_Trans==MC_Dark) ||
 | 
			
		||||
                   (MC_Trans==MC_Light) || (MC_Trans==MC_White)); MC_Trans++);
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  if (Same_color(palette, MC_Black, MC_Dark))
 | 
			
		||||
    MC_OnBlack=MC_Light;
 | 
			
		||||
  else
 | 
			
		||||
    MC_OnBlack=MC_Dark;
 | 
			
		||||
  
 | 
			
		||||
  if (Same_color(palette, MC_White, MC_Light))
 | 
			
		||||
  {
 | 
			
		||||
    MC_Window=MC_Dark;
 | 
			
		||||
    MC_Darker=MC_Black;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    MC_Window=MC_Light;
 | 
			
		||||
    MC_Darker=MC_Dark;
 | 
			
		||||
  }
 | 
			
		||||
  MC_Lighter=MC_White;
 | 
			
		||||
  
 | 
			
		||||
  Remap_menu_sprites();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2923,18 +3059,20 @@ void Remap_menu_sprites()
 | 
			
		||||
        for (i=0; i<CURSOR_SPRITE_WIDTH; i++)
 | 
			
		||||
          Remap_pixel(&Gfx->Cursor_sprite[k][j][i]);
 | 
			
		||||
    // Main menu bar
 | 
			
		||||
    for (j=0; j<Menu_bars[MENUBAR_TOOLS].Height; j++)
 | 
			
		||||
      for (i=0; i<Menu_bars[MENUBAR_TOOLS].Skin_width; i++)
 | 
			
		||||
        Remap_pixel(&Gfx->Menu_block[j][i]);
 | 
			
		||||
    for (k=0; k<3; k++)
 | 
			
		||||
      for (j=0; j<Menu_bars[MENUBAR_TOOLS].Height; j++)
 | 
			
		||||
        for (i=0; i<Menu_bars[MENUBAR_TOOLS].Skin_width; i++)
 | 
			
		||||
          Remap_pixel(&Gfx->Menu_block[k][j][i]);
 | 
			
		||||
    // Menu sprites
 | 
			
		||||
    for (k=0; k<NB_MENU_SPRITES; k++)
 | 
			
		||||
      for (j=0; j<MENU_SPRITE_HEIGHT; j++)
 | 
			
		||||
        for (i=0; i<MENU_SPRITE_WIDTH; i++)
 | 
			
		||||
          Remap_pixel(&Gfx->Menu_sprite[k][j][i]);
 | 
			
		||||
    for (l=0; l<2; l++)
 | 
			
		||||
      for (k=0; k<NB_MENU_SPRITES; k++)
 | 
			
		||||
        for (j=0; j<MENU_SPRITE_HEIGHT; j++)
 | 
			
		||||
          for (i=0; i<MENU_SPRITE_WIDTH; i++)
 | 
			
		||||
            Remap_pixel(&Gfx->Menu_sprite[l][k][j][i]);
 | 
			
		||||
    // Effects sprites
 | 
			
		||||
    for (k=0; k<NB_EFFECTS_SPRITES; k++)
 | 
			
		||||
      for (j=0; j<MENU_SPRITE_HEIGHT; j++)
 | 
			
		||||
        for (i=0; i<MENU_SPRITE_WIDTH; i++)
 | 
			
		||||
      for (j=0; j<EFFECT_SPRITE_HEIGHT; j++)
 | 
			
		||||
        for (i=0; i<EFFECT_SPRITE_WIDTH; i++)
 | 
			
		||||
          Remap_pixel(&Gfx->Effect_sprite[k][j][i]);
 | 
			
		||||
    // Layers buttons
 | 
			
		||||
    for (l=0; l<3; l++)
 | 
			
		||||
@ -2944,13 +3082,15 @@ void Remap_menu_sprites()
 | 
			
		||||
            Remap_pixel(&Gfx->Layer_sprite[l][k][j][i]);
 | 
			
		||||
    
 | 
			
		||||
    // Status bar
 | 
			
		||||
    for (j=0; j<Menu_bars[MENUBAR_STATUS].Height; j++)
 | 
			
		||||
      for (i=0; i<Menu_bars[MENUBAR_STATUS].Skin_width; i++)
 | 
			
		||||
        Remap_pixel(&Gfx->Statusbar_block[j][i]);
 | 
			
		||||
    for (k=0; k<3; k++)
 | 
			
		||||
      for (j=0; j<Menu_bars[MENUBAR_STATUS].Height; j++)
 | 
			
		||||
        for (i=0; i<Menu_bars[MENUBAR_STATUS].Skin_width; i++)
 | 
			
		||||
          Remap_pixel(&Gfx->Statusbar_block[k][j][i]);
 | 
			
		||||
    // Layer bar
 | 
			
		||||
    for (j=0; j<Menu_bars[MENUBAR_LAYERS].Height; j++)
 | 
			
		||||
      for (i=0; i<Menu_bars[MENUBAR_LAYERS].Skin_width; i++)
 | 
			
		||||
        Remap_pixel(&Gfx->Layerbar_block[j][i]);
 | 
			
		||||
    for (k=0; k<3; k++)
 | 
			
		||||
      for (j=0; j<Menu_bars[MENUBAR_LAYERS].Height; j++)
 | 
			
		||||
        for (i=0; i<Menu_bars[MENUBAR_LAYERS].Skin_width; i++)
 | 
			
		||||
          Remap_pixel(&Gfx->Layerbar_block[k][j][i]);
 | 
			
		||||
    
 | 
			
		||||
    // Help fonts
 | 
			
		||||
    for (k=0; k<256; k++)
 | 
			
		||||
 | 
			
		||||
@ -89,7 +89,7 @@ void Window_display_frame_in(word x_pos,word y_pos,word width,word height);
 | 
			
		||||
void Window_display_frame_out(word x_pos,word y_pos,word width,word height);
 | 
			
		||||
void Window_display_frame(word x_pos,word y_pos,word width,word height);
 | 
			
		||||
 | 
			
		||||
void Display_sprite_in_menu(int btn_number,int sprite_number);
 | 
			
		||||
void Display_sprite_in_menu(int btn_number,char sprite_number);
 | 
			
		||||
void Display_paintbrush_in_menu(void);
 | 
			
		||||
void Display_paintbrush_in_window(word x,word y,int number);
 | 
			
		||||
 | 
			
		||||
@ -99,6 +99,7 @@ void Window_display_icon_sprite(word x_pos,word y_pos,byte type);
 | 
			
		||||
 | 
			
		||||
byte Best_color(byte red,byte green,byte blue);
 | 
			
		||||
byte Best_color_nonexcluded(byte red,byte green,byte blue);
 | 
			
		||||
byte Best_color_perceptual(byte r,byte g,byte b);
 | 
			
		||||
 | 
			
		||||
void Horizontal_XOR_line_zoom(short x_pos, short y_pos, short width);
 | 
			
		||||
void Vertical_XOR_line_zoom(short x_pos, short y_pos, short height);
 | 
			
		||||
@ -108,4 +109,7 @@ void Change_magnifier_factor(byte factor_index, byte point_at_mouse);
 | 
			
		||||
/// Width of one layer button, in pixels before scaling
 | 
			
		||||
extern word Layer_button_width;
 | 
			
		||||
 | 
			
		||||
/// Copy viewport settings and offsets from the Main to the Spare.
 | 
			
		||||
void Copy_view_to_spare(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user