Completed Negative Magic tool as a plugin (except sound).
Created Mirror and Flip Magic tools as plugins (except sound); hooks added to Magic plugin API to allow starter and starter-undo mirror/flip. Created Fade and Darken Magic tools as plugins. Moved magic tool sounds to 'magic'. Added flip and mirror icons to main Tux Paint UI (used to share magic tools') Created 'tp-magic-config.sh' to get CFLAGS for compiling magic tool plugins. Improved magic tool plugin API. Committed some documentation on magic tool plugin API.
This commit is contained in:
parent
c6aa0af0a9
commit
47e44cb80f
32 changed files with 917 additions and 729 deletions
29
Makefile
29
Makefile
|
|
@ -1,4 +1,4 @@
|
|||
# Makefile for tuxpaint
|
||||
|
||||
# $Id$
|
||||
|
||||
# Tux Paint - A simple drawing program for children.
|
||||
|
|
@ -39,13 +39,16 @@ DATA_PREFIX=$(PKG_ROOT)$(PREFIX)/share/tuxpaint
|
|||
|
||||
# Magic Tool plug-ins
|
||||
|
||||
INCLUDE_PREFIX=$(PKG_ROOT)$(PREFIX)/include
|
||||
MAGIC_PREFIX=$(PKG_ROOT)$(PREFIX)/lib/tuxpaint
|
||||
|
||||
|
||||
# Docs and man page:
|
||||
|
||||
DOC_PREFIX=$(PKG_ROOT)$(PREFIX)/share/doc/tuxpaint
|
||||
DEVDOC_PREFIX=$(PKG_ROOT)$(PREFIX)/share/doc/tuxpaint-dev
|
||||
MAN_PREFIX=$(PKG_ROOT)$(PREFIX)/share/man
|
||||
DEVMAN_PREFIX=$(PKG_ROOT)$(PREFIX)/share/man
|
||||
|
||||
|
||||
# 'System-wide' Config file:
|
||||
|
|
@ -291,6 +294,7 @@ include Makefile-i18n
|
|||
|
||||
install: install-bin install-data install-man install-doc \
|
||||
install-magic-plugins \
|
||||
install-magic-plugin-dev \
|
||||
install-icon install-gettext install-im install-importscript \
|
||||
install-default-config install-example-stamps \
|
||||
install-example-starters \
|
||||
|
|
@ -322,7 +326,24 @@ install-magic-plugins:
|
|||
@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
|
||||
@install -d $(DATA_PREFIX)/sounds/magic
|
||||
@cp magic/sounds/*.wav $(DATA_PREFIX)/sounds/magic
|
||||
@chmod a+r,g-w,o-w $(DATA_PREFIX)/sounds/magic/*.wav
|
||||
|
||||
install-magic-plugin-dev:
|
||||
@echo
|
||||
@echo "...Installing Magic Tool plug-in development files and docs..."
|
||||
@-rm $(BIN_PREFIX)/tp-magic-config
|
||||
@sed src/tp-magic-config.sh -e s/__VERSION__/$(VER_VERSION)/ \
|
||||
-e s=__INCLUDE__=$(INCLUDE_PREFIX)/tuxpaint= > \
|
||||
$(BIN_PREFIX)/tp-magic-config
|
||||
@chmod a+rx,g-w,o-w $(BIN_PREFIX)/tp-magic-config
|
||||
@install -d $(INCLUDE_PREFIX)/tuxpaint
|
||||
@cp src/tp_magic_api.h $(INCLUDE_PREFIX)/tuxpaint
|
||||
@chmod a+r,g-w,o-w $(INCLUDE_PREFIX)/tuxpaint/tp_magic_api.h
|
||||
@install -d $(DEVDOC_PREFIX)
|
||||
@cp -R magic/docs/* $(DEVDOC_PREFIX)
|
||||
@chmod a=rX,g=rX,u=rwX $(DEVDOC_PREFIX)
|
||||
|
||||
# Installs the various parts for the MinGW/MSYS development/testing environment.
|
||||
|
||||
|
|
@ -493,6 +514,9 @@ uninstall: uninstall-i18n
|
|||
-rm $(MAN_PREFIX)/man1/tuxpaint-import.1.gz
|
||||
-rm -f -r $(CONFDIR)
|
||||
-rm -r $(MAGIC_PREFIX)
|
||||
-rm -r $(INCLUDE_PREFIX)/tuxpaint
|
||||
-rm $(BIN_PREFIX)/tp-magic-config
|
||||
-rm -r $(DEVDOC_PREFIX)
|
||||
|
||||
|
||||
# Install default config file:
|
||||
|
|
@ -759,6 +783,7 @@ obj/tuxpaint.o: src/tuxpaint.c \
|
|||
src/compiler.h src/debug.h \
|
||||
src/tools.h src/titles.h src/colors.h src/shapes.h \
|
||||
src/sounds.h src/tip_tux.h src/great.h \
|
||||
src/tp_magic_api.h \
|
||||
$(HQXX_H) \
|
||||
src/$(MOUSEDIR)/arrow.xbm src/$(MOUSEDIR)/arrow-mask.xbm \
|
||||
src/$(MOUSEDIR)/hand.xbm src/$(MOUSEDIR)/hand-mask.xbm \
|
||||
|
|
@ -882,7 +907,7 @@ obj/resource.o: visualc/resources.rc obj visualc/resource.h
|
|||
# Go into 'magic' subdirectory and buld magic plug-ins
|
||||
|
||||
magic-plugins:
|
||||
@cd magic ; make DATA_PREFIX="$(DATA_PREFIX)"
|
||||
@cd magic ; make
|
||||
|
||||
# Make the "obj" directory to throw the object(s) into:
|
||||
# (not necessary any more; bjk 2006.02.20)
|
||||
|
|
|
|||
BIN
data/images/ui/flip.png
Normal file
BIN
data/images/ui/flip.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 186 B |
BIN
data/images/ui/mirror.png
Normal file
BIN
data/images/ui/mirror.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 766 B |
|
|
@ -9,13 +9,31 @@ http://www.tuxpaint.org/
|
|||
$Id$
|
||||
|
||||
|
||||
2007.July.4 (0.9.18)
|
||||
2007.July.5 (0.9.18)
|
||||
* System-Related Improvements:
|
||||
----------------------------
|
||||
* Adding an API for developing Magic tools as plug-ins.
|
||||
(e.g., '.so' shared objects under Linux)
|
||||
* Added an API for developing Magic tools as plug-ins.
|
||||
('.so' shared objects under Linux, '.dll' libraries under Windows, etc.)
|
||||
Plugins must provide a number of functions that Tux Paint calls,
|
||||
and Tux Paint provides a structure ("magic_api") that includes info.
|
||||
(e.g., the running Tux Paint's version number) and pointers to
|
||||
useful functions (e.g., getpixel(), putpixel(), etc.)
|
||||
|
||||
* Ported (most of) 'Negative' magic tool to Magic tool plug-in system.
|
||||
* Magic plugin development can be done outside of Tux Paint base
|
||||
source-code by using new "tp-magic-config" shell script to query
|
||||
for C compiler flags, which points to where "tp_magic_api.h" header
|
||||
file is installed.
|
||||
|
||||
* Magic plugin development docs created. On Linux/Unix, installed into
|
||||
/usr/[local/]share/docs/tuxpaint-dev/ by default.
|
||||
|
||||
* Ported existing magic tools to the new Magic tool plug-in system:
|
||||
- Negative
|
||||
- Mirror
|
||||
- Flip
|
||||
- Fade
|
||||
- Darken
|
||||
[[ FIXME: Do the rest ]]
|
||||
|
||||
* New Translations:
|
||||
-----------------
|
||||
|
|
|
|||
|
|
@ -1,35 +1,40 @@
|
|||
# Makefile for magic plugins
|
||||
|
||||
SDL_CFLAGS=$(shell sdl-config --cflags)
|
||||
CFLAGS=-g -Wall $(SDL_CFLAGS) -DDATA_PREFIX=\"$(DATA_PREFIX)\"
|
||||
#-fPIC ?
|
||||
# Places to pick up Tux Paint Magic Plugin Dev header and SDL headers
|
||||
# (can't assume plugin dev stuff has been installed yet, since we're
|
||||
# part of Tux Paint base, so "install-plugin-dev" probably hasn't
|
||||
# been run yet; hence "-I../src/" to find 'tp_magic_api.h')
|
||||
|
||||
all: negative.so
|
||||
SO_TYPE=so
|
||||
|
||||
TP_MAGIC_CFLAGS=$(shell sdl-config --cflags) \
|
||||
-I../src/ \
|
||||
$(shell tp-magic-config --cflags)
|
||||
CFLAGS=-g -Wall $(TP_MAGIC_CFLAGS)
|
||||
|
||||
|
||||
all: negative.$(SO_TYPE) \
|
||||
fade_darken.$(SO_TYPE) \
|
||||
mirror_flip.$(SO_TYPE) \
|
||||
|
||||
clean:
|
||||
@echo
|
||||
@echo "Cleaning up the Magic plug-ins directory ($(PWD))"
|
||||
@-rm -f *.so
|
||||
@-rm -f obj/*
|
||||
@-rm -f *.$(SO_TYPE)
|
||||
|
||||
|
||||
# Negative tool
|
||||
# ------------------------------------------------------------------------
|
||||
# Shared objects:
|
||||
# ---------------
|
||||
|
||||
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
|
||||
negative.$(SO_TYPE): src/negative.c
|
||||
@echo "Building Negative magic tool"
|
||||
@$(CC) $(CFLAGS) -shared -o negative.$(SO_TYPE) src/negative.c
|
||||
|
||||
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
|
||||
fade_darken.$(SO_TYPE): src/fade_darken.c
|
||||
@echo "Building Fade and Darken magic tools"
|
||||
@$(CC) $(CFLAGS) -shared -o fade_darken.$(SO_TYPE) src/fade_darken.c
|
||||
|
||||
|
||||
|
||||
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
|
||||
mirror_flip.$(SO_TYPE): src/mirror_flip.c
|
||||
@echo "Building Mirror and Flip magic tools"
|
||||
@$(CC) $(CFLAGS) -shared -o mirror_flip.$(SO_TYPE) src/mirror_flip.c
|
||||
|
||||
|
|
|
|||
131
magic/docs/README.txt
Normal file
131
magic/docs/README.txt
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
Stub docs for Tux Paint Magic Plugin Development
|
||||
|
||||
#include "tp_magic_api.h"
|
||||
|
||||
|
||||
build plugins with:
|
||||
-------------------
|
||||
Linux/Unix:
|
||||
-----------
|
||||
$(CC) -shared `tp-magic-config --cflags` plugin.c -o plugin.so
|
||||
|
||||
Then install globally into: /usr/[local/]lib/tuxpaint/.
|
||||
Or locally into: ~/.tuxpaint/magic/ [[FIXME]]
|
||||
|
||||
Windows:
|
||||
--------
|
||||
??? [[FIXME]]
|
||||
|
||||
Mac OS X:
|
||||
---------
|
||||
??? [[FIXME]]
|
||||
|
||||
|
||||
magic plugins must provide:
|
||||
---------------------------
|
||||
NOTE: Each function name should be preceded with the name of the
|
||||
shared object file, e.g. "negative.so" or "negative.dll" would have
|
||||
a function called "negative_init()".
|
||||
|
||||
int get_tool_count(magic_api * api)
|
||||
return the number of Magic tools this plugin provides
|
||||
(used below as the 'which' values sent to each function)
|
||||
|
||||
char * get_name(magic_api * api, int which)
|
||||
return the name of a/the magic tool (for 'Magic' tool buttons in UI)
|
||||
Tux Paint will free() the string;
|
||||
example:
|
||||
return (strdup(gettext("Fun")));
|
||||
|
||||
SDL_Surface * get_icon(magic_api * api, int which)
|
||||
return the icon of a/the magic tool (for 'Magic' tool buttons in UI)
|
||||
Tux Paint will SDL_FreeSurface() the surface:
|
||||
example:
|
||||
sprintf(fname, "%s/images/magic/funtool.png", api->data_directory);
|
||||
return(IMG_Load(fname));
|
||||
|
||||
char * get_description(magic_api * api, int which)
|
||||
return the description of a/the magic tool (for Tux help text in UI);
|
||||
Tux Paint will free() the string;
|
||||
example:
|
||||
return (strdup(gettext("A fun tool")));
|
||||
|
||||
int requires_colors(magic_api * api, int which)
|
||||
return whether a/the magic tool accepts colors
|
||||
('1' for true; activates color palette in UI;
|
||||
'0' for false; disables color palette in UI)
|
||||
|
||||
void set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 g)
|
||||
accept the color palette choice from Tux Paint
|
||||
(only called if requires_colors() for the current tool returned true)
|
||||
|
||||
int init(magic_api * api)
|
||||
initialization function; called once, during Tux Paint startup
|
||||
return 1 if success;
|
||||
return 0 if failure (tool(s) will be disabled in Magic tool);
|
||||
|
||||
void shutdown(magic_api * api)
|
||||
cleanup function; should free any alloc'd memory, etc.;
|
||||
happens once, at Tux Paint shutdown
|
||||
|
||||
void click(magic_api * api, int which,
|
||||
SDL_Surface * snapshot, SDL_Surface * canvas,
|
||||
int x, int y)
|
||||
should affect 'canvas' at (x,y) location; may use 'snapshot' to fetch
|
||||
pixels from most recent undo buffer;
|
||||
Tux Paint's undo buffer is updated prior to this call
|
||||
|
||||
void drag(magic_api * api, int which,
|
||||
SDL_Surface * snapshot, SDL_Surface * canvas,
|
||||
int ox, int oy, int x, int y)
|
||||
should affect 'canvas' between (ox,oy) and (x,y) locations;
|
||||
may use 'snapshot' to fetch pixels from most recent undo buffer;
|
||||
Tux Paint's undo buffer is NOT updated prior to this call; the
|
||||
'snapshot' buffer will contain the same contents as when click() was
|
||||
last called
|
||||
|
||||
|
||||
tp provides, via magic_api structure ("api" arg to magic tool functions):
|
||||
-------------------------------------------------------------------------
|
||||
void putpixel(SDL_Surface * surf, int x, int y, Uint32 pixel)
|
||||
function that puts a pixel at an (x,y) position in a surface
|
||||
|
||||
Uint32 getpixel(SDL_Surface * surf, int x, int y)
|
||||
function that returns a pixel value from an (x,y) position on a surface
|
||||
|
||||
int in_circle(int x, int y, int radius)
|
||||
function that returns whether an x/y position (centered at (0,0)) is
|
||||
within a circle of 'radius'
|
||||
|
||||
void show_progress_bar(void)
|
||||
draws the Tux Paint progress bar animation; use while you're busy
|
||||
|
||||
void tuxpaint_version(int * major, int * minor, int * revision)
|
||||
returns the version of Tux Paint being used
|
||||
|
||||
void line(int which, SDL_Surface * canvas, SDL_Surface * snapshot,
|
||||
int x1, int y1, int x2, int y2, int step, FUNC callback)
|
||||
function that calls calculates a line between (x1,y1) and (x2,y2)
|
||||
and calls 'callback' every 'step' iterations;
|
||||
sends to the callback: Tux Paint's 'magic_api' structure, along with the
|
||||
'which', 'canvas' and 'snapshot' values sent to line(), and the (x,y)
|
||||
coordinates
|
||||
|
||||
|
||||
FIXME: Implement these:
|
||||
|
||||
void playsound(Mix_Chunk * snd, int pan, int dist)
|
||||
function that plays a sound, panned left/right 'pan'
|
||||
and at distance 'dist'. pan may be SNDPOS_LEFT, SNDPOS_CENTER or
|
||||
SNDPOS_RIGHT, and dist may be SNDDIST_NEAR.
|
||||
|
||||
void special_notify(int flag)
|
||||
notifies tux paint of special events; SPECIAL_FLIP and SPECIAL_MIRROR
|
||||
flags may be sent
|
||||
|
||||
float sRGB_to_linear_table[256]
|
||||
sRGB-to-linear look-up table
|
||||
|
||||
unsigned char linear_to_sRGB(float linear)
|
||||
linear-to-sRGB look-up helper function
|
||||
|
||||
BIN
magic/sounds/flip.wav
Normal file
BIN
magic/sounds/flip.wav
Normal file
Binary file not shown.
BIN
magic/sounds/mirror.wav
Normal file
BIN
magic/sounds/mirror.wav
Normal file
Binary file not shown.
144
magic/src/fade_darken.c
Normal file
144
magic/src/fade_darken.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#include "tp_magic_api.h"
|
||||
#include "SDL_image.h"
|
||||
|
||||
enum {
|
||||
TOOL_FADE,
|
||||
TOOL_DARKEN,
|
||||
NUM_TOOLS
|
||||
};
|
||||
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
// No setup required:
|
||||
int fade_darken_init(magic_api * api)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
// Multiple tools:
|
||||
int fade_darken_get_tool_count(magic_api * api)
|
||||
{
|
||||
return(NUM_TOOLS);
|
||||
}
|
||||
|
||||
// Load our icon:
|
||||
SDL_Surface * fade_darken_get_icon(magic_api * api, int which)
|
||||
{
|
||||
char fname[1024];
|
||||
|
||||
if (which == TOOL_FADE)
|
||||
{
|
||||
snprintf(fname, sizeof(fname), "%s/images/magic/fade.png",
|
||||
api->data_directory);
|
||||
}
|
||||
else if (which == TOOL_DARKEN)
|
||||
{
|
||||
snprintf(fname, sizeof(fname), "%s/images/magic/darken.png",
|
||||
api->data_directory);
|
||||
}
|
||||
|
||||
return(IMG_Load(fname));
|
||||
}
|
||||
|
||||
// Return our name, localized:
|
||||
char * fade_darken_get_name(magic_api * api, int which)
|
||||
{
|
||||
if (which == TOOL_FADE)
|
||||
return(strdup(gettext("Lighten")));
|
||||
else if (which == TOOL_DARKEN)
|
||||
return(strdup(gettext("Darken")));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// Return our description, localized:
|
||||
char * fade_darken_get_description(magic_api * api, int which)
|
||||
{
|
||||
if (which == TOOL_FADE)
|
||||
return(strdup(
|
||||
gettext("Click and move to fade the colors.")));
|
||||
else if (which == TOOL_DARKEN)
|
||||
return(strdup(
|
||||
gettext("Click and move to darken the colors.")));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// Callback that does the fade_darken color effect on a circle centered around x,y
|
||||
void do_fade_darken(void * ptr, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x, int y)
|
||||
{
|
||||
int xx, yy;
|
||||
Uint8 r, g, b;
|
||||
magic_api * api = (magic_api *) ptr;
|
||||
|
||||
for (yy = y - 16; yy < y + 16; yy++)
|
||||
{
|
||||
for (xx = x - 16; xx < x + 16; xx++)
|
||||
{
|
||||
if (api->in_circle(xx - x, yy - y, 16))
|
||||
{
|
||||
SDL_GetRGB(api->getpixel(last, xx, yy), last->format, &r, &g, &b);
|
||||
|
||||
if (which == TOOL_FADE)
|
||||
{
|
||||
r = min(r + 48, 255);
|
||||
g = min(g + 48, 255);
|
||||
b = min(b + 48, 255);
|
||||
}
|
||||
else if (which == TOOL_DARKEN)
|
||||
{
|
||||
r = max(r - 48, 0);
|
||||
g = max(g - 48, 0);
|
||||
b = max(b - 48, 0);
|
||||
}
|
||||
|
||||
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ask Tux Paint to call our 'do_fade_darken()' callback over a line
|
||||
void fade_darken_drag(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * last, int ox, int oy, int x, int y)
|
||||
{
|
||||
SDL_LockSurface(last);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line(which, canvas, last, ox, oy, x, y, 1, do_fade_darken);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(last);
|
||||
}
|
||||
|
||||
// Ask Tux Paint to call our 'do_fade_darken()' callback at a single point
|
||||
void fade_darken_click(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x, int y)
|
||||
{
|
||||
fade_darken_drag(api, which, canvas, last, x, y, x, y);
|
||||
}
|
||||
|
||||
|
||||
// No setup happened:
|
||||
void fade_darken_shutdown(magic_api * api)
|
||||
{
|
||||
}
|
||||
|
||||
// We don't use colors
|
||||
void fade_darken_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
|
||||
{
|
||||
}
|
||||
|
||||
// We don't use colors
|
||||
int fade_darken_requires_colors(magic_api * api, int which)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
#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};
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef MAGIC_HELPERS_H
|
||||
#define MAGIC_HELPERS_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include <libintl.h>
|
||||
|
||||
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
|
||||
136
magic/src/mirror_flip.c
Normal file
136
magic/src/mirror_flip.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#include "tp_magic_api.h"
|
||||
#include "SDL_image.h"
|
||||
|
||||
/* What tools we contain: */
|
||||
|
||||
enum {
|
||||
TOOL_MIRROR,
|
||||
TOOL_FLIP,
|
||||
NUM_TOOLS
|
||||
};
|
||||
|
||||
// No setup required:
|
||||
int mirror_flip_init(magic_api * api)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
// We have multiple tools:
|
||||
int mirror_flip_get_tool_count(magic_api * api)
|
||||
{
|
||||
return(NUM_TOOLS);
|
||||
}
|
||||
|
||||
// Load our icons:
|
||||
SDL_Surface * mirror_flip_get_icon(magic_api * api, int which)
|
||||
{
|
||||
char fname[1024];
|
||||
|
||||
if (which == TOOL_MIRROR)
|
||||
{
|
||||
snprintf(fname, sizeof(fname), "%s/images/magic/mirror.png",
|
||||
api->data_directory);
|
||||
}
|
||||
else if (which == TOOL_FLIP)
|
||||
{
|
||||
snprintf(fname, sizeof(fname), "%s/images/magic/flip.png",
|
||||
api->data_directory);
|
||||
}
|
||||
|
||||
return(IMG_Load(fname));
|
||||
}
|
||||
|
||||
// Return our names, localized:
|
||||
char * mirror_flip_get_name(magic_api * api, int which)
|
||||
{
|
||||
if (which == TOOL_MIRROR)
|
||||
return(strdup(gettext("Mirror")));
|
||||
else if (which == TOOL_FLIP)
|
||||
return(strdup(gettext("Flip")));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// Return our descriptions, localized:
|
||||
char * mirror_flip_get_description(magic_api * api, int which)
|
||||
{
|
||||
if (which == TOOL_MIRROR)
|
||||
return(strdup(
|
||||
gettext("Click to flip the picture upside-down.")));
|
||||
else
|
||||
return(strdup(
|
||||
gettext("Click to make a mirror image.")));
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
// We affect the whole canvas, so only do things on click, not drag:
|
||||
void mirror_flip_drag(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * last, int ox, int oy, int x, int y)
|
||||
{
|
||||
// No-op
|
||||
}
|
||||
|
||||
// Affect the canvas on click:
|
||||
void mirror_flip_click(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x, int y)
|
||||
{
|
||||
int xx, yy;
|
||||
SDL_Rect src, dest;
|
||||
|
||||
if (which == TOOL_MIRROR)
|
||||
{
|
||||
for (xx = 0; xx < canvas->w; xx++)
|
||||
{
|
||||
src.x = xx;
|
||||
src.y = 0;
|
||||
src.w = 1;
|
||||
src.h = canvas->h;
|
||||
|
||||
dest.x = canvas->w - xx - 1;
|
||||
dest.y = 0;
|
||||
|
||||
SDL_BlitSurface(last, &src, canvas, &dest);
|
||||
}
|
||||
|
||||
api->special_notify(SPECIAL_MIRROR);
|
||||
}
|
||||
else if (which == TOOL_FLIP)
|
||||
{
|
||||
for (yy = 0; yy < canvas->h; yy++)
|
||||
{
|
||||
src.x = 0;
|
||||
src.y = yy;
|
||||
src.w = canvas->w;
|
||||
src.h = 1;
|
||||
|
||||
dest.x = 0;
|
||||
dest.y = canvas->h - yy - 1;
|
||||
|
||||
SDL_BlitSurface(last, &src, canvas, &dest);
|
||||
}
|
||||
|
||||
api->special_notify(SPECIAL_FLIP);
|
||||
}
|
||||
}
|
||||
|
||||
// No setup happened:
|
||||
void mirror_flip_shutdown(magic_api * api)
|
||||
{
|
||||
}
|
||||
|
||||
// We don't use colors:
|
||||
void mirror_flip_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
|
||||
{
|
||||
}
|
||||
|
||||
// We don't use colors:
|
||||
int mirror_flip_requires_colors(magic_api * api, int which)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,111 +1,106 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libintl.h>
|
||||
#include "tp_magic_api.h"
|
||||
#include "SDL_image.h"
|
||||
#include "magic_helpers.h"
|
||||
|
||||
void init()
|
||||
// No setup required:
|
||||
int negative_init(magic_api * api)
|
||||
{
|
||||
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)
|
||||
// Only one tool:
|
||||
int negative_get_tool_count(magic_api * api)
|
||||
{
|
||||
printf("Loading icon: " DATA_PREFIX "/images/magic/negative.png\n");
|
||||
return(IMG_Load(DATA_PREFIX "/images/magic/negative.png"));
|
||||
return(1);
|
||||
}
|
||||
|
||||
char * get_name(int which)
|
||||
// Load our icon:
|
||||
SDL_Surface * negative_get_icon(magic_api * api, int which)
|
||||
{
|
||||
/* Only 1 tool; ignoring 'which' */
|
||||
char fname[1024];
|
||||
|
||||
snprintf(fname, sizeof(fname), "%s/images/magic/negative.png",
|
||||
api->data_directory);
|
||||
return(IMG_Load(fname));
|
||||
}
|
||||
|
||||
// Return our name, localized:
|
||||
char * negative_get_name(magic_api * api, int which)
|
||||
{
|
||||
return(strdup(gettext("Negative")));
|
||||
}
|
||||
|
||||
char * get_description(int which)
|
||||
// Return our description, localized:
|
||||
char * negative_get_description(magic_api * api, int which)
|
||||
{
|
||||
/* Only 1 tool; ignoring 'which' */
|
||||
|
||||
return(strdup(gettext("Click and move the mouse around to draw a negative.")));
|
||||
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)
|
||||
// Callback that does the negative color effect on a circle centered around x,y
|
||||
void do_negative(void * ptr, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * last,
|
||||
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);
|
||||
magic_api * api = (magic_api *) ptr;
|
||||
|
||||
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))
|
||||
if (api->in_circle(xx - x, yy - y, 16))
|
||||
{
|
||||
SDL_GetRGB(getpixel_last(last, xx, yy), last->format, &r, &g, &b);
|
||||
SDL_GetRGB(api->getpixel(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));
|
||||
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ask Tux Paint to call our 'do_negative()' callback over a line
|
||||
void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
|
||||
SDL_Surface * last, int ox, int oy, int x, int y)
|
||||
{
|
||||
SDL_LockSurface(last);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
api->line(which, canvas, last, ox, oy, x, y, 1, do_negative);
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(last);
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
// Ask Tux Paint to call our 'do_negative()' callback at a single point
|
||||
void negative_click(magic_api * api, int which,
|
||||
SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x, int y)
|
||||
{
|
||||
printf("negative plugin shutting down\n");
|
||||
negative_drag(api, which, canvas, last, x, y, x, y);
|
||||
}
|
||||
|
||||
void set_color(Uint8 r, Uint8 g, Uint8 b)
|
||||
|
||||
// No setup happened:
|
||||
void negative_shutdown(magic_api * api)
|
||||
{
|
||||
/* Doesn't use color; ignoring */
|
||||
}
|
||||
|
||||
int requires_colors(int which)
|
||||
// We don't use colors
|
||||
void negative_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
|
||||
{
|
||||
/* (Only 1 tool; ignoring 'which') */
|
||||
|
||||
return 0; // Don't need a color palette
|
||||
}
|
||||
|
||||
// We don't use colors
|
||||
int negative_requires_colors(magic_api * api, int which)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
49
src/magic.h
49
src/magic.h
|
|
@ -44,21 +44,14 @@ enum
|
|||
MAGIC_BLUR,
|
||||
MAGIC_SMUDGE,
|
||||
|
||||
MAGIC_FADE,
|
||||
MAGIC_DARKEN,
|
||||
|
||||
MAGIC_CHALK,
|
||||
MAGIC_BLOCKS,
|
||||
|
||||
MAGIC_NEGATIVE,
|
||||
MAGIC_TINT,
|
||||
|
||||
MAGIC_DRIP,
|
||||
MAGIC_CARTOON,
|
||||
|
||||
MAGIC_MIRROR,
|
||||
MAGIC_FLIP,
|
||||
|
||||
NUM_MAGICS
|
||||
};
|
||||
|
||||
|
|
@ -72,26 +65,19 @@ const int magic_colors[] = {
|
|||
COLORSEL_ENABLE, // large bricks
|
||||
COLORSEL_ENABLE, // small bricks
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE, // rainbow
|
||||
COLORSEL_ENABLE, // sparkles
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE, // blur
|
||||
COLORSEL_DISABLE, // smudge
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE, // chalk
|
||||
COLORSEL_DISABLE, // blocks
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE,
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_ENABLE, // tint
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE,
|
||||
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE,
|
||||
COLORSEL_DISABLE, // drip
|
||||
COLORSEL_DISABLE, // cartoon
|
||||
};
|
||||
|
||||
/* Magic tool names: */
|
||||
|
|
@ -109,20 +95,13 @@ const char *const magic_names[NUM_MAGICS] = {
|
|||
gettext_noop("Blur"),
|
||||
gettext_noop("Smudge"),
|
||||
|
||||
gettext_noop("Lighten"),
|
||||
gettext_noop("Darken"),
|
||||
|
||||
gettext_noop("Chalk"),
|
||||
gettext_noop("Blocks"),
|
||||
|
||||
gettext_noop("Negative"),
|
||||
gettext_noop("Tint"),
|
||||
|
||||
gettext_noop("Drip"),
|
||||
gettext_noop("Cartoon"),
|
||||
|
||||
gettext_noop("Mirror"),
|
||||
gettext_noop("Flip"),
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -141,23 +120,16 @@ const char *const magic_tips[NUM_MAGICS] = {
|
|||
gettext_noop("Click and move the mouse around to blur the picture."),
|
||||
gettext_noop("Click and move the mouse around to smudge the picture."),
|
||||
|
||||
gettext_noop("Click and move to fade the colors."),
|
||||
gettext_noop("Click and move to darken the colors."),
|
||||
|
||||
gettext_noop
|
||||
("Click and move the mouse around to turn the picture into a chalk drawing."),
|
||||
gettext_noop("Click and move the mouse around to make the picture blocky."),
|
||||
|
||||
gettext_noop("Click and move the mouse around to draw a negative."),
|
||||
gettext_noop
|
||||
("Click and move the mouse around to change the picture’s color."),
|
||||
|
||||
gettext_noop("Click and move the mouse around to make the picture drip."),
|
||||
gettext_noop
|
||||
("Click and move the mouse around to turn the picture into a cartoon."),
|
||||
|
||||
gettext_noop("Click to make a mirror image."),
|
||||
gettext_noop("Click to flip the picture upside-down."),
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -176,20 +148,13 @@ const char *const magic_img_fnames[NUM_MAGICS] = {
|
|||
DATA_PREFIX "images/magic/blur.png",
|
||||
DATA_PREFIX "images/magic/smudge.png",
|
||||
|
||||
DATA_PREFIX "images/magic/fade.png",
|
||||
DATA_PREFIX "images/magic/darken.png",
|
||||
|
||||
DATA_PREFIX "images/magic/chalk.png",
|
||||
DATA_PREFIX "images/magic/blocks.png",
|
||||
|
||||
DATA_PREFIX "images/magic/negative.png",
|
||||
DATA_PREFIX "images/magic/tint.png",
|
||||
|
||||
DATA_PREFIX "images/magic/drip.png",
|
||||
DATA_PREFIX "images/magic/cartoon.png",
|
||||
|
||||
DATA_PREFIX "images/magic/mirror.png",
|
||||
DATA_PREFIX "images/magic/flip.png",
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
51
src/tp-magic-config.sh
Executable file
51
src/tp-magic-config.sh
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#!/bin/sh
|
||||
|
||||
# tp-magic-config
|
||||
|
||||
# "Tux Paint Magic Config"
|
||||
# Tool that reports compiler options used when buidling Magic Tool
|
||||
# shared objects for Tux Paint
|
||||
|
||||
# (c) Copyright 2007, by Bill Kendrick
|
||||
# bill@newbreedsoftware.com
|
||||
# http://www.tuxpaint.org/
|
||||
|
||||
# This program 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# (See COPYING.txt)
|
||||
|
||||
# Note: "__VERSION__" and "__INCLUDE__" are replaced by values
|
||||
# in Tux Paint's Makefile, via 'sed', by the 'make install-magic-plugin-dev'
|
||||
# target.
|
||||
|
||||
# July 5, 2007 - July 5, 2007
|
||||
|
||||
|
||||
if [ $# -ne 0 ]; then
|
||||
if [ $1 = "--version" ]; then
|
||||
echo "__VERSION__"
|
||||
exit
|
||||
fi
|
||||
if [ $1 = "--cflags" ]; then
|
||||
echo `sdl-config --cflags` -I__INCLUDE__
|
||||
exit
|
||||
fi
|
||||
if [ $1 = "--libs" ]; then
|
||||
echo `sdl-config --libs`
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Usage: tp-magic-config [--version] [--cflags] [--libs]"
|
||||
|
||||
653
src/tuxpaint.c
653
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 - July 3, 2007
|
||||
June 14, 2002 - July 5, 2007
|
||||
$Id$
|
||||
*/
|
||||
|
||||
|
|
@ -845,26 +845,41 @@ static int recording, playing;
|
|||
static char *playfile;
|
||||
static FILE *demofi;
|
||||
|
||||
|
||||
/* Magic tools API and tool handles: */
|
||||
|
||||
#include "tp_magic_api.h"
|
||||
|
||||
void update_progress_bar(void);
|
||||
void special_notify(int flags);
|
||||
|
||||
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);
|
||||
int (*get_tool_count)(magic_api *);
|
||||
char * (*get_name)(magic_api *, int);
|
||||
SDL_Surface * (*get_icon)(magic_api *, int);
|
||||
char * (*get_description)(magic_api *, int);
|
||||
int (*requires_colors)(magic_api *, int);
|
||||
void (*set_color)(magic_api *, Uint8, Uint8, Uint8);
|
||||
int (*init)(magic_api *);
|
||||
void (*shutdown)(magic_api *);
|
||||
void (*click)(magic_api *, int, SDL_Surface *, SDL_Surface *, int, int);
|
||||
void (*drag)(magic_api *, 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];
|
||||
// FIXME: Drop the 512 constant :P
|
||||
|
||||
static int num_plugin_files; // How many shared object files we went through
|
||||
void * magic_handle[512]; // Handle to shared object (to be unloaded later) // FIXME: Unload them!
|
||||
magic_funcs_t magic_funcs[512]; // Pointer to shared objects' functions
|
||||
static int num_magics; // How many magic tools were loaded (note: shared objs may report more than 1 tool)
|
||||
int magic_idx[512]; // Index to magic tools within shared objects (shared objs may report more than 1 tool)
|
||||
int magic_handle_idx[512]; // Index to magic funcs for each magic tool (shared objs may report more than 1 tool)
|
||||
static int magic_colors[512]; // Whether magic tool accepts colors
|
||||
static char * magic_names[512]; // Name of magic tool
|
||||
static char * magic_tips[512]; // Description of magic tool
|
||||
|
||||
magic_api * magic_api_struct; // Pointer to our internal functions; passed to shared object's functions when we call them
|
||||
|
||||
|
||||
#if !defined(WIN32) && !defined(__APPLE__) && !defined(__BEOS__)
|
||||
static const char *printcommand = PRINTCOMMAND;
|
||||
|
|
@ -889,6 +904,7 @@ static SDL_Surface *img_title, *img_title_credits, *img_title_tuxpaint;
|
|||
static SDL_Surface *img_btn_up, *img_btn_down, *img_btn_off;
|
||||
static SDL_Surface *img_btnsm_up, *img_btnsm_off;
|
||||
static SDL_Surface *img_prev, *img_next;
|
||||
static SDL_Surface *img_mirror, *img_flip;
|
||||
static SDL_Surface *img_dead40x40;
|
||||
static SDL_Surface *img_black, *img_grey;
|
||||
static SDL_Surface *img_yes, *img_no;
|
||||
|
|
@ -1166,8 +1182,6 @@ typedef struct dirent2
|
|||
static void mainloop(void);
|
||||
static void brush_draw(int x1, int y1, int x2, int y2, int update);
|
||||
static void blit_brush(int x, int y, int direction);
|
||||
static void magic_draw(int x1, int y1, int x2, int y2, int button_down);
|
||||
static void blit_magic(int x, int y, int button_down);
|
||||
static void stamp_draw(int x, int y);
|
||||
static void rec_undo_buffer(void);
|
||||
static void show_usage(FILE * f, char *prg);
|
||||
|
|
@ -1318,9 +1332,15 @@ static void mirror_starter(void);
|
|||
static void flip_starter(void);
|
||||
int valid_click(Uint8 button);
|
||||
int in_circle(int x, int y);
|
||||
int in_circle_rad(int x, int y, int rad);
|
||||
int paintsound(int size);
|
||||
void load_magic_plugins(void);
|
||||
|
||||
void magic_line_func(int which, SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x1, int y1, int x2, int y2, int step,
|
||||
void (*cb)(void *, int, SDL_Surface *, SDL_Surface *,
|
||||
int, int));
|
||||
|
||||
#ifdef DEBUG
|
||||
static char *debug_gettext(const char *str);
|
||||
static int charsize(Uint16 c);
|
||||
|
|
@ -2956,32 +2976,38 @@ static void mainloop(void)
|
|||
}
|
||||
else if (cur_tool == TOOL_MAGIC)
|
||||
{
|
||||
int undo_ctr;
|
||||
SDL_Surface * last;
|
||||
|
||||
|
||||
/* Start doing magic! */
|
||||
|
||||
tmp_int = cur_undo;
|
||||
rec_undo_buffer();
|
||||
|
||||
if (cur_undo > 0)
|
||||
undo_ctr = cur_undo - 1;
|
||||
else
|
||||
undo_ctr = NUM_UNDO_BUFS - 1;
|
||||
|
||||
last = undo_bufs[undo_ctr];
|
||||
|
||||
magic_funcs[magic_handle_idx[cur_magic]].click(magic_api_struct,
|
||||
magic_idx[cur_magic],
|
||||
canvas, last,
|
||||
old_x, old_y);
|
||||
|
||||
// FIXME: Maybe 'click' should return an update rect?
|
||||
update_canvas(0, 0, canvas->w, canvas->h);
|
||||
|
||||
/* 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
|
||||
{
|
||||
|
|
@ -2997,14 +3023,6 @@ 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)
|
||||
{
|
||||
|
|
@ -3530,15 +3548,26 @@ static void mainloop(void)
|
|||
}
|
||||
else if (cur_tool == TOOL_MAGIC)
|
||||
{
|
||||
/* Pushing button and moving: Do the magic: */
|
||||
int undo_ctr;
|
||||
SDL_Surface * last;
|
||||
|
||||
#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);
|
||||
}
|
||||
/* Pushing button and moving: Continue doing the magic: */
|
||||
|
||||
if (cur_undo > 0)
|
||||
undo_ctr = cur_undo - 1;
|
||||
else
|
||||
undo_ctr = NUM_UNDO_BUFS - 1;
|
||||
|
||||
last = undo_bufs[undo_ctr];
|
||||
|
||||
magic_funcs[magic_handle_idx[cur_magic]].drag(magic_api_struct,
|
||||
magic_idx[cur_magic],
|
||||
canvas, last,
|
||||
old_x, old_y,
|
||||
new_x, new_y);
|
||||
|
||||
// FIXME: Maybe 'drag' should return an update rect?
|
||||
update_canvas(0, 0, canvas->w, canvas->h);
|
||||
}
|
||||
else if (cur_tool == TOOL_ERASER)
|
||||
{
|
||||
|
|
@ -4397,86 +4426,6 @@ static void stamp_draw(int x, int y)
|
|||
|
||||
/* Draw using the current brush: */
|
||||
|
||||
static void magic_draw(int x1, int y1, int x2, int y2, int button_down)
|
||||
{
|
||||
int dx, dy, y;
|
||||
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;
|
||||
|
||||
orig_x2 = x2;
|
||||
orig_y2 = y2;
|
||||
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
if (dx != 0)
|
||||
{
|
||||
m = ((float) dy) / ((float) dx);
|
||||
b = y1 - m * x1;
|
||||
|
||||
if (x2 >= x1)
|
||||
dx = 1;
|
||||
else
|
||||
dx = -1;
|
||||
|
||||
|
||||
while (x1 != x2)
|
||||
{
|
||||
y1 = m * x1 + b;
|
||||
y2 = m * (x1 + dx) + b;
|
||||
|
||||
if (y1 > y2)
|
||||
{
|
||||
for (y = y1; y >= y2; y--)
|
||||
blit_magic(x1, y, button_down);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y <= y2; y++)
|
||||
blit_magic(x1, y, button_down);
|
||||
}
|
||||
|
||||
x1 = x1 + dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y1 > y2)
|
||||
{
|
||||
for (y = y1; y >= y2; y--)
|
||||
blit_magic(x1, y, button_down);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y <= y2; y++)
|
||||
blit_magic(x1, y, button_down);
|
||||
}
|
||||
}
|
||||
|
||||
if (orig_x1 > orig_x2)
|
||||
{
|
||||
tmp = orig_x1;
|
||||
orig_x1 = orig_x2;
|
||||
orig_x2 = tmp;
|
||||
}
|
||||
|
||||
if (orig_y1 > orig_y2)
|
||||
{
|
||||
tmp = orig_y1;
|
||||
orig_y1 = orig_y2;
|
||||
orig_y2 = tmp;
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* MAGIC_ME */
|
||||
|
||||
/* Play sound: */
|
||||
|
|
@ -4512,12 +4461,11 @@ 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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// this one rounds down
|
||||
|
|
@ -4580,40 +4528,12 @@ static void do_brick(int x, int y, int w, int h)
|
|||
|
||||
/* Draw the current brush in the current color: */
|
||||
|
||||
#if 0 // MAGIC_ME
|
||||
|
||||
static void blit_magic(int x, int y, int button_down)
|
||||
{
|
||||
int xx, yy, w, h;
|
||||
Uint32 colr;
|
||||
Uint8 r, g, b, a;
|
||||
SDL_Surface *last;
|
||||
SDL_Rect src, dest;
|
||||
int undo_ctr;
|
||||
Uint32(*getpixel_canvas) (SDL_Surface *, int, int) =
|
||||
getpixels[canvas->format->BytesPerPixel];
|
||||
void (*putpixel) (SDL_Surface *, int, int, Uint32) =
|
||||
putpixels[canvas->format->BytesPerPixel];
|
||||
Uint32(*getpixel_last) (SDL_Surface *, int, int);
|
||||
|
||||
|
||||
/* In case we need to use the current canvas (just saved to undo buf)... */
|
||||
|
||||
if (cur_undo > 0)
|
||||
undo_ctr = cur_undo - 1;
|
||||
else
|
||||
undo_ctr = NUM_UNDO_BUFS - 1;
|
||||
|
||||
last = undo_bufs[undo_ctr];
|
||||
getpixel_last = getpixels[last->format->BytesPerPixel];
|
||||
|
||||
|
||||
brush_counter++;
|
||||
|
||||
if (brush_counter >= 4) /* FIXME: Arbitrary? */
|
||||
{
|
||||
brush_counter = 0;
|
||||
|
||||
magic_funcs[cur_magic].click(0 /* MAGIC_ME */, canvas, last, x, y);
|
||||
|
||||
// PORT THESE TO MAGIC PLUGIN API:
|
||||
|
||||
#if 0 // MAGIC_ME
|
||||
if (cur_magic == MAGIC_BLUR)
|
||||
|
|
@ -4761,25 +4681,6 @@ static void blit_magic(int x, int y, int button_down)
|
|||
static int y_count;
|
||||
unsigned char *mybrick;
|
||||
|
||||
#if 0
|
||||
if (cur_magic == MAGIC_SMALLBRICK)
|
||||
{
|
||||
vertical_joint = 1; // between a brick and the one above/below
|
||||
horizontal_joint = 1; // between a brick and the one to the side
|
||||
nominal_width = 9;
|
||||
nominal_height = 6; // 11 to 14, for joints of 2
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
if (cur_magic == MAGIC_LARGEBRICK)
|
||||
{
|
||||
vertical_joint = 3; // between a brick and the one above/below
|
||||
horizontal_joint = 3; // between a brick and the one to the side
|
||||
nominal_width = 27;
|
||||
nominal_height = 18; // 11 to 14, for joints of 2
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (cur_magic == MAGIC_LARGEBRICK)
|
||||
{
|
||||
vertical_joint = 4; // between a brick and the one above/below
|
||||
|
|
@ -4787,7 +4688,6 @@ static void blit_magic(int x, int y, int button_down)
|
|||
nominal_width = 36;
|
||||
nominal_height = 24; // 11 to 14, for joints of 2
|
||||
}
|
||||
#endif
|
||||
|
||||
nominal_length = 2 * nominal_width;
|
||||
specified_width = nominal_width - horizontal_joint;
|
||||
|
|
@ -4869,67 +4769,6 @@ static void blit_magic(int x, int y, int button_down)
|
|||
}
|
||||
SDL_UnlockSurface(canvas);
|
||||
}
|
||||
else if (cur_magic == MAGIC_NEGATIVE)
|
||||
{
|
||||
SDL_LockSurface(last);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
for (yy = y - 16; yy < y + 16; yy++)
|
||||
{
|
||||
for (xx = x - 16; xx < x + 16; xx++)
|
||||
{
|
||||
if (in_circle(xx - x, yy - y))
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (cur_magic == MAGIC_FADE || cur_magic == MAGIC_DARKEN)
|
||||
{
|
||||
SDL_LockSurface(last);
|
||||
SDL_LockSurface(canvas);
|
||||
|
||||
for (yy = y - 16; yy < y + 16; yy++)
|
||||
{
|
||||
for (xx = x - 16; xx < x + 16; xx++)
|
||||
{
|
||||
if (in_circle(xx - x, yy - y))
|
||||
{
|
||||
/* Get original color: */
|
||||
|
||||
SDL_GetRGB(getpixel_last(last, xx, yy), last->format, &r, &g, &b);
|
||||
|
||||
if (cur_magic == MAGIC_FADE)
|
||||
{
|
||||
r = min(r + 48, 255);
|
||||
g = min(g + 48, 255);
|
||||
b = min(b + 48, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = max(r - 48, 0);
|
||||
g = max(g - 48, 0);
|
||||
b = max(b - 48, 0);
|
||||
}
|
||||
|
||||
putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(canvas);
|
||||
SDL_UnlockSurface(last);
|
||||
}
|
||||
else if (cur_magic == MAGIC_TINT)
|
||||
{
|
||||
double rd = sRGB_to_linear_table[color_hexes[cur_color][0]];
|
||||
|
|
@ -5256,56 +5095,6 @@ static void blit_magic(int x, int y, int button_down)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
else if (cur_magic == MAGIC_FLIP)
|
||||
{
|
||||
/* Flip the canvas: */
|
||||
|
||||
for (yy = 0; yy < canvas->h; yy++)
|
||||
{
|
||||
src.x = 0;
|
||||
src.y = yy;
|
||||
src.w = canvas->w;
|
||||
src.h = 1;
|
||||
|
||||
dest.x = 0;
|
||||
dest.y = canvas->h - yy - 1;
|
||||
|
||||
SDL_BlitSurface(last, &src, canvas, &dest);
|
||||
}
|
||||
|
||||
|
||||
/* Flip starter, too! */
|
||||
|
||||
starter_flipped = !starter_flipped;
|
||||
|
||||
if (img_starter != NULL)
|
||||
flip_starter();
|
||||
}
|
||||
else if (cur_magic == MAGIC_MIRROR)
|
||||
{
|
||||
/* Mirror-image the canvas: */
|
||||
|
||||
for (xx = 0; xx < canvas->w; xx++)
|
||||
{
|
||||
src.x = xx;
|
||||
src.y = 0;
|
||||
src.w = 1;
|
||||
src.h = canvas->h;
|
||||
|
||||
dest.x = canvas->w - xx - 1;
|
||||
dest.y = 0;
|
||||
|
||||
SDL_BlitSurface(last, &src, canvas, &dest);
|
||||
}
|
||||
|
||||
|
||||
/* Mirror starter, too! */
|
||||
|
||||
starter_mirrored = !starter_mirrored;
|
||||
|
||||
if (img_starter != NULL)
|
||||
mirror_starter();
|
||||
}
|
||||
else if (cur_magic == MAGIC_THIN || cur_magic == MAGIC_THICK)
|
||||
{
|
||||
SDL_LockSurface(last);
|
||||
|
|
@ -5362,6 +5151,8 @@ static void blit_magic(int x, int y, int button_down)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Store canvas into undo buffer: */
|
||||
|
||||
|
|
@ -7567,6 +7358,9 @@ static void setup(int argc, char *argv[])
|
|||
img_prev = loadimage(DATA_PREFIX "images/ui/prev.png");
|
||||
img_next = loadimage(DATA_PREFIX "images/ui/next.png");
|
||||
|
||||
img_mirror = loadimage(DATA_PREFIX "images/ui/mirror.png");
|
||||
img_flip = loadimage(DATA_PREFIX "images/ui/flip.png");
|
||||
|
||||
img_open = loadimage(DATA_PREFIX "images/ui/open.png");
|
||||
img_erase = loadimage(DATA_PREFIX "images/ui/erase.png");
|
||||
img_back = loadimage(DATA_PREFIX "images/ui/back.png");
|
||||
|
|
@ -8193,12 +7987,6 @@ 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);
|
||||
#endif
|
||||
|
||||
|
||||
draw_image_title(TITLE_MAGIC, r_ttoolopt);
|
||||
|
||||
|
|
@ -8825,7 +8613,6 @@ static void draw_stamps(void)
|
|||
|
||||
if (!disable_stamp_controls)
|
||||
{
|
||||
#if 0 // MAGIC_ME
|
||||
/* Show mirror button: */
|
||||
|
||||
dest.x = WINDOW_WIDTH - 96;
|
||||
|
|
@ -8851,12 +8638,12 @@ static void draw_stamps(void)
|
|||
}
|
||||
SDL_BlitSurface(button_body, NULL, screen, &dest);
|
||||
|
||||
dest.x = WINDOW_WIDTH - 96 + (48 - img_magics[MAGIC_MIRROR]->w) / 2;
|
||||
dest.x = WINDOW_WIDTH - 96 + (48 - img_mirror->w) / 2;
|
||||
dest.y = (40 + ((5 + TOOLOFFSET / 2) * 48) +
|
||||
(48 - img_magics[MAGIC_MIRROR]->h) / 2);
|
||||
(48 - img_mirror->h) / 2);
|
||||
|
||||
SDL_BlitSurface(button_color, NULL, img_magics[MAGIC_MIRROR], NULL);
|
||||
SDL_BlitSurface(img_magics[MAGIC_MIRROR], NULL, screen, &dest);
|
||||
SDL_BlitSurface(button_color, NULL, img_mirror, NULL);
|
||||
SDL_BlitSurface(img_mirror, NULL, screen, &dest);
|
||||
|
||||
/* Show flip button: */
|
||||
|
||||
|
|
@ -8883,14 +8670,12 @@ static void draw_stamps(void)
|
|||
}
|
||||
SDL_BlitSurface(button_body, NULL, screen, &dest);
|
||||
|
||||
dest.x = WINDOW_WIDTH - 48 + (48 - img_magics[MAGIC_FLIP]->w) / 2;
|
||||
dest.x = WINDOW_WIDTH - 48 + (48 - img_flip->w) / 2;
|
||||
dest.y = (40 + ((5 + TOOLOFFSET / 2) * 48) +
|
||||
(48 - img_magics[MAGIC_FLIP]->h) / 2);
|
||||
(48 - img_flip->h) / 2);
|
||||
|
||||
SDL_BlitSurface(button_color, NULL, img_magics[MAGIC_FLIP], NULL);
|
||||
SDL_BlitSurface(img_magics[MAGIC_FLIP], NULL, screen, &dest);
|
||||
|
||||
#endif
|
||||
SDL_BlitSurface(button_color, NULL, img_flip, NULL);
|
||||
SDL_BlitSurface(img_flip, NULL, screen, &dest);
|
||||
|
||||
|
||||
#ifdef OLD_STAMP_GROW_SHRINK
|
||||
|
|
@ -11755,6 +11540,9 @@ static void cleanup(void)
|
|||
free_surface(&img_prev);
|
||||
free_surface(&img_next);
|
||||
|
||||
free_surface(&img_mirror);
|
||||
free_surface(&img_flip);
|
||||
|
||||
free_surface(&img_title_on);
|
||||
free_surface(&img_title_off);
|
||||
free_surface(&img_title_large_on);
|
||||
|
|
@ -16330,6 +16118,14 @@ int in_circle(int x, int y)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int in_circle_rad(int x, int y, int rad)
|
||||
{
|
||||
if ((x * x) + (y * y) - (rad * rad) < 0)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
int paintsound(int size)
|
||||
{
|
||||
if (SND_PAINT1 + (size / 12) >= SND_PAINT4)
|
||||
|
|
@ -16787,13 +16583,33 @@ void load_magic_plugins(void)
|
|||
DIR *d;
|
||||
struct dirent *f;
|
||||
char fname[512];
|
||||
char objname[512];
|
||||
char funcname[512];
|
||||
|
||||
num_plugin_files = 0;
|
||||
num_magics = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\n");
|
||||
printf("Loading magic plug-ins from %s\n", MAGIC_PREFIX);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
/* Set magic API hooks: */
|
||||
|
||||
magic_api_struct = (magic_api *) malloc(sizeof(magic_api));
|
||||
magic_api_struct->tp_version = strdup(VER_VERSION);
|
||||
magic_api_struct->data_directory = strdup(DATA_PREFIX);
|
||||
magic_api_struct->update_progress_bar = update_progress_bar;
|
||||
// FIXME: magic_api_struct->sRGB_to_linear_table = sRGB_to_linear_table;
|
||||
// FIXME: magic_api_struct->linear_to_sRGB = linear_to_sRGB;
|
||||
magic_api_struct->in_circle = in_circle_rad;
|
||||
magic_api_struct->getpixel = getpixels[canvas->format->BytesPerPixel];
|
||||
magic_api_struct->putpixel = putpixels[canvas->format->BytesPerPixel];
|
||||
magic_api_struct->line = magic_line_func;
|
||||
magic_api_struct->playsound = NULL; // FIXME
|
||||
magic_api_struct->special_notify = special_notify;
|
||||
|
||||
|
||||
d = opendir(MAGIC_PREFIX);
|
||||
|
||||
|
|
@ -16811,52 +16627,71 @@ void load_magic_plugins(void)
|
|||
{
|
||||
snprintf(fname, sizeof(fname), "%s%s", MAGIC_PREFIX, f->d_name);
|
||||
|
||||
/* Get just the name of the object (e.g., "negative"), w/o filename
|
||||
extension: */
|
||||
|
||||
strcpy(objname, f->d_name);
|
||||
strcpy(strchr(objname, '.'), "");
|
||||
|
||||
|
||||
magic_handle[num_plugin_files] = SDL_LoadObject(fname);
|
||||
|
||||
if (magic_handle[num_plugin_files] != NULL)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("loading: %s\n", fname);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
magic_funcs[num_plugin_files].get_tool_count =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"get_tool_count");
|
||||
magic_funcs[num_plugin_files].get_tool_count =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].get_name =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"get_name");
|
||||
magic_funcs[num_plugin_files].get_name =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].get_icon =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"get_icon");
|
||||
magic_funcs[num_plugin_files].get_icon =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].get_description =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"get_description");
|
||||
magic_funcs[num_plugin_files].get_description =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].requires_colors =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"requires_colors");
|
||||
magic_funcs[num_plugin_files].requires_colors =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].set_color =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"set_color");
|
||||
magic_funcs[num_plugin_files].set_color =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].init =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"init");
|
||||
magic_funcs[num_plugin_files].init =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].shutdown =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"shutdown");
|
||||
magic_funcs[num_plugin_files].shutdown =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].click =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"click");
|
||||
magic_funcs[num_plugin_files].click =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
magic_funcs[num_plugin_files].drag =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files],
|
||||
snprintf(funcname, sizeof(funcname), "%s_%s", objname,
|
||||
"drag");
|
||||
magic_funcs[num_plugin_files].drag =
|
||||
SDL_LoadFunction(magic_handle[num_plugin_files], funcname);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("get_tool_count = 0x%x\n",
|
||||
|
|
@ -16898,13 +16733,13 @@ void load_magic_plugins(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
res = magic_funcs[num_plugin_files].init();
|
||||
res = magic_funcs[num_plugin_files].init(magic_api_struct);
|
||||
|
||||
if (res != 0)
|
||||
n = magic_funcs[num_plugin_files].get_tool_count();
|
||||
n = magic_funcs[num_plugin_files].get_tool_count(magic_api_struct);
|
||||
else
|
||||
{
|
||||
magic_funcs[num_plugin_files].shutdown();
|
||||
magic_funcs[num_plugin_files].shutdown(magic_api_struct);
|
||||
n = 0;
|
||||
}
|
||||
|
||||
|
|
@ -16919,13 +16754,17 @@ void load_magic_plugins(void)
|
|||
{
|
||||
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);
|
||||
magic_idx[num_magics] = i;
|
||||
magic_handle_idx[num_magics] = num_plugin_files;
|
||||
magic_names[num_magics] = magic_funcs[num_plugin_files].get_name(magic_api_struct, i);
|
||||
magic_tips[num_magics] = magic_funcs[num_plugin_files].get_description(magic_api_struct, i);
|
||||
magic_colors[num_magics] = magic_funcs[num_plugin_files].requires_colors(magic_api_struct, i);
|
||||
|
||||
img_magics[num_magics] = magic_funcs[num_plugin_files].get_icon(i);
|
||||
img_magics[num_magics] = magic_funcs[num_plugin_files].get_icon(magic_api_struct, i);
|
||||
|
||||
printf("-- %s\n", magic_names[i]);
|
||||
#ifdef DEBUG
|
||||
printf("-- %s\n", magic_names[num_magics]);
|
||||
#endif
|
||||
|
||||
num_magics++;
|
||||
}
|
||||
|
|
@ -16947,11 +16786,151 @@ void load_magic_plugins(void)
|
|||
closedir(d);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Loaded %d magic tools from %d plug-in files\n", num_magics,
|
||||
num_plugin_files);
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
/* FIXME: Sort it? -bjk 2007.07.03 */
|
||||
}
|
||||
|
||||
void update_progress_bar(void)
|
||||
{
|
||||
show_progress_bar(screen);
|
||||
}
|
||||
|
||||
void magic_line_func(int which, SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x1, int y1, int x2, int y2, int step,
|
||||
void (*cb)(void *, int, SDL_Surface *, SDL_Surface *,
|
||||
int, int))
|
||||
{
|
||||
int dx, dy, y;
|
||||
int orig_x1, orig_y1, orig_x2, orig_y2, tmp;
|
||||
float m, b;
|
||||
int cnt;
|
||||
|
||||
orig_x1 = x1;
|
||||
orig_y1 = y1;
|
||||
|
||||
orig_x2 = x2;
|
||||
orig_y2 = y2;
|
||||
|
||||
|
||||
dx = x2 - x1;
|
||||
dy = y2 - y1;
|
||||
|
||||
cnt = step - 1;
|
||||
|
||||
if (dx != 0)
|
||||
{
|
||||
m = ((float) dy) / ((float) dx);
|
||||
b = y1 - m * x1;
|
||||
|
||||
if (x2 >= x1)
|
||||
dx = 1;
|
||||
else
|
||||
dx = -1;
|
||||
|
||||
|
||||
while (x1 != x2)
|
||||
{
|
||||
y1 = m * x1 + b;
|
||||
y2 = m * (x1 + dx) + b;
|
||||
|
||||
if (y1 > y2)
|
||||
{
|
||||
for (y = y1; y >= y2; y--)
|
||||
{
|
||||
cnt = (cnt + 1) % step;
|
||||
if (cnt == 0)
|
||||
cb((void *) magic_api_struct, which, canvas, last, x1, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y <= y2; y++)
|
||||
{
|
||||
cnt = (cnt + 1) % step;
|
||||
if (cnt == 0)
|
||||
cb((void *) magic_api_struct, which, canvas, last, x1, y);
|
||||
}
|
||||
}
|
||||
|
||||
x1 = x1 + dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y1 > y2)
|
||||
{
|
||||
for (y = y1; y >= y2; y--)
|
||||
{
|
||||
cnt = (cnt + 1) % step;
|
||||
if (cnt == 0)
|
||||
cb((void *) magic_api_struct, which, canvas, last, x1, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y <= y2; y++)
|
||||
{
|
||||
cnt = (cnt + 1) % step;
|
||||
if (cnt == 0)
|
||||
cb((void *) magic_api_struct, which, canvas, last, x1, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (orig_x1 > orig_x2)
|
||||
{
|
||||
tmp = orig_x1;
|
||||
orig_x1 = orig_x2;
|
||||
orig_x2 = tmp;
|
||||
}
|
||||
|
||||
if (orig_y1 > orig_y2)
|
||||
{
|
||||
tmp = orig_y1;
|
||||
orig_y1 = orig_y2;
|
||||
orig_y2 = tmp;
|
||||
}
|
||||
|
||||
/* FIXME: Set and return an update rect? */
|
||||
}
|
||||
|
||||
|
||||
/* Handle special things that some magic tools do that
|
||||
need to affect more than just the current canvas: */
|
||||
|
||||
void special_notify(int flags)
|
||||
{
|
||||
int tmp_int;
|
||||
|
||||
tmp_int = (cur_undo - 1) % NUM_UNDO_BUFS;
|
||||
|
||||
if (flags & SPECIAL_MIRROR)
|
||||
{
|
||||
/* Mirror starter, too! */
|
||||
|
||||
starter_mirrored = !starter_mirrored;
|
||||
|
||||
if (img_starter != NULL)
|
||||
mirror_starter();
|
||||
|
||||
undo_starters[tmp_int] = UNDO_STARTER_MIRRORED;
|
||||
}
|
||||
|
||||
if (flags & SPECIAL_FLIP)
|
||||
{
|
||||
/* Flip starter, too! */
|
||||
|
||||
starter_flipped = !starter_flipped;
|
||||
|
||||
if (img_starter != NULL)
|
||||
flip_starter();
|
||||
|
||||
undo_starters[tmp_int] = UNDO_STARTER_FLIPPED;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue