Added new magic tools: Kalidescope, Glass Tile, Emboss, Metal Paint, Waves.

Began new magic tool: Flower.
This commit is contained in:
William Kendrick 2007-07-11 00:24:15 +00:00
parent c44cf54033
commit f8249b1e4d
9 changed files with 1067 additions and 25 deletions

View file

@ -9,7 +9,7 @@ http://www.tuxpaint.org/
$Id$ $Id$
2007.July.8 (0.9.18) 2007.July.10 (0.9.18)
* System-Related Improvements: * System-Related Improvements:
---------------------------- ----------------------------
* Added an API for developing Magic tools as plug-ins. * Added an API for developing Magic tools as plug-ins.
@ -28,28 +28,22 @@ $Id$
/usr/[local/]share/docs/tuxpaint-dev/ by default. /usr/[local/]share/docs/tuxpaint-dev/ by default.
* Ported existing magic tools to the new Magic tool plug-in system: * Ported existing magic tools to the new Magic tool plug-in system:
- Blur (Blur, Fill, Lighten, Darken, Mirror, Flip, Rainbow, Blocks, Chalk,
- Fill Grass, Negative, Tint, Smudge, Drip, Cartoon, Brick (large & small))
- Lighten
- Darken
- Mirror
- Flip
- Rainbow
- Blocks
- Chalk
- Grass
- Negative
- Tint
- Smudge
- Drip
- Cartoon
- Brick (large)
- Brick (small)
* New Brushes * New Brushes
----------- -----------
* Sparkles (based on old Magic Tool) * Sparkles (based on old Magic Tool)
* New Magic tools:
----------------
* Kalidescope
* Glass Tile
* Emboss
* Metal Paint
* Waves
* Flower [unfinished]
* New Localizations: * New Localizations:
------------------ ------------------
* Thai input method * Thai input method

View file

@ -25,7 +25,13 @@ all: negative.$(SO_TYPE) \
tint.$(SO_TYPE) \ tint.$(SO_TYPE) \
smudge.$(SO_TYPE) \ smudge.$(SO_TYPE) \
cartoon.$(SO_TYPE) \ cartoon.$(SO_TYPE) \
bricks.$(SO_TYPE) bricks.$(SO_TYPE) \
kalidescope.$(SO_TYPE) \
glasstile.$(SO_TYPE) \
emboss.$(SO_TYPE) \
metalpaint.$(SO_TYPE) \
waves.$(SO_TYPE) \
flower.$(SO_TYPE)
install: install:
cd .. ; make install-magic-plugins cd .. ; make install-magic-plugins
@ -87,4 +93,28 @@ bricks.$(SO_TYPE): src/bricks.c
@echo "Building Large Bricks and Small Bricks magic tools" @echo "Building Large Bricks and Small Bricks magic tools"
$(CC) $(CFLAGS) -shared -o $@ $< $(CC) $(CFLAGS) -shared -o $@ $<
kalidescope.$(SO_TYPE): src/kalidescope.c
@echo "Building Kalidescope magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<
glasstile.$(SO_TYPE): src/glasstile.c
@echo "Building Glass Tile magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<
emboss.$(SO_TYPE): src/emboss.c
@echo "Building Emboss magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<
metalpaint.$(SO_TYPE): src/metalpaint.c
@echo "Building Metal Paint magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<
waves.$(SO_TYPE): src/waves.c
@echo "Building Waves magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<
flower.$(SO_TYPE): src/flower.c
@echo "Building Flower magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<

View file

