diff --git a/magic/Makefile b/magic/Makefile
index 17884a4f8..6f4473971 100644
--- a/magic/Makefile
+++ b/magic/Makefile
@@ -6,7 +6,7 @@
# bill@newbreedsoftware.com
# http://www.tuxpaint.org/
-# July 2007 - July 24, 2007
+# July 2007 - August 9, 2007
SO_TYPE=so
@@ -43,7 +43,9 @@ all: negative.$(SO_TYPE) \
flower.$(SO_TYPE) \
foam.$(SO_TYPE) \
ripples.$(SO_TYPE) \
- sparkles.$(SO_TYPE)
+ light.$(SO_TYPE) \
+ shift.$(SO_TYPE) \
+ calligraphy.$(SO_TYPE)
@strip *.$(SO_TYPE)
install:
@@ -99,7 +101,7 @@ smudge.$(SO_TYPE): src/smudge.c
@$(CC) $(CFLAGS) -shared -o $@ $<
cartoon.$(SO_TYPE): src/cartoon.c
- @echo "Building Smudge magic tool"
+ @echo "Building Cartoon magic tool"
@$(CC) $(CFLAGS) -shared -o $@ $<
bricks.$(SO_TYPE): src/bricks.c
@@ -138,7 +140,14 @@ ripples.$(SO_TYPE): src/ripples.c
@echo "Building Ripples magic tool"
@$(CC) $(CFLAGS) -shared -o $@ $<
-sparkles.$(SO_TYPE): src/sparkles.c
- @echo "Building Sparkles magic tool"
+light.$(SO_TYPE): src/light.c
+ @echo "Building Light magic tool"
@$(CC) $(CFLAGS) -shared -o $@ $<
+shift.$(SO_TYPE): src/shift.c
+ @echo "Building Shift magic tool"
+ @$(CC) $(CFLAGS) -shared -o $@ $<
+
+calligraphy.$(SO_TYPE): src/calligraphy.c
+ @echo "Building Calligraphy magic tool"
+ @$(CC) $(CFLAGS) -shared -o $@ $<
diff --git a/magic/icons/calligraphy.png b/magic/icons/calligraphy.png
new file mode 100644
index 000000000..ca90869e5
Binary files /dev/null and b/magic/icons/calligraphy.png differ
diff --git a/magic/icons/calligraphy_brush.png b/magic/icons/calligraphy_brush.png
new file mode 100644
index 000000000..4a30294e9
Binary files /dev/null and b/magic/icons/calligraphy_brush.png differ
diff --git a/magic/icons/light.png b/magic/icons/light.png
new file mode 100644
index 000000000..4b4f292fd
Binary files /dev/null and b/magic/icons/light.png differ
diff --git a/magic/icons/sparkles.png b/magic/icons/sparkles.png
deleted file mode 100644
index eac486810..000000000
Binary files a/magic/icons/sparkles.png and /dev/null differ
diff --git a/magic/magic-docs/Makefile b/magic/magic-docs/Makefile
index 6ea838ae0..1db4cfaf6 100644
--- a/magic/magic-docs/Makefile
+++ b/magic/magic-docs/Makefile
@@ -7,7 +7,7 @@
# Bill Kendrick
# bill@newbreedsoftware.com
#
-# August 2, 2007 - August 2, 2007
+# August 2, 2007 - August 9, 2007
# $Id$
LINKS=links -dump -no-numbering -no-references
@@ -16,6 +16,7 @@ TXT_FILES= \
blocks.txt \
blur.txt \
bricks.txt \
+ calligraphy.txt \
cartoon.txt \
chalk.txt \
darken.txt \
@@ -29,13 +30,14 @@ TXT_FILES= \
glasstile.txt \
grass.txt \
kalidescope.txt \
+ light.txt \
metalpaint.txt \
mirror.txt \
negative.txt \
rainbow.txt \
ripples.txt \
+ shift.txt \
smudge.txt \
- sparkles.txt \
tint.txt \
waves.txt
@@ -53,6 +55,9 @@ blur.txt: html/blur.html
bricks.txt: html/bricks.html
@$(LINKS) $< > $@
+calligraphy.txt: html/calligraphy.html
+ @$(LINKS) $< > $@
+
cartoon.txt: html/cartoon.html
@$(LINKS) $< > $@
@@ -110,7 +115,10 @@ ripples.txt: html/ripples.html
smudge.txt: html/smudge.html
@$(LINKS) $< > $@
-sparkles.txt: html/sparkles.html
+light.txt: html/light.html
+ @$(LINKS) $< > $@
+
+shift.txt: html/shift.html
@$(LINKS) $< > $@
tint.txt: html/tint.html
diff --git a/magic/magic-docs/calligraphy.txt b/magic/magic-docs/calligraphy.txt
new file mode 100644
index 000000000..ed2647958
--- /dev/null
+++ b/magic/magic-docs/calligraphy.txt
@@ -0,0 +1,3 @@
+ Tux Paint "Magic" Tool: Calligraphy
+
+ This paints on the canvas with a calligraphy pen.
diff --git a/magic/magic-docs/html/sparkles.html b/magic/magic-docs/html/calligraphy.html
similarity index 76%
rename from magic/magic-docs/html/sparkles.html
rename to magic/magic-docs/html/calligraphy.html
index bb23893aa..8e958e159 100644
--- a/magic/magic-docs/html/sparkles.html
+++ b/magic/magic-docs/html/calligraphy.html
@@ -1,7 +1,7 @@
Tux Paint "Magic" Tool:
-Sparkles
+Calligraphy
@@ -12,13 +12,12 @@ alink="#FF00FF">
Tux Paint "Magic" Tool:
-Sparkles
+Calligraphy
- This draws glowing sparkles on the canvas, in the currently-selected
- color.
+ This paints on the canvas with a calligraphy pen.
diff --git a/magic/magic-docs/html/light.html b/magic/magic-docs/html/light.html
new file mode 100644
index 000000000..3d4323924
--- /dev/null
+++ b/magic/magic-docs/html/light.html
@@ -0,0 +1,25 @@
+
+Tux Paint "Magic" Tool:
+
+Light
+
+
+
+
+
+
+
+Tux Paint "Magic" Tool:
+
+Light
+
+
+
+
+ This draws a glowing beam on the canvas, in the currently-selected
+ color. The more you use it on one spot, the more white it becomes.
+
+
+
+
diff --git a/magic/magic-docs/light.txt b/magic/magic-docs/light.txt
new file mode 100644
index 000000000..28f0b032c
--- /dev/null
+++ b/magic/magic-docs/light.txt
@@ -0,0 +1,4 @@
+ Tux Paint "Magic" Tool: Light
+
+ This draws a glowing beam on the canvas, in the currently-selected color.
+ The more you use it on one spot, the more white it becomes.
diff --git a/magic/magic-docs/sparkles.txt b/magic/magic-docs/sparkles.txt
deleted file mode 100644
index 014c74286..000000000
--- a/magic/magic-docs/sparkles.txt
+++ /dev/null
@@ -1,4 +0,0 @@
- Tux Paint "Magic" Tool: Sparkles
-
- This draws glowing sparkles on the canvas, in the currently-selected
- color.
diff --git a/magic/sounds/light1.ogg b/magic/sounds/light1.ogg
new file mode 100644
index 000000000..f6d592303
Binary files /dev/null and b/magic/sounds/light1.ogg differ
diff --git a/magic/sounds/light2.ogg b/magic/sounds/light2.ogg
new file mode 100644
index 000000000..debf88650
Binary files /dev/null and b/magic/sounds/light2.ogg differ
diff --git a/magic/sounds/sparkles1.wav b/magic/sounds/sparkles1.wav
deleted file mode 100644
index c4f36d644..000000000
Binary files a/magic/sounds/sparkles1.wav and /dev/null differ
diff --git a/magic/sounds/sparkles2.wav b/magic/sounds/sparkles2.wav
deleted file mode 100644
index ceb1b4b87..000000000
Binary files a/magic/sounds/sparkles2.wav and /dev/null differ
diff --git a/magic/src/calligraphy.c b/magic/src/calligraphy.c
new file mode 100644
index 000000000..2a5a462b7
--- /dev/null
+++ b/magic/src/calligraphy.c
@@ -0,0 +1,422 @@
+/*
+ calligraphy.c
+
+ Calligraphy Magic Tool Plugin
+ Tux Paint - A simple drawing program for children.
+
+ Copyright (c) 2002-2007 by Bill Kendrick and others; see AUTHORS.txt
+ 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)
+
+ Last updated: August 7, 2007
+ $Id$
+*/
+
+#include
+#include
+#include
+#include "tp_magic_api.h"
+#include "SDL_image.h"
+#include "SDL_mixer.h"
+
+#include
+
+typedef struct
+{
+ float x, y;
+} Point2D;
+
+Mix_Chunk * calligraphy_snd;
+Point2D calligraphy_control_points[4];
+int calligraphy_r, calligraphy_g, calligraphy_b;
+int calligraphy_old_thick;
+Uint32 calligraphy_last_time;
+SDL_Surface * calligraphy_brush, * calligraphy_colored_brush;
+
+
+Point2D calligraphy_PointOnCubicBezier(Point2D* cp, float t);
+void calligraphy_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve);
+float calligraphy_dist(float x1, float y1, float x2, float y2);
+
+
+
+// No setup required:
+int calligraphy_init(magic_api * api)
+{
+ char fname[1024];
+
+ snprintf(fname, sizeof(fname), "%s/sounds/magic/calligraphy.wav",
+ api->data_directory);
+
+ calligraphy_snd = Mix_LoadWAV(fname);
+
+ snprintf(fname, sizeof(fname), "%s/images/magic/calligraphy_brush.png",
+ api->data_directory);
+
+ calligraphy_brush = IMG_Load(fname);
+ calligraphy_colored_brush = NULL;
+
+ if (calligraphy_brush == NULL)
+ return(0);
+
+ calligraphy_last_time = 0;
+
+ /* (Force blit first time we get a color) */
+ calligraphy_r = -1;
+ calligraphy_g = -1;
+ calligraphy_b = -1;
+
+ return(1);
+}
+
+Uint32 calligraphy_api_version(void) { return(TP_MAGIC_API_VERSION); }
+
+// Only one tool:
+int calligraphy_get_tool_count(magic_api * api)
+{
+ return(1);
+}
+
+// Load our icon:
+SDL_Surface * calligraphy_get_icon(magic_api * api, int which)
+{
+ char fname[1024];
+
+ snprintf(fname, sizeof(fname), "%s/images/magic/calligraphy.png",
+ api->data_directory);
+ return(IMG_Load(fname));
+}
+
+// Return our name, localized:
+char * calligraphy_get_name(magic_api * api, int which)
+{
+ return(strdup(gettext("Calligraphy")));
+}
+
+// Return our description, localized:
+char * calligraphy_get_description(magic_api * api, int which)
+{
+ return(strdup(
+ gettext("Click and move the mouse around to draw in calligraphy.")));
+}
+
+
+void calligraphy_drag(magic_api * api, int which, SDL_Surface * canvas,
+ SDL_Surface * last, int ox, int oy, int x, int y,
+ SDL_Rect * update_rect)
+{
+ Point2D * curve;
+ int i, n_points, thick, new_thick;
+ Uint32 colr;
+ SDL_Rect src, dest;
+
+// if (SDL_GetTicks() < calligraphy_last_time + 5)
+// return;
+
+ calligraphy_control_points[0].x = calligraphy_control_points[1].x;
+ calligraphy_control_points[0].y = calligraphy_control_points[1].y;
+ calligraphy_control_points[1].x = calligraphy_control_points[2].x;
+ calligraphy_control_points[1].y = calligraphy_control_points[2].y;
+ calligraphy_control_points[2].x = calligraphy_control_points[3].x;
+ calligraphy_control_points[2].y = calligraphy_control_points[3].y;
+ calligraphy_control_points[3].x = x;
+ calligraphy_control_points[3].y = y;
+
+ calligraphy_last_time = SDL_GetTicks();
+
+
+/*
+ if ((calligraphy_control_points[0].x == calligraphy_control_points[1].x &&
+ calligraphy_control_points[0].y == calligraphy_control_points[1].y) ||
+ (calligraphy_control_points[1].x == calligraphy_control_points[2].x &&
+ calligraphy_control_points[1].y == calligraphy_control_points[2].y) ||
+ (calligraphy_control_points[2].x == calligraphy_control_points[3].x &&
+ calligraphy_control_points[2].y == calligraphy_control_points[3].y))
+ return; // No-op; not enough control points yet!
+*/
+
+ n_points = calligraphy_dist(calligraphy_control_points[0].x,
+ calligraphy_control_points[0].y,
+ calligraphy_control_points[1].x,
+ calligraphy_control_points[1].y) +
+ calligraphy_dist(calligraphy_control_points[1].x,
+ calligraphy_control_points[1].y,
+ calligraphy_control_points[2].x,
+ calligraphy_control_points[2].y) +
+ calligraphy_dist(calligraphy_control_points[2].x,
+ calligraphy_control_points[2].y,
+ calligraphy_control_points[3].x,
+ calligraphy_control_points[3].y);
+
+ if (n_points == 0)
+ return; // No-op; not any points to plot
+
+
+ curve = (Point2D *) malloc(sizeof(Point2D) * n_points);
+
+ calligraphy_ComputeBezier(calligraphy_control_points, n_points, curve);
+
+ colr = SDL_MapRGB(canvas->format,
+ calligraphy_r,
+ calligraphy_g,
+ calligraphy_b);
+
+ new_thick = 40 - min((n_points /* / 2 */), 32);
+
+ for (i = 0; i < n_points - 1; i++)
+ {
+ thick = ((new_thick * i) +
+ (calligraphy_old_thick * (n_points - i))) / n_points;
+
+
+ /* The new way, using an antialiased brush bitmap */
+
+ x = curve[i].x;
+ y = curve[i].y;
+
+ src.x = calligraphy_brush->w - thick / 2 - thick / 4;
+ src.w = thick / 2 + thick / 4;
+ src.y = 0;
+ src.h = thick / 4;
+
+ dest.x = x - thick / 4;
+ dest.y = y - thick / 4;
+
+ SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
+
+
+ src.x = 0;
+ src.w = thick / 2 + thick / 4;
+ src.y = calligraphy_brush->h - thick / 4;
+ src.h = thick / 4;
+
+ dest.x = x - thick / 2;
+ dest.y = y;
+
+ SDL_BlitSurface(calligraphy_colored_brush, &src, canvas, &dest);
+
+ /* Old way; using putpixel:
+ SDL_LockSurface(canvas);
+
+ for (j = -(thick / 2); j < (thick / 2) + 1; j++)
+ {
+ x = curve[i].x + j;
+ y = curve[i].y - (j / 2); // 30 degrees
+
+ api->putpixel(canvas, x, y, colr);
+ api->putpixel(canvas, x + 1, y, colr);
+ api->putpixel(canvas, x, y + 1, colr);
+ api->putpixel(canvas, x + 1, y + 1, colr);
+ }
+
+ SDL_UnlockSurface(canvas);
+ */
+ }
+
+ calligraphy_old_thick = (calligraphy_old_thick + new_thick) / 2;
+
+ free(curve);
+
+
+
+ if (ox > x) { int tmp = ox; ox = x; x = tmp; }
+ if (oy > y) { int tmp = oy; oy = y; y = tmp; }
+
+ update_rect->x = ox - 16;
+ update_rect->y = oy - 16;
+ update_rect->w = (x + 16) - update_rect->x;
+ update_rect->h = (y + 16) - update_rect->h;
+
+ /* FIXME */
+
+ update_rect->x = 0;
+ update_rect->y = 0;
+ update_rect->w = canvas->w;
+ update_rect->h = canvas->h;
+
+ api->playsound(calligraphy_snd, (x * 255) / canvas->w, 255);
+}
+
+void calligraphy_click(magic_api * api, int which,
+ SDL_Surface * canvas, SDL_Surface * last,
+ int x, int y, SDL_Rect * update_rect)
+{
+ calligraphy_old_thick = 8;
+ calligraphy_last_time = 0;
+
+ calligraphy_control_points[0].x = x;
+ calligraphy_control_points[0].y = y;
+ calligraphy_control_points[1].x = x;
+ calligraphy_control_points[1].y = y;
+ calligraphy_control_points[2].x = x;
+ calligraphy_control_points[2].y = y;
+ calligraphy_control_points[3].x = x;
+ calligraphy_control_points[3].y = y;
+}
+
+
+void calligraphy_release(magic_api * api, int which,
+ SDL_Surface * canvas, SDL_Surface * last,
+ int x, int y, SDL_Rect * update_rect)
+{
+}
+
+
+void calligraphy_shutdown(magic_api * api)
+{
+ if (calligraphy_snd != NULL)
+ Mix_FreeChunk(calligraphy_snd);
+ if (calligraphy_brush != NULL)
+ SDL_FreeSurface(calligraphy_brush);
+ if (calligraphy_colored_brush != NULL)
+ SDL_FreeSurface(calligraphy_colored_brush);
+}
+
+// We don't use colors
+void calligraphy_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
+{
+ int x, y;
+ Uint8 a;
+ Uint32 amask;
+
+ if (calligraphy_r == r &&
+ calligraphy_g == g &&
+ calligraphy_b == b)
+ return;
+
+ calligraphy_r = r;
+ calligraphy_g = g;
+ calligraphy_b = b;
+
+ if (calligraphy_colored_brush != NULL)
+ SDL_FreeSurface(calligraphy_colored_brush);
+
+ amask = ~(calligraphy_brush->format->Rmask |
+ calligraphy_brush->format->Gmask |
+ calligraphy_brush->format->Bmask);
+
+ calligraphy_colored_brush =
+ SDL_CreateRGBSurface(SDL_SWSURFACE,
+ calligraphy_brush->w,
+ calligraphy_brush->h,
+ calligraphy_brush->format->BitsPerPixel,
+ calligraphy_brush->format->Rmask,
+ calligraphy_brush->format->Gmask,
+ calligraphy_brush->format->Bmask, amask);
+
+ if (calligraphy_colored_brush == NULL)
+ return; // FIXME: Error!
+
+ SDL_LockSurface(calligraphy_brush);
+ SDL_LockSurface(calligraphy_colored_brush);
+
+
+ for (y = 0; y < calligraphy_brush->h; y++)
+ {
+ for (x = 0; x < calligraphy_brush->w; x++)
+ {
+ SDL_GetRGBA(api->getpixel(calligraphy_brush, x, y),
+ calligraphy_brush->format, &r, &g, &b, &a);
+
+ api->putpixel(calligraphy_colored_brush, x, y,
+ SDL_MapRGBA(calligraphy_colored_brush->format,
+ calligraphy_r,
+ calligraphy_g,
+ calligraphy_b, a));
+ }
+ }
+
+ SDL_UnlockSurface(calligraphy_colored_brush);
+ SDL_UnlockSurface(calligraphy_brush);
+}
+
+// We don't use colors
+int calligraphy_requires_colors(magic_api * api, int which)
+{
+ return 1;
+}
+
+
+/*
+Code to generate a cubic Bezier curve
+*/
+
+/*
+cp is a 4 element array where:
+cp[0] is the starting point, or P0 in the above diagram
+cp[1] is the first control point, or P1 in the above diagram
+cp[2] is the second control point, or P2 in the above diagram
+cp[3] is the end point, or P3 in the above diagram
+t is the parameter value, 0 <= t <= 1
+*/
+
+Point2D calligraphy_PointOnCubicBezier( Point2D* cp, float t )
+{
+ float ax, bx, cx;
+ float ay, by, cy;
+ float tSquared, tCubed;
+ Point2D result;
+
+ /* calculate the polynomial coefficients */
+
+ cx = 3.0 * (cp[1].x - cp[0].x);
+ bx = 3.0 * (cp[2].x - cp[1].x) - cx;
+ ax = cp[3].x - cp[0].x - cx - bx;
+
+ cy = 3.0 * (cp[1].y - cp[0].y);
+ by = 3.0 * (cp[2].y - cp[1].y) - cy;
+ ay = cp[3].y - cp[0].y - cy - by;
+
+ /* calculate the curve point at parameter value t */
+
+ tSquared = t * t;
+ tCubed = tSquared * t;
+
+ result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
+ result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
+
+ return result;
+}
+
+
+/*
+ ComputeBezier fills an array of Point2D structs with the curve
+ points generated from the control points cp. Caller must
+ allocate sufficient memory for the result, which is
+
+*/
+
+void calligraphy_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve)
+{
+ float dt;
+ int i;
+
+ dt = 1.0 / ( numberOfPoints - 1 );
+
+ for( i = 0; i < numberOfPoints; i++)
+ curve[i] = calligraphy_PointOnCubicBezier( cp, i*dt );
+}
+
+float calligraphy_dist(float x1, float y1, float x2, float y2)
+{
+ float d;
+ d = (sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
+
+ return d;
+}
+
diff --git a/magic/src/sparkles.c b/magic/src/sparkles.c
deleted file mode 100644
index 7fa5a610b..000000000
--- a/magic/src/sparkles.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- sparkles.c
-
- Sparkles Magic Tool Plugin
- Tux Paint - A simple drawing program for children.
-
- Copyright (c) 2002-2007 by Bill Kendrick and others; see AUTHORS.txt
- 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)
-
- Last updated: August 9, 2007
- $Id$
-*/
-
-#include
-#include
-#include
-#include "tp_magic_api.h"
-#include "SDL_image.h"
-#include "SDL_mixer.h"
-
-#include "math.h"
-
-/* Our globals: */
-
-Mix_Chunk * sparkles1_snd, * sparkles2_snd;
-float sparkles_h, sparkles_s, sparkles_v;
-
-
-Uint32 sparkles_api_version(void) { return(TP_MAGIC_API_VERSION); }
-
-
-// No setup required:
-int sparkles_init(magic_api * api)
-{
- char fname[1024];
-
- snprintf(fname, sizeof(fname), "%s/sounds/magic/sparkles1.wav",
- api->data_directory);
- sparkles1_snd = Mix_LoadWAV(fname);
-
- snprintf(fname, sizeof(fname), "%s/sounds/magic/sparkles2.wav",
- api->data_directory);
- sparkles2_snd = Mix_LoadWAV(fname);
-
- return(1);
-}
-
-// We have multiple tools:
-int sparkles_get_tool_count(magic_api * api)
-{
- return(1);
-}
-
-// Load our icons:
-SDL_Surface * sparkles_get_icon(magic_api * api, int which)
-{
- char fname[1024];
-
- snprintf(fname, sizeof(fname), "%s/images/magic/sparkles.png",
- api->data_directory);
-
- return(IMG_Load(fname));
-}
-
-// Return our names, localized:
-char * sparkles_get_name(magic_api * api, int which)
-{
- return(strdup(gettext("Sparkles")));
-}
-
-// Return our descriptions, localized:
-char * sparkles_get_description(magic_api * api, int which)
-{
- return(strdup(gettext("Click and drag to draw glowing sparkles on your picture.")));
-}
-
-// Do the effect:
-
-void do_sparkles(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
- int x, int y)
-{
- magic_api * api = (magic_api *) ptr;
- int xx, yy;
- Uint32 pix;
- Uint8 r, g, b;
- float h, s, v, new_h, new_s, new_v;
- float adj;
-
- for (yy = -8; yy < 8; yy++)
- {
- for (xx = -8; xx < 8; xx++)
- {
- if (api->in_circle(xx, yy, 8))
- {
- pix = api->getpixel(canvas, x + xx, y + yy);
-
- SDL_GetRGB(pix, canvas->format, &r, &g, &b);
-
- adj = (7.99 - sqrt(abs(xx * yy))) / 128.0;
-
- api->rgbtohsv(r, g, b, &h, &s, &v);
-
- v = min(1.0, v + adj);
-
- if (sparkles_h == -1 && h == -1)
- {
- new_h = -1;
- new_s = 0;
- new_v = v;
- }
- else if (sparkles_h == -1)
- {
- new_h = h;
- new_s = max(0.0, s - adj / 2.0);
- new_v = v;
- }
- else if (h == -1)
- {
- new_h = sparkles_h;
- new_s = max(0.0, sparkles_s - adj / 2.0);
- new_v = v;
- }
- else
- {
- new_h = (sparkles_h + h) / 2;
- new_s = max(0.0, s - adj / 2.0);
- new_v = v;
- }
-
- api->hsvtorgb(new_h, new_s, new_v, &r, &g, &b);
-
- api->putpixel(canvas, x + xx, y + yy,
- SDL_MapRGB(canvas->format, r, g, b));
- }
- }
- }
-}
-
-// Affect the canvas on drag:
-void sparkles_drag(magic_api * api, int which, SDL_Surface * canvas,
- SDL_Surface * last, int ox, int oy, int x, int y,
- SDL_Rect * update_rect)
-{
- api->line((void *) api, which, canvas, last, ox, oy, x, y, 1, do_sparkles);
-
- if (ox > x) { int tmp = ox; ox = x; x = tmp; }
- if (oy > y) { int tmp = oy; oy = y; y = tmp; }
-
- update_rect->x = ox - 8;
- update_rect->y = oy - 8;
- update_rect->w = (x + 8) - update_rect->x;
- update_rect->h = (y + 8) - update_rect->h;
-
- if ((rand() % 10) == 0)
- {
- if ((rand() % 10) < 5)
- api->playsound(sparkles1_snd, (x * 255) / canvas->w, 255);
- else
- api->playsound(sparkles2_snd, (x * 255) / canvas->w, 255);
- }
-}
-
-// Affect the canvas on click:
-void sparkles_click(magic_api * api, int which,
- SDL_Surface * canvas, SDL_Surface * last,
- int x, int y, SDL_Rect * update_rect)
-{
- sparkles_drag(api, which, canvas, last, x, y, x, y, update_rect);
-}
-
-// Affect the canvas on release:
-void sparkles_release(magic_api * api, int which,
- SDL_Surface * canvas, SDL_Surface * last,
- int x, int y, SDL_Rect * update_rect)
-{
-}
-
-// No setup happened:
-void sparkles_shutdown(magic_api * api)
-{
- if (sparkles1_snd != NULL)
- Mix_FreeChunk(sparkles1_snd);
- if (sparkles2_snd != NULL)
- Mix_FreeChunk(sparkles2_snd);
-}
-
-// Record the color from Tux Paint:
-void sparkles_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
-{
- api->rgbtohsv(r, g, b, &sparkles_h, &sparkles_s, &sparkles_v);
-}
-
-// Use colors:
-int sparkles_requires_colors(magic_api * api, int which)
-{
- return 1;
-}
-