diff --git a/Makefile b/Makefile index b2d3568ed..8b07ffce7 100644 --- a/Makefile +++ b/Makefile @@ -7,12 +7,12 @@ # bill@newbreedsoftware.com # http://www.tuxpaint.org/ -# June 14, 2002 - July 1, 2007 +# June 14, 2002 - July 3, 2007 # The version number, for release: -VER_VERSION=0.9.17 +VER_VERSION=0.9.18 VER_DATE=`date +"%Y-%m-%d"` @@ -37,6 +37,11 @@ EXE_EXT= DATA_PREFIX=$(PKG_ROOT)$(PREFIX)/share/tuxpaint +# Magic Tool plug-ins + +MAGIC_PREFIX=$(PKG_ROOT)$(PREFIX)/lib/tuxpaint + + # Docs and man page: DOC_PREFIX=$(PKG_ROOT)$(PREFIX)/share/doc/tuxpaint @@ -129,6 +134,7 @@ DEFS=-DDATA_PREFIX=\"$(DATA_PREFIX)/\" \ -DDOC_PREFIX=\"$(DOC_PREFIX)/\" \ -DLOCALEDIR=\"$(LOCALE_PREFIX)/\" -DIMDIR=\"$(IM_PREFIX)/\" \ -DCONFDIR=\"$(CONFDIR)/\" \ + -DMAGIC_PREFIX=\"$(MAGIC_PREFIX)/\" \ -DVER_VERSION=\"$(VER_VERSION)\" \ -DVER_DATE=\"$(VER_DATE)\" \ -D$(MAEMOFLAG) @@ -141,7 +147,7 @@ MOUSE_CFLAGS=-Isrc/$(MOUSEDIR) -D$(CURSOR_SHAPES)_CURSOR_SHAPES # "make" with no arguments builds the program and man page from sources: -all: tuxpaint translations +all: tuxpaint translations magic-plugins @echo @echo "--------------------------------------------------------------" @echo @@ -284,6 +290,7 @@ include Makefile-i18n # to do this as superuser ("root")) install: install-bin install-data install-man install-doc \ + install-magic-plugins \ install-icon install-gettext install-im install-importscript \ install-default-config install-example-stamps \ install-example-starters \ @@ -306,9 +313,21 @@ install: install-bin install-data install-man install-doc \ @echo +install-magic-plugins: + @echo + @echo "...Installing Magic Tool plug-ins..." + @install -d $(MAGIC_PREFIX) + @cp magic/*.so $(MAGIC_PREFIX) + @chmod a+r,g-w,o-w $(MAGIC_PREFIX)/*.so + @install -d $(DATA_PREFIX)/images/magic + @cp magic/icons/*.png $(DATA_PREFIX)/images/magic + @chmod a+r,g-w,o-w $(DATA_PREFIX)/images/magic/*.png + + # Installs the various parts for the MinGW/MSYS development/testing environment. install-private-win32: install-bin install-data install-man install-doc \ + install-magic-plugins \ install-gettext install-im install-importscript \ install-default-config install-example-stamps \ install-example-starters @@ -333,6 +352,7 @@ install-private-win32: install-bin install-data install-man install-doc \ # Installs the various parts for the MinGW/MSYS development/testing environment. bdist-private-win32: install-bin install-data install-doc \ + install-magic-plugins \ install-gettext install-im install-dlls\ install-example-stamps install-example-starters @echo @@ -432,6 +452,7 @@ clean: @#if [ -d obj ]; then rmdir obj; fi @-rm -f trans/*.mo @if [ -d trans ]; then rmdir trans; fi + @cd magic ; make clean @echo @@ -471,6 +492,7 @@ uninstall: uninstall-i18n -rm $(MAN_PREFIX)/pl/man1/tuxpaint.1.gz -rm $(MAN_PREFIX)/man1/tuxpaint-import.1.gz -rm -f -r $(CONFDIR) + -rm -r $(MAGIC_PREFIX) # Install default config file: @@ -736,7 +758,7 @@ obj/tuxpaint.o: src/tuxpaint.c \ src/progressbar.h src/dirwalk.h src/get_fname.h \ src/compiler.h src/debug.h \ src/tools.h src/titles.h src/colors.h src/shapes.h \ - src/magic.h src/sounds.h src/tip_tux.h src/great.h \ + src/sounds.h src/tip_tux.h src/great.h \ $(HQXX_H) \ src/$(MOUSEDIR)/arrow.xbm src/$(MOUSEDIR)/arrow-mask.xbm \ src/$(MOUSEDIR)/hand.xbm src/$(MOUSEDIR)/hand-mask.xbm \ @@ -857,6 +879,11 @@ obj/resource.o: visualc/resources.rc obj visualc/resource.h @windres -i visualc/resources.rc -o obj/resource.o +# Go into 'magic' subdirectory and buld magic plug-ins + +magic-plugins: + @cd magic ; make DATA_PREFIX="$(DATA_PREFIX)" + # Make the "obj" directory to throw the object(s) into: # (not necessary any more; bjk 2006.02.20) diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 29032f219..d39991517 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -9,6 +9,15 @@ http://www.tuxpaint.org/ $Id$ +2007.July.3 (0.9.18) + * System-Related Improvements: + ---------------------------- + * Adding an API for developing Magic tools as plug-ins. + (e.g., '.so' shared objects under Linux) + + * Ported (most of) 'Negative' magic tool to Magic tool plug-in system. + + 2007.July.1 (0.9.17) * Interface Improvements: diff --git a/magic/Makefile b/magic/Makefile new file mode 100644 index 000000000..7401c8315 --- /dev/null +++ b/magic/Makefile @@ -0,0 +1,35 @@ +# Makefile for magic plugins + +SDL_CFLAGS=$(shell sdl-config --cflags) +CFLAGS=-g -Wall $(SDL_CFLAGS) -DDATA_PREFIX=\"$(DATA_PREFIX)\" +#-fPIC ? + +all: negative.so + +clean: + @echo + @echo "Cleaning up the Magic plug-ins directory ($(PWD))" + @-rm -f *.so + @-rm -f obj/* + + +# Negative tool +# ------------------------------------------------------------------------ + +negative.so: obj obj/negative.o obj/magic_helpers.o + @echo "Linking Negative magic tool" + @$(CC) -shared -o negative.so obj/negative.o obj/magic_helpers.o + +obj/negative.o: src/negative.c src/magic_helpers.h + @echo "Compiling Negative magic tool" + @$(CC) $(CFLAGS) src/negative.c -c -o obj/negative.o + + + +obj/magic_helpers.o: src/magic_helpers.c src/magic_helpers.h + @echo "Compiling Magic tool helper routines" + @$(CC) $(CFLAGS) src/magic_helpers.c -c -o obj/magic_helpers.o + +obj: + @-mkdir obj + diff --git a/magic/icons/blocks.png b/magic/icons/blocks.png new file mode 100644 index 000000000..348f7fbb9 Binary files /dev/null and b/magic/icons/blocks.png differ diff --git a/magic/icons/blur.png b/magic/icons/blur.png new file mode 100644 index 000000000..eff7bf3b1 Binary files /dev/null and b/magic/icons/blur.png differ diff --git a/magic/icons/cartoon.png b/magic/icons/cartoon.png new file mode 100644 index 000000000..5613dd217 Binary files /dev/null and b/magic/icons/cartoon.png differ diff --git a/magic/icons/chalk.png b/magic/icons/chalk.png new file mode 100644 index 000000000..69431c7a5 Binary files /dev/null and b/magic/icons/chalk.png differ diff --git a/magic/icons/darken.png b/magic/icons/darken.png new file mode 100644 index 000000000..ce5bade63 Binary files /dev/null and b/magic/icons/darken.png differ diff --git a/magic/icons/drip.png b/magic/icons/drip.png new file mode 100644 index 000000000..8cda69923 Binary files /dev/null and b/magic/icons/drip.png differ diff --git a/magic/icons/fade.png b/magic/icons/fade.png new file mode 100644 index 000000000..a8bef4fd1 Binary files /dev/null and b/magic/icons/fade.png differ diff --git a/magic/icons/fill.png b/magic/icons/fill.png new file mode 100644 index 000000000..b0de5e3c7 Binary files /dev/null and b/magic/icons/fill.png differ diff --git a/magic/icons/flip.png b/magic/icons/flip.png new file mode 100644 index 000000000..b6ee7ceff Binary files /dev/null and b/magic/icons/flip.png differ diff --git a/magic/icons/grass.png b/magic/icons/grass.png new file mode 100644 index 000000000..c79f5fec9 Binary files /dev/null and b/magic/icons/grass.png differ diff --git a/magic/icons/largebrick.png b/magic/icons/largebrick.png new file mode 100644 index 000000000..00410701a Binary files /dev/null and b/magic/icons/largebrick.png differ diff --git a/magic/icons/mirror.png b/magic/icons/mirror.png new file mode 100644 index 000000000..f37c4cc88 Binary files /dev/null and b/magic/icons/mirror.png differ diff --git a/magic/icons/negative.png b/magic/icons/negative.png new file mode 100644 index 000000000..5a5189275 Binary files /dev/null and b/magic/icons/negative.png differ diff --git a/magic/icons/rainbow.png b/magic/icons/rainbow.png new file mode 100644 index 000000000..9371bf7d8 Binary files /dev/null and b/magic/icons/rainbow.png differ diff --git a/magic/icons/smallbrick.png b/magic/icons/smallbrick.png new file mode 100644 index 000000000..b42da8e62 Binary files /dev/null and b/magic/icons/smallbrick.png differ diff --git a/magic/icons/smudge.png b/magic/icons/smudge.png new file mode 100644 index 000000000..79e945066 Binary files /dev/null and b/magic/icons/smudge.png differ diff --git a/magic/icons/sparkles.png b/magic/icons/sparkles.png new file mode 100644 index 000000000..eac486810 Binary files /dev/null and b/magic/icons/sparkles.png differ diff --git a/magic/icons/thick.png b/magic/icons/thick.png new file mode 100644 index 000000000..2b57ae2e1 Binary files /dev/null and b/magic/icons/thick.png differ diff --git a/magic/icons/thin.png b/magic/icons/thin.png new file mode 100644 index 000000000..c93ed35cd Binary files /dev/null and b/magic/icons/thin.png differ diff --git a/magic/icons/tint.png b/magic/icons/tint.png new file mode 100644 index 000000000..7b7b90d0d Binary files /dev/null and b/magic/icons/tint.png differ diff --git a/magic/src/magic_helpers.c b/magic/src/magic_helpers.c new file mode 100644 index 000000000..5dfc3ac84 --- /dev/null +++ b/magic/src/magic_helpers.c @@ -0,0 +1,238 @@ +#include "../../src/compiler.h" +#include "magic_helpers.h" + +int MAGIC_in_circle(int x, int y, int radius) +{ + if ((x * x) + (y * y) - (radius * radius) < 0) + return (1); + else + return (0); +} + + +/* Draw a single pixel into the surface: */ + +void MAGIC_putpixel8(SDL_Surface * surface, int x, int y, Uint32 pixel) +{ + Uint8 *p; + + /* Assuming the X/Y values are within the bounds of this surface... */ + if (likely + (likely((unsigned) x < (unsigned) surface->w) + && likely((unsigned) y < (unsigned) surface->h))) + { + // Set a pointer to the exact location in memory of the pixel + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + x); /* Go in X pixels */ + + + /* Set the (correctly-sized) piece of data in the surface's RAM + * to the pixel value sent in: */ + + *p = pixel; + } +} + +/* Draw a single pixel into the surface: */ +void MAGIC_putpixel16(SDL_Surface * surface, int x, int y, Uint32 pixel) +{ + Uint8 *p; + + /* Assuming the X/Y values are within the bounds of this surface... */ + if (likely + (likely((unsigned) x < (unsigned) surface->w) + && likely((unsigned) y < (unsigned) surface->h))) + { + // Set a pointer to the exact location in memory of the pixel + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + (x * 2)); /* Go in X pixels */ + + + /* Set the (correctly-sized) piece of data in the surface's RAM + * to the pixel value sent in: */ + + *(Uint16 *) p = pixel; + } +} + +/* Draw a single pixel into the surface: */ +void MAGIC_putpixel24(SDL_Surface * surface, int x, int y, Uint32 pixel) +{ + Uint8 *p; + + /* Assuming the X/Y values are within the bounds of this surface... */ + if (likely + (likely((unsigned) x < (unsigned) surface->w) + && likely((unsigned) y < (unsigned) surface->h))) + { + // Set a pointer to the exact location in memory of the pixel + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + (x * 3)); /* Go in X pixels */ + + + /* Set the (correctly-sized) piece of data in the surface's RAM + * to the pixel value sent in: */ + + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) + { + p[0] = (pixel >> 16) & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = pixel & 0xff; + } + else + { + p[0] = pixel & 0xff; + p[1] = (pixel >> 8) & 0xff; + p[2] = (pixel >> 16) & 0xff; + } + + } +} + +/* Draw a single pixel into the surface: */ +void MAGIC_putpixel32(SDL_Surface * surface, int x, int y, Uint32 pixel) +{ + Uint8 *p; + + /* Assuming the X/Y values are within the bounds of this surface... */ + if (likely + (likely((unsigned) x < (unsigned) surface->w) + && likely((unsigned) y < (unsigned) surface->h))) + { + // Set a pointer to the exact location in memory of the pixel + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + (x * 4)); /* Go in X pixels */ + + + /* Set the (correctly-sized) piece of data in the surface's RAM + * to the pixel value sent in: */ + + *(Uint32 *) p = pixel; // 32-bit display + } +} + +/* Get a pixel: */ +Uint32 MAGIC_getpixel8(SDL_Surface * surface, int x, int y) +{ + Uint8 *p; + + /* get the X/Y values within the bounds of this surface */ + if (unlikely((unsigned) x > (unsigned) surface->w - 1u)) + x = (x < 0) ? 0 : surface->w - 1; + if (unlikely((unsigned) y > (unsigned) surface->h - 1u)) + y = (y < 0) ? 0 : surface->h - 1; + + /* Set a pointer to the exact location in memory of the pixel + in question: */ + + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + x); /* Go in X pixels */ + + + /* Return the correctly-sized piece of data containing the + * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit + * RGB value) */ + + return (*p); +} + +/* Get a pixel: */ +Uint32 MAGIC_getpixel16(SDL_Surface * surface, int x, int y) +{ + Uint8 *p; + + /* get the X/Y values within the bounds of this surface */ + if (unlikely((unsigned) x > (unsigned) surface->w - 1u)) + x = (x < 0) ? 0 : surface->w - 1; + if (unlikely((unsigned) y > (unsigned) surface->h - 1u)) + y = (y < 0) ? 0 : surface->h - 1; + + /* Set a pointer to the exact location in memory of the pixel + in question: */ + + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + (x * 2)); /* Go in X pixels */ + + + /* Return the correctly-sized piece of data containing the + * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit + * RGB value) */ + + return (*(Uint16 *) p); +} + +/* Get a pixel: */ +Uint32 MAGIC_getpixel24(SDL_Surface * surface, int x, int y) +{ + Uint8 *p; + Uint32 pixel; + + /* get the X/Y values within the bounds of this surface */ + if (unlikely((unsigned) x > (unsigned) surface->w - 1u)) + x = (x < 0) ? 0 : surface->w - 1; + if (unlikely((unsigned) y > (unsigned) surface->h - 1u)) + y = (y < 0) ? 0 : surface->h - 1; + + /* Set a pointer to the exact location in memory of the pixel + in question: */ + + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + (x * 3)); /* Go in X pixels */ + + + /* Return the correctly-sized piece of data containing the + * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit + * RGB value) */ + + /* Depending on the byte-order, it could be stored RGB or BGR! */ + + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) + pixel = p[0] << 16 | p[1] << 8 | p[2]; + else + pixel = p[0] | p[1] << 8 | p[2] << 16; + + return pixel; +} + +/* Get a pixel: */ +Uint32 MAGIC_getpixel32(SDL_Surface * surface, int x, int y) +{ + Uint8 *p; + + /* get the X/Y values within the bounds of this surface */ + if (unlikely((unsigned) x > (unsigned) surface->w - 1u)) + x = (x < 0) ? 0 : surface->w - 1; + if (unlikely((unsigned) y > (unsigned) surface->h - 1u)) + y = (y < 0) ? 0 : surface->h - 1; + + /* Set a pointer to the exact location in memory of the pixel + in question: */ + + p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start at top of RAM */ + (y * surface->pitch) + /* Go down Y lines */ + (x * 4)); /* Go in X pixels */ + + + /* Return the correctly-sized piece of data containing the + * pixel's value (an 8-bit palette value, or a 16-, 24- or 32-bit + * RGB value) */ + + return *(Uint32 *) p; // 32-bit display +} + +void (*MAGIC_putpixels[]) (SDL_Surface *, int, int, Uint32) = +{ +MAGIC_putpixel8, MAGIC_putpixel8, MAGIC_putpixel16, MAGIC_putpixel24, MAGIC_putpixel32}; + + +Uint32(*MAGIC_getpixels[])(SDL_Surface *, int, int) = +{ +MAGIC_getpixel8, MAGIC_getpixel8, MAGIC_getpixel16, MAGIC_getpixel24, MAGIC_getpixel32}; + diff --git a/magic/src/magic_helpers.h b/magic/src/magic_helpers.h new file mode 100644 index 000000000..d97653a05 --- /dev/null +++ b/magic/src/magic_helpers.h @@ -0,0 +1,23 @@ +#ifndef MAGIC_HELPERS_H +#define MAGIC_HELPERS_H + +#include "SDL.h" +#include + +int MAGIC_in_circle(int x, int y, int radius); + +void MAGIC_putpixel8(SDL_Surface * surface, int x, int y, Uint32 pixel); +void MAGIC_putpixel16(SDL_Surface * surface, int x, int y, Uint32 pixel); +void MAGIC_putpixel24(SDL_Surface * surface, int x, int y, Uint32 pixel); +void MAGIC_putpixel32(SDL_Surface * surface, int x, int y, Uint32 pixel); + +extern void (*MAGIC_putpixels[]) (SDL_Surface *, int, int, Uint32); + +Uint32 MAGIC_getpixel8(SDL_Surface * surface, int x, int y); +Uint32 MAGIC_getpixel16(SDL_Surface * surface, int x, int y); +Uint32 MAGIC_getpixel24(SDL_Surface * surface, int x, int y); +Uint32 MAGIC_getpixel32(SDL_Surface * surface, int x, int y); + +extern Uint32(*MAGIC_getpixels[]) (SDL_Surface *, int, int); + +#endif diff --git a/magic/src/negative.c b/magic/src/negative.c new file mode 100644 index 000000000..fed671b12 --- /dev/null +++ b/magic/src/negative.c @@ -0,0 +1,111 @@ +#include +#include +#include "SDL_image.h" +#include "magic_helpers.h" + +void init() +{ + printf("negative plugin initializing\n"); +} + +int get_tool_count(void) +{ + printf("negative tool reporting tool count: 1\n"); + return(1); +} + +SDL_Surface * get_icon(int which) +{ + printf("Loading icon: " DATA_PREFIX "/images/magic/negative.png\n"); + return(IMG_Load(DATA_PREFIX "/images/magic/negative.png")); +} + +char * get_name(int which) +{ + /* Only 1 tool; ignoring 'which' */ + + return(strdup(gettext("Negative"))); +} + +char * get_description(int which) +{ + /* Only 1 tool; ignoring 'which' */ + + return(strdup(gettext("Click and move the mouse around to draw a negative."))); +} + +void drag(int which, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y); + +void click(int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y) +{ +/* + SDL_Rect src, dest; + + src.x = x - 12; + src.y = y - 12; + src.w = 16; + src.h = 16; + + dest.x = x - 8; + dest.y = y - 8; + dest.w = 16; + dest.h = 16; + + SDL_BlitSurface(last, &src, canvas, &dest); +*/ + + drag(which, canvas, last, x, y, x, y); +} + +void drag(int which, SDL_Surface * canvas, SDL_Surface * last, int ox, int oy, int x, int y) +{ + int xx, yy; + Uint8 r, g, b; + void (*putpixel) (SDL_Surface *, int, int, Uint32) = + MAGIC_putpixels[canvas->format->BytesPerPixel]; + Uint32(*getpixel_last) (SDL_Surface *, int, int); + + getpixel_last = MAGIC_getpixels[last->format->BytesPerPixel]; + + + SDL_LockSurface(last); + SDL_LockSurface(canvas); + + for (yy = y - 16; yy < y + 16; yy++) + { + for (xx = x - 16; xx < x + 16; xx++) + { + if (MAGIC_in_circle(xx - x, yy - y, 16)) + { + SDL_GetRGB(getpixel_last(last, xx, yy), last->format, &r, &g, &b); + + r = 0xFF - r; + g = 0xFF - g; + b = 0xFF - b; + + putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b)); + } + } + } + + SDL_UnlockSurface(canvas); + SDL_UnlockSurface(last); +} + +void shutdown() +{ + printf("negative plugin shutting down\n"); +} + +void set_color(Uint8 r, Uint8 g, Uint8 b) +{ + /* Doesn't use color; ignoring */ +} + +int requires_colors(int which) +{ + /* (Only 1 tool; ignoring 'which') */ + + return 0; // Don't need a color palette +} + diff --git a/src/tuxpaint.c b/src/tuxpaint.c index 19cc640aa..f10ebe9d1 100644 --- a/src/tuxpaint.c +++ b/src/tuxpaint.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (See COPYING.txt) - June 14, 2002 - June 25, 2007 + June 14, 2002 - July 3, 2007 $Id$ */ @@ -408,7 +408,6 @@ extern WrapperData macosx; #include "titles.h" #include "colors.h" #include "shapes.h" -#include "magic.h" #include "sounds.h" #include "tip_tux.h" #include "great.h" @@ -846,6 +845,27 @@ static int recording, playing; static char *playfile; static FILE *demofi; +typedef struct magic_funcs_s { + int (*get_tool_count)(void); + char * (*get_name)(int); + SDL_Surface * (*get_icon)(int); + char * (*get_description)(int); + int (*requires_colors)(int); + void (*set_color)(Uint8, Uint8, Uint8); + int (*init)(void); + void (*shutdown)(void); + void (*click)(int, SDL_Surface *, SDL_Surface *, int, int); + void (*drag)(int, SDL_Surface *, SDL_Surface *, int, int, int, int); +} magic_funcs_t; + +static int num_plugin_files; +static int num_magics; +void * magic_handle[512]; +magic_funcs_t magic_funcs[512]; +static int magic_colors[512]; +static char * magic_names[512]; +static char * magic_tips[512]; + #if !defined(WIN32) && !defined(__APPLE__) && !defined(__BEOS__) static const char *printcommand = PRINTCOMMAND; static const char *altprintcommand = ALTPRINTCOMMAND; @@ -1040,7 +1060,7 @@ static int * brushes_spacing = NULL; static short * brushes_directional = NULL; static SDL_Surface *img_shapes[NUM_SHAPES], *img_shape_names[NUM_SHAPES]; -static SDL_Surface *img_magics[NUM_MAGICS], *img_magic_names[NUM_MAGICS]; +static SDL_Surface * img_magics[512], * img_magic_names[512]; static SDL_Surface *img_openlabels_open, *img_openlabels_erase, *img_openlabels_slideshow, *img_openlabels_back, *img_openlabels_play, *img_openlabels_next; @@ -1299,6 +1319,7 @@ static void flip_starter(void); int valid_click(Uint8 button); int in_circle(int x, int y); int paintsound(int size); +void load_magic_plugins(void); #ifdef DEBUG static char *debug_gettext(const char *str); @@ -2174,7 +2195,7 @@ static void mainloop(void) else if (cur_tool == TOOL_MAGIC) { cur_thing = cur_magic; - num_things = NUM_MAGICS; + num_things = num_magics; thing_scroll = &magic_scroll; rainbow_color = 0; draw_magic(); @@ -2944,18 +2965,23 @@ static void mainloop(void) /* Mirror or flip, make a note so we record it for the starters, too! */ +#if 0 /* MAGIC_ME */ if (cur_magic == MAGIC_MIRROR) undo_starters[tmp_int] = UNDO_STARTER_MIRRORED; else if (cur_magic == MAGIC_FLIP) undo_starters[tmp_int] = UNDO_STARTER_FLIPPED; +#endif /* (Arbitrarily large, so we draw once now) */ reset_brush_counter(); +#if 0 /* MAGIC_ME */ if (cur_magic != MAGIC_FILL) { +#endif magic_draw(old_x, old_y, old_x, old_y, button_down); +#if 0 /* MAGIC_ME */ } else { @@ -2970,12 +2996,15 @@ static void mainloop(void) draw_tux_text(TUX_GREAT, magic_tips[MAGIC_FILL], 1); } +#endif +#if 0 if (cur_magic == MAGIC_FLIP || cur_magic == MAGIC_MIRROR || cur_magic == MAGIC_FILL) { update_canvas(0, 0, canvas->w, canvas->h); } +#endif } else if (cur_tool == TOOL_ERASER) { @@ -3503,8 +3532,10 @@ static void mainloop(void) { /* Pushing button and moving: Do the magic: */ +#if 0 // MAGIC_ME if (cur_magic != MAGIC_FLIP && cur_magic != MAGIC_MIRROR && cur_magic != MAGIC_FILL) +#endif { magic_draw(old_x, old_y, new_x, new_y, button_down); } @@ -4372,8 +4403,10 @@ static void magic_draw(int x1, int y1, int x2, int y2, int button_down) int orig_x1, orig_y1, orig_x2, orig_y2, tmp; float m, b; +#if 0 /* MAGIC_ME */ if (cur_magic == MAGIC_RAINBOW) rainbow_color = (rainbow_color + 1) % NUM_RAINBOW_COLORS; +#endif orig_x1 = x1; orig_y1 = y1; @@ -4444,6 +4477,8 @@ static void magic_draw(int x1, int y1, int x2, int y2, int button_down) } +#if 0 /* MAGIC_ME */ + /* Play sound: */ if (cur_magic == MAGIC_DRIP) @@ -4477,6 +4512,8 @@ static void magic_draw(int x1, int y1, int x2, int y2, int button_down) else if (cur_magic == MAGIC_GRASS) playsound(screen, 0, SND_GRASS, 0, x1, y1); +#endif + /* FIXME: Arbitrary? */ update_canvas(orig_x1 - 32, orig_y1 - 32, orig_x2 + 32, orig_y2 + 64); @@ -4498,6 +4535,8 @@ static int log2int(int x) return y; } +#if 0 // MAGIC_ME + static void do_brick(int x, int y, int w, int h) { SDL_Rect dest; @@ -4536,6 +4575,9 @@ static void do_brick(int x, int y, int w, int h) playsound(screen, 0, SND_BRICK, 1, x, SNDDIST_NEAR); } +#endif + + /* Draw the current brush in the current color: */ static void blit_magic(int x, int y, int button_down) @@ -4570,7 +4612,10 @@ static void blit_magic(int x, int y, int button_down) { brush_counter = 0; + magic_funcs[cur_magic].click(0 /* MAGIC_ME */, canvas, last, x, y); + +#if 0 // MAGIC_ME if (cur_magic == MAGIC_BLUR) { double state[32][32][3]; @@ -5261,7 +5306,6 @@ static void blit_magic(int x, int y, int button_down) if (img_starter != NULL) mirror_starter(); } -#if 0 else if (cur_magic == MAGIC_THIN || cur_magic == MAGIC_THICK) { SDL_LockSurface(last); @@ -7652,9 +7696,9 @@ static void setup(int argc, char *argv[]) load_stamps(screen); - /* Load magic icons: */ - for (i = 0; i < NUM_MAGICS; i++) - img_magics[i] = loadimage(magic_img_fnames[i]); + /* Load magic tool plugins: */ + + load_magic_plugins(); show_progress_bar(screen); @@ -7896,7 +7940,7 @@ static void create_button_labels(void) for (i = 0; i < NUM_TOOLS; i++) img_tool_names[i] = do_render_button_label(tool_names[i]); - for (i = 0; i < NUM_MAGICS; i++) + for (i = 0; i < num_magics; i++) img_magic_names[i] = do_render_button_label(magic_names[i]); for (i = 0; i < NUM_SHAPES; i++) @@ -8149,16 +8193,16 @@ static void draw_magic(void) int magic, i, max, off_y; SDL_Rect dest; +#if 0 // MAGIC_ME // restore these to black (stamp and text controls borrow them) SDL_BlitSurface(img_black, NULL, img_magics[MAGIC_FLIP], NULL); SDL_BlitSurface(img_black, NULL, img_magics[MAGIC_MIRROR], NULL); - - /* FIXME: Should we worry about more than 14 magic effects? :^/ */ +#endif draw_image_title(TITLE_MAGIC, r_ttoolopt); - if (NUM_MAGICS > 14 + TOOLOFFSET) + if (num_magics > 14 + TOOLOFFSET) { off_y = 24; max = 12 + TOOLOFFSET; @@ -8178,7 +8222,7 @@ static void draw_magic(void) dest.x = WINDOW_WIDTH - 96; dest.y = 40 + 24 + ((6 + TOOLOFFSET / 2) * 48); - if (magic_scroll < NUM_MAGICS - 12 - TOOLOFFSET) + if (magic_scroll < num_magics - 12 - TOOLOFFSET) { SDL_BlitSurface(img_scroll_down, NULL, screen, &dest); } @@ -8201,7 +8245,7 @@ static void draw_magic(void) dest.x = ((i % 2) * 48) + (WINDOW_WIDTH - 96); dest.y = ((i / 2) * 48) + 40 + off_y; - if (magic < NUM_MAGICS) + if (magic < num_magics) { if (magic == cur_magic) { @@ -8781,6 +8825,7 @@ static void draw_stamps(void) if (!disable_stamp_controls) { +#if 0 // MAGIC_ME /* Show mirror button: */ dest.x = WINDOW_WIDTH - 96; @@ -8813,7 +8858,6 @@ static void draw_stamps(void) SDL_BlitSurface(button_color, NULL, img_magics[MAGIC_MIRROR], NULL); SDL_BlitSurface(img_magics[MAGIC_MIRROR], NULL, screen, &dest); - /* Show flip button: */ dest.x = WINDOW_WIDTH - 48; @@ -8846,6 +8890,8 @@ static void draw_stamps(void) SDL_BlitSurface(button_color, NULL, img_magics[MAGIC_FLIP], NULL); SDL_BlitSurface(img_magics[MAGIC_FLIP], NULL, screen, &dest); +#endif + #ifdef OLD_STAMP_GROW_SHRINK /* Show shrink button: */ @@ -11688,8 +11734,8 @@ static void cleanup(void) free_surface_array(img_tools, NUM_TOOLS); free_surface_array(img_tool_names, NUM_TOOLS); free_surface_array(img_title_names, NUM_TITLES); - free_surface_array(img_magics, NUM_MAGICS); - free_surface_array(img_magic_names, NUM_MAGICS); + free_surface_array(img_magics, num_magics); + free_surface_array(img_magic_names, num_magics); free_surface_array(img_shapes, NUM_SHAPES); free_surface_array(img_shape_names, NUM_SHAPES); free_surface_array(img_tux, NUM_TIP_TUX); @@ -16733,3 +16779,179 @@ float pick_best_scape(unsigned int orig_w, unsigned int orig_h, } #endif + + +void load_magic_plugins(void) +{ + int res, n, i; + DIR *d; + struct dirent *f; + char fname[512]; + + num_plugin_files = 0; + num_magics = 0; + + printf("\n"); + printf("Loading magic plug-ins from %s\n", MAGIC_PREFIX); + fflush(stdout); + + d = opendir(MAGIC_PREFIX); + + if (d != NULL) + { + /* Gather list of files (for sorting): */ + + do + { + f = readdir(d); + + if (f != NULL) + { + if (f->d_type == DT_REG) + { + snprintf(fname, sizeof(fname), "%s%s", MAGIC_PREFIX, f->d_name); + + magic_handle[num_plugin_files] = SDL_LoadObject(fname); + + if (magic_handle[num_plugin_files] != NULL) + { + printf("loading: %s\n", fname); + fflush(stdout); + + magic_funcs[num_plugin_files].get_tool_count = + SDL_LoadFunction(magic_handle[num_plugin_files], + "get_tool_count"); + + magic_funcs[num_plugin_files].get_name = + SDL_LoadFunction(magic_handle[num_plugin_files], + "get_name"); + + magic_funcs[num_plugin_files].get_icon = + SDL_LoadFunction(magic_handle[num_plugin_files], + "get_icon"); + + magic_funcs[num_plugin_files].get_description = + SDL_LoadFunction(magic_handle[num_plugin_files], + "get_description"); + + magic_funcs[num_plugin_files].requires_colors = + SDL_LoadFunction(magic_handle[num_plugin_files], + "requires_colors"); + + magic_funcs[num_plugin_files].set_color = + SDL_LoadFunction(magic_handle[num_plugin_files], + "set_color"); + + magic_funcs[num_plugin_files].init = + SDL_LoadFunction(magic_handle[num_plugin_files], + "init"); + + magic_funcs[num_plugin_files].shutdown = + SDL_LoadFunction(magic_handle[num_plugin_files], + "shutdown"); + + magic_funcs[num_plugin_files].click = + SDL_LoadFunction(magic_handle[num_plugin_files], + "click"); + + magic_funcs[num_plugin_files].drag = + SDL_LoadFunction(magic_handle[num_plugin_files], + "drag"); + +#ifdef DEBUG + printf("get_tool_count = 0x%x\n", + (int) magic_funcs[num_plugin_files].get_tool_count); + printf("get_name = 0x%x\n", + (int) magic_funcs[num_plugin_files].get_name); + printf("get_icon = 0x%x\n", + (int) magic_funcs[num_plugin_files].get_icon); + printf("get_description = 0x%x\n", + (int) magic_funcs[num_plugin_files].get_description); + printf("requires_colors = 0x%x\n", + (int) magic_funcs[num_plugin_files].requires_colors); + printf("set_color = 0x%x\n", + (int) magic_funcs[num_plugin_files].set_color); + printf("init = 0x%x\n", + (int) magic_funcs[num_plugin_files].init); + printf("shutdown = 0x%x\n", + (int) magic_funcs[num_plugin_files].shutdown); + printf("click = 0x%x\n", + (int) magic_funcs[num_plugin_files].click); + printf("drag = 0x%x\n", + (int) magic_funcs[num_plugin_files].drag); +#endif + + if (magic_funcs[num_plugin_files].get_tool_count == NULL || + magic_funcs[num_plugin_files].get_name == NULL || + magic_funcs[num_plugin_files].get_icon == NULL || + magic_funcs[num_plugin_files].get_description == NULL || + magic_funcs[num_plugin_files].requires_colors == NULL || + magic_funcs[num_plugin_files].set_color == NULL || + magic_funcs[num_plugin_files].init == NULL || + magic_funcs[num_plugin_files].shutdown == NULL || + magic_funcs[num_plugin_files].click == NULL || + magic_funcs[num_plugin_files].drag == NULL) + { + fprintf(stderr, "Error: plugin %s is missing function(s)\n", fname); + fflush(stderr); + SDL_UnloadObject(magic_handle[num_plugin_files]); + } + else + { + res = magic_funcs[num_plugin_files].init(); + + if (res != 0) + n = magic_funcs[num_plugin_files].get_tool_count(); + else + { + magic_funcs[num_plugin_files].shutdown(); + n = 0; + } + + + if (n == 0) + { + fprintf(stderr, "Error: plugin %s failed to startup or reported 0 magic tools\n", fname); + fflush(stderr); + SDL_UnloadObject(magic_handle[num_plugin_files]); + } + else + { + for (i = 0; i < n; i++) + { + magic_names[num_magics] = magic_funcs[num_plugin_files].get_name(i); + magic_tips[num_magics] = magic_funcs[num_plugin_files].get_description(i); + magic_colors[num_magics] = magic_funcs[num_plugin_files].requires_colors(i); + + img_magics[num_magics] = magic_funcs[num_plugin_files].get_icon(i); + + printf("-- %s\n", magic_names[i]); + + num_magics++; + } + + num_plugin_files++; + } + } + } + else + { + fprintf(stderr, "Warning: Failed to load object %s: %s\n", fname, SDL_GetError()); + fflush(stderr); + } + } + } + } + while (f != NULL); + + closedir(d); + } + + printf("Loaded %d magic tools from %d plug-in files\n", num_magics, + num_plugin_files); + printf("\n"); + fflush(stdout); + + /* FIXME: Sort it? -bjk 2007.07.03 */ +} +