@ -119,17 +119,17 @@ void do_example(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
// Affect the canvas on drag: // Affect the canvas on drag:
void example_drag(magic_api * api, int which, SDL_Surface * canvas, void example_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y, SDL_Surface * last, int ox, int oy, int x, int y,
sDL_Rect * update_rect) SDL_Rect * update_rect)
{ {
api->line(which, canvas, last, ox, oy, x, y, 1, do_example); api->line(which, canvas, last, ox, oy, x, y, 1, do_example);
if (ox > x) { int tmp = ox; ox = x; x = tmp; } if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; } if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = x - 4; update_rect->x = ox - 4;
update_rect->y = y - 4; update_rect->y = oy - 4;
update_rect->w = (ox + 4) - update_rect->x; update_rect->w = (x + 4) - update_rect->x;
update_rect->h = (oy + 4) - update_rect->h; update_rect->h = (y + 4) - update_rect->h;
api->playsound(snd_effect[which], api->playsound(snd_effect[which],
(x * 255) / canvas->w, (y * 255) / canvas->h); (x * 255) / canvas->w, (y * 255) / canvas->h);
@ -140,7 +140,7 @@ void example_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last, SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect) int x, int y, SDL_Rect * update_rect)
{ {
example_drag(api, which, canvas, last, x, y, x, y, SDL_Rect * update_rect); example_drag(api, which, canvas, last, x, y, x, y, update_rect);
} }
// Affect the canvas on release: // Affect the canvas on release:

143
magic/src/emboss.c Normal file
View file

@ -0,0 +1,143 @@
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
/* Our globals: */
Mix_Chunk * emboss_snd;
Uint32 emboss_api_version(void) { return(TP_MAGIC_API_VERSION); }
// No setup required:
int emboss_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/one.wav",
api->data_directory);
emboss_snd = Mix_LoadWAV(fname);
return(1);
}
// We have multiple tools:
int emboss_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * emboss_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/emboss.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * emboss_get_name(magic_api * api, int which)
{
return(strdup(gettext("Emboss")));
}
// Return our descriptions, localized:
char * emboss_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click and drag the mouse to emboss the picture.")));
}
// Do the effect:
void do_emboss(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api * api = (magic_api *) ptr;
int xx, yy;
Uint8 r1, g1, b1,
r2, g2, b2,
r, g, b;
int avg1, avg2;
for (yy = -16; yy < 16; yy++)
{
for (xx = -16; xx < 16; xx++)
{
if (api->in_circle(xx, yy, 16))
{
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format, &r1, &g1, &b1);
SDL_GetRGB(api->getpixel(last, x + xx + 2, y + yy + 2), last->format, &r2, &g2, &b2);
avg1 = (r1 + g1 + b1) / 3;
avg2 = (r2 + g2 + b2) / 3;
r = 128 + (((avg1 - avg2) * 3) / 2);
if (r < 0) r = 0;
if (r > 255) r = 255;
g = b = r;
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
}
// Affect the canvas on drag:
void emboss_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(which, canvas, last, ox, oy, x, y, 1, do_emboss);
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;
api->playsound(emboss_snd,
(x * 255) / canvas->w, (y * 255) / canvas->h);
}
// Affect the canvas on click:
void emboss_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
emboss_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void emboss_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
}
// No setup happened:
void emboss_shutdown(magic_api * api)
{
if (emboss_snd != NULL)
Mix_FreeChunk(emboss_snd);
}
// Record the color from Tux Paint:
void emboss_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
}
// Use colors:
int emboss_requires_colors(magic_api * api, int which)
{
return 0;
}

216
magic/src/flower.c Normal file
View file

@ -0,0 +1,216 @@
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
/* Our globals: */
Mix_Chunk * flower_snd;
Uint8 flower_r, flower_g, flower_b;
int flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y;
/* Local function prototypes: */
void flower_drawbase(magic_api * api, SDL_Surface * canvas, int x, int y);
void flower_drawstalk(magic_api * api, SDL_Surface * canvas,
int minx, int maxx, int endx, int starty, int endy);
void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y);
Uint32 flower_api_version(void) { return(TP_MAGIC_API_VERSION); }
// No setup required:
int flower_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/flower.wav",
api->data_directory);
flower_snd = Mix_LoadWAV(fname);
return(1);
}
// We have multiple tools:
int flower_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * flower_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/flower.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * flower_get_name(magic_api * api, int which)
{
return(strdup(gettext("Flower")));
}
// Return our descriptions, localized:
char * flower_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click and drag to draw a flower stalk. Let go to finish the flower.")));
}
// Affect the canvas on drag:
void flower_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
if (x < flower_min_x)
flower_min_x = x;
if (ox < flower_min_x)
flower_min_x = ox;
if (x > flower_max_x)
flower_max_x = x;
if (ox > flower_max_x)
flower_max_x = ox;
if (y > flower_bottom_y)
y = flower_bottom_y;
if (oy > flower_bottom_y)
y = flower_bottom_y;
SDL_BlitSurface(last, NULL, canvas, NULL);
flower_drawbase(api, canvas, flower_bottom_x, flower_bottom_y);
flower_drawstalk(api, canvas, flower_min_x, flower_max_x, x,
y, flower_bottom_y);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(flower_snd, (x * 255) / canvas->w, 255); /* FIXME: Distance? */
}
// Affect the canvas on click:
void flower_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
flower_min_x = x;
flower_max_x = x;
flower_bottom_x = x;
flower_bottom_y = y;
flower_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void flower_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
if (y >= flower_bottom_y - 32)
y = flower_bottom_y - 32;
flower_drag(api, which, canvas, last, x, y, x, y, update_rect);
flower_drawflower(api, canvas, x, y);
/* FIXME */
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y)
{
SDL_Rect dest;
/* FIXME: Draw the flower in the chosen color: */
dest.x = x - 8;
dest.y = y - 8;
dest.w = 16;
dest.h = 16;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format,
flower_r,
flower_g,
flower_b));
}
void flower_drawbase(magic_api * api, SDL_Surface * canvas, int x, int y)
{
SDL_Rect dest;
/* FIXME: Draw the flower stalk: */
dest.x = x - 16;
dest.y = y - 8;
dest.w = 32;
dest.h = 16;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 128, 0));
}
void flower_drawstalk(magic_api * api, SDL_Surface * canvas,
int minx, int maxx, int endx, int starty, int endy)
{
/* flower_min_x, flower_max_x, x, flower_bottom_y, y */
int y, h;
SDL_Rect dest;
h = endy - starty;
for (y = starty; y < starty + (h / 2); y++)
{
dest.x = minx;
dest.y = y;
dest.w = 2;
dest.h = 2;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 128, 255, 128));
}
for (y = starty + (h / 2); y < endy; y++)
{
dest.x = maxx;
dest.y = y;
dest.w = 2;
dest.h = 2;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 64, 192, 64));
}
}
// No setup happened:
void flower_shutdown(magic_api * api)
{
if (flower_snd != NULL)
Mix_FreeChunk(flower_snd);
}
// Record the color from Tux Paint:
void flower_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
flower_r = r;
flower_g = g;
flower_b = b;
}
// Use colors:
int flower_requires_colors(magic_api * api, int which)
{
return 1;
}

249
magic/src/glasstile.c Normal file
View file

@ -0,0 +1,249 @@
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
/* Our globals: */
Mix_Chunk * glasstile_snd;
Uint32 glasstile_api_version(void) { return(TP_MAGIC_API_VERSION); }
int * * glasstile_hit;
int glasstile_hit_xsize;
int glasstile_hit_ysize;
// No setup required:
int glasstile_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/glasstile.wav",
api->data_directory);
glasstile_snd = Mix_LoadWAV(fname);
glasstile_hit = NULL;
glasstile_hit_ysize = 0;
return(1);
}
// We have multiple tools:
int glasstile_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * glasstile_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/glasstile.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * glasstile_get_name(magic_api * api, int which)
{
return(strdup(gettext("Glass Tile")));
}
// Return our descriptions, localized:
char * glasstile_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click and drag the mouse to put glass tile over your picture.")));
}
// Do the effect:
void do_glasstile(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api * api = (magic_api *) ptr;
int xx, yy, xl, xr, yt, yb;
Uint8 r1, g1, b1,
r2, g2, b2,
r3, g3, b3,
r4, g4, b4,
r, g, b;
Uint32 rgb;
#define GT_SIZE 20
if (x < 0 || y < 0 || x >= canvas->w || y >= canvas->h)
return;
if (glasstile_hit[y / GT_SIZE][x / GT_SIZE])
return;
glasstile_hit[y / GT_SIZE][x / GT_SIZE] = 1;
/* Align mouse (x,y) to the tile shape (to avoid smearing) */
x = ((x / (GT_SIZE * 2)) * (GT_SIZE * 2)) + (GT_SIZE / 2);
y = ((y / (GT_SIZE * 2)) * (GT_SIZE * 2)) + (GT_SIZE / 2);
/* Apply the effect: */
for (yy = -GT_SIZE; yy < GT_SIZE; yy = yy + 2)
{
for (xx = -GT_SIZE; xx < GT_SIZE; xx = xx + 2)
{
SDL_GetRGB(api->getpixel(last, x + xx, y + yy), last->format,
&r1, &g1, &b1);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy), last->format,
&r2, &g2, &b2);
SDL_GetRGB(api->getpixel(last, x + xx, y + yy + 1), last->format,
&r3, &g3, &b3);
SDL_GetRGB(api->getpixel(last, x + xx + 1, y + yy + 1), last->format,
&r4, &g4, &b4);
r = (r1 + r2 + r3 + r4) >> 2;
g = (g1 + g2 + g3 + g4) >> 2;
b = (b1 + b2 + b3 + b4) >> 2;
if (xx <= -GT_SIZE + 2 || yy == -GT_SIZE + 2)
{
r = min(255, r + 64);
g = min(255, g + 64);
b = min(255, b + 64);
}
else if (xx >= GT_SIZE - 3|| yy >= GT_SIZE - 3)
{
r = max(0, r - 64);
g = max(0, g - 64);
b = max(0, b - 64);
}
rgb = SDL_MapRGB(canvas->format, r, g, b);
xl = (xx / 3) - GT_SIZE + (GT_SIZE / 3);
xr = (xx / 3) + (GT_SIZE * 2) / 3;
yt = (yy / 3) - GT_SIZE + (GT_SIZE / 3);
yb = (yy / 3) + (GT_SIZE * 2) / 3;
api->putpixel(canvas, x + xl, y + yt, rgb);
api->putpixel(canvas, x + xx / 2, y + yt, rgb);
api->putpixel(canvas, x + xr, y + yt, rgb);
api->putpixel(canvas, x + xl, y + yy / 2, rgb);
api->putpixel(canvas, x + xr, y + yy / 2, rgb);
api->putpixel(canvas, x + xl, y + yb, rgb);
api->putpixel(canvas, x + xx / 2, y + yb, rgb);
api->putpixel(canvas, x + xr, y + yb, rgb);
/* Center */
api->putpixel(canvas, x + xx / 2, y + yy / 2, rgb);
}
}
}
// Affect the canvas on drag:
void glasstile_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(which, canvas, last, ox, oy, x, y, 1, do_glasstile);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
/* FIXME */
/*
x = ((x / (GT_SIZE * 2)) * (GT_SIZE * 2));
y = ((y / (GT_SIZE * 2)) * (GT_SIZE * 2));
ox = ((ox / (GT_SIZE * 2)) * (GT_SIZE * 2));
oy = ((oy / (GT_SIZE * 2)) * (GT_SIZE * 2));
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
x -= GT_SIZE * 2;
y -= GT_SIZE * 2;
ox += GT_SIZE * 2;
oy += GT_SIZE * 2;
update_rect->x = x - 1;
update_rect->y = y - 1;
update_rect->w = ox - update_rect->x + 1;
update_rect->h = oy - update_rect->h + 1;
*/
api->playsound(glasstile_snd, (x * 255) / canvas->w, 255);
}
// Affect the canvas on click:
void glasstile_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
int xx, yy;
if (glasstile_hit == NULL)
{
glasstile_hit_ysize = (canvas->h / GT_SIZE) + 1;
glasstile_hit_xsize = (canvas->w / GT_SIZE) + 1;
glasstile_hit = (int * *) malloc(sizeof(int *) * glasstile_hit_ysize);
for (yy = 0; yy < glasstile_hit_ysize; yy++)
glasstile_hit[yy] = (int *) malloc(sizeof(int) * glasstile_hit_xsize);
}
for (yy = 0; yy < glasstile_hit_ysize; yy++)
for (xx = 0; xx < glasstile_hit_xsize; xx++)
glasstile_hit[yy][xx] = 0;
glasstile_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void glasstile_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
}
// No setup happened:
void glasstile_shutdown(magic_api * api)
{
int y;
if (glasstile_snd != NULL)
Mix_FreeChunk(glasstile_snd);
if (glasstile_hit != NULL)
{
for (y = 0; y < glasstile_hit_ysize; y++)
{
if (glasstile_hit[y] != NULL)
free(glasstile_hit[y]);
}
free(glasstile_hit);
}
}
// Record the color from Tux Paint:
void glasstile_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
}
// Use colors:
int glasstile_requires_colors(magic_api * api, int which)
{
return 0;
}

137
magic/src/kalidescope.c Normal file
View file

@ -0,0 +1,137 @@
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
/* Our globals: */
Mix_Chunk * kalidescope_snd;
Uint8 kalidescope_r, kalidescope_g, kalidescope_b;
Uint32 kalidescope_api_version(void) { return(TP_MAGIC_API_VERSION); }
// No setup required:
int kalidescope_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/kalidescope.wav",
api->data_directory);
kalidescope_snd = Mix_LoadWAV(fname);
return(1);
}
// We have multiple tools:
int kalidescope_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * kalidescope_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/kalidescope.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * kalidescope_get_name(magic_api * api, int which)
{
return(strdup(gettext("Kalidescope")));
}
// Return our descriptions, localized:
char * kalidescope_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click and drag the mouse to draw with symmetric brushes (a kalidescope).")));
}
// Do the effect:
void do_kalidescope(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api * api = (magic_api *) ptr;
int xx, yy;
Uint32 colr;
colr = SDL_MapRGB(canvas->format,
kalidescope_r,
kalidescope_g,
kalidescope_b);
for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{
if (api->in_circle(xx, yy, 8))
{
api->putpixel(canvas, x + xx, y + yy, colr);
api->putpixel(canvas, canvas->w - 1 - x + xx, y + yy, colr);
api->putpixel(canvas, x + xx, canvas->h - 1 - y + yy, colr);
api->putpixel(canvas, canvas->w - 1 - x + xx, canvas->h - 1 - y + yy, colr);
}
}
}
}
// Affect the canvas on drag:
void kalidescope_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(which, canvas, last, ox, oy, x, y, 1, do_kalidescope);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(kalidescope_snd, 255, 255);
}
// Affect the canvas on click:
void kalidescope_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
kalidescope_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void kalidescope_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
}
// No setup happened:
void kalidescope_shutdown(magic_api * api)
{
if (kalidescope_snd != NULL)
Mix_FreeChunk(kalidescope_snd);
}
// Record the color from Tux Paint:
void kalidescope_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
kalidescope_r = r;
kalidescope_g = g;
kalidescope_b = b;
}
// Use colors:
int kalidescope_requires_colors(magic_api * api, int which)
{
return 1;
}

147
magic/src/metalpaint.c Normal file
View file

@ -0,0 +1,147 @@
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
/* Our globals: */
Mix_Chunk * metalpaint_snd;
Uint8 metalpaint_r, metalpaint_g, metalpaint_b;
Uint32 metalpaint_api_version(void) { return(TP_MAGIC_API_VERSION); }
// No setup required:
int metalpaint_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/one.wav",
api->data_directory);
metalpaint_snd = Mix_LoadWAV(fname);
return(1);
}
// We have multiple tools:
int metalpaint_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * metalpaint_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/metalpaint.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * metalpaint_get_name(magic_api * api, int which)
{
return(strdup(gettext("Metal Paint")));
}
// Return our descriptions, localized:
char * metalpaint_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click and drag the mouse to paint with a metallic color.")));
}
#define METALPAINT_CYCLE 32
/* Based on 'Golden' gradient in The GIMP: */
int metalpaint_gradient[METALPAINT_CYCLE] = {
56, 64, 73, 83, 93, 102, 113, 123,
139, 154, 168, 180, 185, 189, 183, 174,
164, 152, 142, 135, 129, 138, 149, 158,
166, 163, 158, 149, 140, 122, 103, 82
};
// Do the effect:
void do_metalpaint(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api * api = (magic_api *) ptr;
int xx, yy;
int n;
Uint8 r, g, b;
for (yy = -8; yy < 8; yy++)
{
for (xx = -8; xx < 8; xx++)
{
n = metalpaint_gradient[((x + xx + y + yy) / 4) % METALPAINT_CYCLE];
r = (metalpaint_r * n) / 255;
g = (metalpaint_g * n) / 255;
b = (metalpaint_b * n) / 255;
api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
// Affect the canvas on drag:
void metalpaint_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(which, canvas, last, ox, oy, x, y, 1, do_metalpaint);
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;
api->playsound(metalpaint_snd, (x * 255) / canvas->w, 255);
}
// Affect the canvas on click:
void metalpaint_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
metalpaint_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void metalpaint_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
}
// No setup happened:
void metalpaint_shutdown(magic_api * api)
{
if (metalpaint_snd != NULL)
Mix_FreeChunk(metalpaint_snd);
}
// Record the color from Tux Paint:
void metalpaint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
metalpaint_r = min(255, r + 64);
metalpaint_g = min(255, g + 64);
metalpaint_b = min(255, b + 64);
}
// Use colors:
int metalpaint_requires_colors(magic_api * api, int which)
{
return 1;
}

126
magic/src/waves.c Normal file
View file

@ -0,0 +1,126 @@
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include <math.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
/* Our globals: */
Mix_Chunk * waves_snd;
Uint32 waves_api_version(void) { return(TP_MAGIC_API_VERSION); }
// No setup required:
int waves_init(magic_api * api)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/sounds/magic/waves.wav",
api->data_directory);
waves_snd = Mix_LoadWAV(fname);
return(1);
}
// We have multiple tools:
int waves_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * waves_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/waves.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * waves_get_name(magic_api * api, int which)
{
return(strdup(gettext("Waves")));
}
// Return our descriptions, localized:
char * waves_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click to make the picture wavy. (Click towards the top for shorter waves; the bottom for taller waves. Click towards the left for small waves; the right for wide waves.)")));
}
void waves_drag(magic_api * api, int which, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y,
SDL_Rect * update_rect)
{
}
// Affect the canvas on click:
void waves_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
int xx, yy;
SDL_Rect src, dest;
int offset;
int width;
int height;
offset = (y % 72); // kinda random...
width = ((x * 16) / canvas->w) + 16;
height = 10 - ((y * 5) / canvas->h);
for (yy = 0; yy < canvas->h; yy++)
{
xx = sin(((yy + offset) * height) * M_PI / 180.0) * width;
src.x = 0;
src.y = yy;
src.w = canvas->w;
src.h = 1;
dest.x = xx;
dest.y = yy;
SDL_BlitSurface(last, &src, canvas, &dest);
}
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
// Affect the canvas on release:
void waves_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
}
// No setup happened:
void waves_shutdown(magic_api * api)
{
if (waves_snd != NULL)
Mix_FreeChunk(waves_snd);
}
// Record the color from Tux Paint:
void waves_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
}
// Use colors:
int waves_requires_colors(magic_api * api, int which)
{
return 0;
}