Finished flower tool.

Added foam tool.
Cleanup.
This commit is contained in:
William Kendrick 2007-07-11 06:20:05 +00:00
parent f8249b1e4d
commit 1f0d12ba91
17 changed files with 840 additions and 92 deletions

View file

@ -42,7 +42,9 @@ $Id$
* Emboss
* Metal Paint
* Waves
* Flower [unfinished]
* Flower
(utilizes Bezier curve example code from Wikipedia.org)
* Foam
* New Localizations:
------------------

View file

@ -31,7 +31,8 @@ all: negative.$(SO_TYPE) \
emboss.$(SO_TYPE) \
metalpaint.$(SO_TYPE) \
waves.$(SO_TYPE) \
flower.$(SO_TYPE)
flower.$(SO_TYPE) \
foam.$(SO_TYPE)
install:
cd .. ; make install-magic-plugins
@ -117,4 +118,8 @@ flower.$(SO_TYPE): src/flower.c
@echo "Building Flower magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<
foam.$(SO_TYPE): src/foam.c
@echo "Building Foam magic tool"
$(CC) $(CFLAGS) -shared -o $@ $<

BIN
magic/icons/flower_base.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
magic/icons/flower_leaf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

BIN
magic/icons/foam_data.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View file

@ -184,10 +184,10 @@ void bricks_drag(magic_api * api, int which, SDL_Surface * canvas,
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = x - 36;
update_rect->y = y - 24;
update_rect->w = (ox + 36) - update_rect->x;
update_rect->h = (oy + 24) - update_rect->h;
update_rect->x = x - 64;
update_rect->y = y - 64;
update_rect->w = (ox + 128) - update_rect->x;
update_rect->h = (oy + 128) - update_rect->h;
api->playsound(brick_snd, (x * 255) / canvas->w, 255);
}

View file

@ -62,8 +62,8 @@ void do_emboss(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
magic_api * api = (magic_api *) ptr;
int xx, yy;
Uint8 r1, g1, b1,
r2, g2, b2,
r, g, b;
r2, g2, b2;
int r, g, b;
int avg1, avg2;
for (yy = -16; yy < 16; yy++)

View file

@ -7,16 +7,38 @@
/* Our globals: */
enum { SIDE_LEFT, SIDE_RIGHT };
enum { LEAFSIDE_RIGHT_DOWN,
LEAFSIDE_LEFT_DOWN,
LEAFSIDE_RIGHT_UP,
LEAFSIDE_LEFT_UP };
Mix_Chunk * flower_snd;
Uint8 flower_r, flower_g, flower_b;
int flower_min_x, flower_max_x, flower_bottom_x, flower_bottom_y;
int flower_side_first;
int flower_side_decided;
SDL_Surface * flower_base, * flower_leaf, * flower_petals,
* flower_petals_colorized;
/* Local function prototypes: */
void flower_drawbase(magic_api * api, SDL_Surface * canvas, int x, int y);
typedef struct
{
float x, y;
} Point2D;
void flower_predrag(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y);
void flower_drawbase(magic_api * api, SDL_Surface * canvas);
void flower_drawstalk(magic_api * api, SDL_Surface * canvas,
int minx, int maxx, int endx, int starty, int endy);
int top_x, int top_y, int minx, int maxx,
int bottom_x, int bottom_y, int final);
void flower_drawflower(magic_api * api, SDL_Surface * canvas, int x, int y);
Point2D flower_PointOnCubicBezier(Point2D* cp, float t);
void flower_ComputeBezier(Point2D* cp, int numberOfPoints, Point2D* curve);
void flower_colorize_petals(magic_api * api);
Uint32 flower_api_version(void) { return(TP_MAGIC_API_VERSION); }
@ -31,6 +53,18 @@ int flower_init(magic_api * api)
api->data_directory);
flower_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/flower_base.png",
api->data_directory);
flower_base = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/flower_leaf.png",
api->data_directory);
flower_leaf = IMG_Load(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/flower_petals.png",
api->data_directory);
flower_petals = IMG_Load(fname);
return(1);
}
@ -64,9 +98,8 @@ char * flower_get_description(magic_api * api, int which)
}
// 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)
void flower_predrag(magic_api * api, SDL_Surface * canvas,
SDL_Surface * last, int ox, int oy, int x, int y)
{
if (x < flower_min_x)
flower_min_x = x;
@ -82,19 +115,47 @@ void flower_drag(magic_api * api, int which, SDL_Surface * canvas,
if (oy > flower_bottom_y)
y = flower_bottom_y;
// Determine which way to bend first:
//
if (flower_side_decided == 0)
{
if (x < flower_bottom_x - 10)
{
flower_side_first = SIDE_LEFT;
flower_side_decided = 1;
}
else if (x > flower_bottom_x + 10)
{
flower_side_first = SIDE_RIGHT;
flower_side_decided = 1;
}
}
}
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)
{
flower_predrag(api, canvas, last, ox, oy, x, y);
/* Erase any old stuff; this is a live-edited effect: */
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);
/* Draw the base and the stalk (low-quality) for now: */
flower_drawstalk(api, canvas,
x, y, flower_min_x, flower_max_x,
flower_bottom_x, flower_bottom_y, !(api->button_down()));
flower_drawbase(api, canvas);
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:
@ -105,7 +166,10 @@ void flower_click(magic_api * api, int which,
flower_min_x = x;
flower_max_x = x;
flower_bottom_x = x;
flower_bottom_y = y;
flower_bottom_y = y - flower_base->h;
flower_side_decided = 0;
flower_side_first = SIDE_LEFT;
flower_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
@ -115,19 +179,39 @@ void flower_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
/* Don't let flower be too low compared to base: */
if (y >= flower_bottom_y - 32)
y = flower_bottom_y - 32;
flower_drag(api, which, canvas, last, x, y, x, y, update_rect);
/* Do final calcs and draw base: */
flower_predrag(api, canvas, last, x, y, x, y);
/* Erase any old stuff: */
SDL_BlitSurface(last, NULL, canvas, NULL);
/* Draw high-quality stalk, and flower: */
flower_drawstalk(api, canvas,
x, y, flower_min_x, flower_max_x,
flower_bottom_x, flower_bottom_y, 1);
flower_drawflower(api, canvas, x, y);
/* FIXME */
flower_drawbase(api, canvas);
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? */
}
@ -135,69 +219,206 @@ 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 - (flower_petals->w / 2);
dest.y = y - (flower_petals->h / 2);
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));
SDL_BlitSurface(flower_petals_colorized, NULL, canvas, &dest);
}
void flower_drawbase(magic_api * api, SDL_Surface * canvas, int x, int y)
void flower_drawbase(magic_api * api, SDL_Surface * canvas)
{
SDL_Rect dest;
/* FIXME: Draw the flower stalk: */
dest.x = flower_bottom_x - (flower_base->w / 2);
dest.y = flower_bottom_y;
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));
SDL_BlitSurface(flower_base, NULL, canvas, &dest);
}
void flower_drawstalk(magic_api * api, SDL_Surface * canvas,
int minx, int maxx, int endx, int starty, int endy)
int top_x, int top_y, int minx, int maxx,
int bottom_x, int bottom_y, int final)
{
/* flower_min_x, flower_max_x, x, flower_bottom_y, y */
Point2D control_points[4];
Point2D * curve;
int i, n_points;
int left, right;
SDL_Rect dest, src;
int xx, yy, side;
int y, h;
SDL_Rect dest;
h = endy - starty;
/* Compute a nice bezier curve for the stalk, based on the
base (x,y), leftmost (x), rightmost (x), and top (x,y) */
for (y = starty; y < starty + (h / 2); y++)
control_points[0].x = top_x;
control_points[0].y = top_y;
if (flower_side_first == SIDE_LEFT)
{
dest.x = minx;
dest.y = y;
dest.w = 2;
dest.h = 2;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 128, 255, 128));
control_points[1].x = minx;
control_points[2].x = maxx;
}
else
{
control_points[1].x = maxx;
control_points[2].x = minx;
}
for (y = starty + (h / 2); y < endy; y++)
{
dest.x = maxx;
dest.y = y;
dest.w = 2;
dest.h = 2;
control_points[1].y = ((bottom_y - top_y) / 3) + top_y;
control_points[2].y = (((bottom_y - top_y) / 3) * 2) + top_y;
control_points[3].x = bottom_x;
control_points[3].y = bottom_y;
if (final == 0)
n_points = 8;
else
n_points = bottom_y - top_y;
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 64, 192, 64));
}
curve = (Point2D *) malloc(sizeof(Point2D) * n_points);
flower_ComputeBezier(control_points, n_points, curve);
/* Draw the curve: */
for (i = 0; i < n_points - 1; i++)
{
if (final == 0)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
dest.w = 2;
dest.h = 2;
}
else
{
left = min(curve[i].x, curve[i + 1].x);
right = max(curve[i].x, curve[i + 1].x);
dest.x = left;
dest.y = curve[i].y;
dest.w = right - left + 1;
dest.h = 2;
}
SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 128, 0));
/* When we're done (final render), we can add some random leaves: */
if (final && i > 32 && i < n_points - 32 && (i % 16) == 0 &&
(rand() % 5) > 0)
{
/* Check for hard left/right angles: */
side = -1;
if (curve[i - 2].x - curve[i + 2].x > 5)
{
/* Hard lower-left-to-upper-right (/),
stick either a left-upward or right-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_UP;
else
side = LEAFSIDE_RIGHT_DOWN;
}
else if (curve[i - 2].x - curve[i + 2].x < -5)
{
/* Hard lower-right-to-upper-left (\)
stick either a right-upward or left-downward facing leaf */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_UP;
}
else if (abs(curve[i - 2].x - curve[i + 2].x) < 5)
{
/* Mostly up; stick left- or right-downward: */
if (rand() % 10 < 5)
side = LEAFSIDE_LEFT_DOWN;
else
side = LEAFSIDE_RIGHT_DOWN;
}
/* Draw the appropriately-oriented leaf, if any: */
if (side == LEAFSIDE_RIGHT_DOWN)
{
dest.x = curve[i].x;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, NULL, canvas, &dest);
}
else if (side == LEAFSIDE_LEFT_DOWN)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
src.x = xx;
src.y = 0;
src.w = 1;
src.h = flower_leaf->h;
dest.x = curve[i].x - xx;
dest.y = curve[i].y;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_RIGHT_UP)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = 0;
src.y = yy;
src.w = flower_leaf->w;
src.h = 1;
dest.x = curve[i].x;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
else if (side == LEAFSIDE_LEFT_UP)
{
for (xx = 0; xx < flower_leaf->w; xx++)
{
for (yy = 0; yy < flower_leaf->h; yy++)
{
src.x = xx;
src.y = yy;
src.w = 1;
src.h = 1;
dest.x = curve[i].x - xx;
dest.y = curve[i].y - yy;
SDL_BlitSurface(flower_leaf, &src, canvas, &dest);
}
}
}
}
}
}
// No setup happened:
void flower_shutdown(magic_api * api)
{
if (flower_snd != NULL)
Mix_FreeChunk(flower_snd);
if (flower_base != NULL)
SDL_FreeSurface(flower_base);
if (flower_leaf != NULL)
SDL_FreeSurface(flower_leaf);
if (flower_petals != NULL)
SDL_FreeSurface(flower_petals);
if (flower_petals_colorized != NULL)
SDL_FreeSurface(flower_petals_colorized);
}
// Record the color from Tux Paint:
@ -206,6 +427,8 @@ void flower_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
flower_r = r;
flower_g = g;
flower_b = b;
flower_colorize_petals(api);
}
// Use colors:
@ -214,3 +437,120 @@ int flower_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 flower_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
<sizeof(Point2D) numberOfPoints>
*/
void flower_ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve )
{
float dt;
int i;
dt = 1.0 / ( numberOfPoints - 1 );
for( i = 0; i < numberOfPoints; i++)
curve[i] = flower_PointOnCubicBezier( cp, i*dt );
}
void flower_colorize_petals(magic_api * api)
{
Uint32 amask;
int x, y;
Uint8 r, g, b, a;
if (flower_petals_colorized != NULL)
SDL_FreeSurface(flower_petals_colorized);
/* Create a surface to render into: */
amask = ~(flower_petals->format->Rmask |
flower_petals->format->Gmask |
flower_petals->format->Bmask);
flower_petals_colorized =
SDL_CreateRGBSurface(SDL_SWSURFACE,
flower_petals->w,
flower_petals->h,
flower_petals->format->BitsPerPixel,
flower_petals->format->Rmask,
flower_petals->format->Gmask,
flower_petals->format->Bmask, amask);
/* Render the new petals: */
SDL_LockSurface(flower_petals);
SDL_LockSurface(flower_petals_colorized);
for (y = 0; y < flower_petals->h; y++)
{
for (x = 0; x < flower_petals->w; x++)
{
SDL_GetRGBA(api->getpixel(flower_petals, x, y),
flower_petals->format, &r, &g, &b, &a);
api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format,
flower_r, flower_g, flower_b, a));
if (api->in_circle((x - flower_petals->w / 2),
(y - flower_petals->h / 2),
8))
{
api->putpixel(flower_petals_colorized, x, y,
SDL_MapRGBA(flower_petals_colorized->format,
0xFF, 0xFF, 0x00, a));
}
}
}
SDL_UnlockSurface(flower_petals_colorized);
SDL_UnlockSurface(flower_petals);
}

390
magic/src/foam.c Normal file
View file

@ -0,0 +1,390 @@
#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 * foam_snd;
Uint8 foam_r, foam_g, foam_b;
int foam_mask_w, foam_mask_h;
int * foam_mask, * foam_mask_tmp;
SDL_Surface * foam_7, * foam_5, * foam_3, * foam_1;
void foam_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect);
#define FOAM_PROP 8
#define FOAM_RADIUS 3
Uint32 foam_api_version(void) { return(TP_MAGIC_API_VERSION); }
// No setup required:
int foam_init(magic_api * api)
{
char fname[1024];
SDL_Surface * foam_data;
snprintf(fname, sizeof(fname), "%s/sounds/magic/foam.wav",
api->data_directory);
foam_snd = Mix_LoadWAV(fname);
snprintf(fname, sizeof(fname), "%s/images/magic/foam_data.png",
api->data_directory);
foam_data = IMG_Load(fname);
foam_7 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 4) / 4,
((api->canvas_h / FOAM_PROP) * 4) / 4, 0);
foam_5 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 3) / 4,
((api->canvas_h / FOAM_PROP) * 3) / 4, 0);
foam_3 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 2) / 4,
((api->canvas_h / FOAM_PROP) * 2) / 4, 0);
foam_1 = api->scale(foam_data, ((api->canvas_w / FOAM_PROP) * 1) / 4,
((api->canvas_h / FOAM_PROP) * 1) / 4, 0);
SDL_FreeSurface(foam_data);
return(1);
}
// We have multiple tools:
int foam_get_tool_count(magic_api * api)
{
return(1);
}
// Load our icons:
SDL_Surface * foam_get_icon(magic_api * api, int which)
{
char fname[1024];
snprintf(fname, sizeof(fname), "%s/images/magic/foam.png",
api->data_directory);
return(IMG_Load(fname));
}
// Return our names, localized:
char * foam_get_name(magic_api * api, int which)
{
return(strdup(gettext("Foam")));
}
// Return our descriptions, localized:
char * foam_get_description(magic_api * api, int which)
{
return(strdup(gettext("Click and drag the mouse to cover an area with foamy bubbles..")));
}
// Do the effect:
void do_foam(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y)
{
magic_api * api = (magic_api *) ptr;
int xx, yy, nx, ny;
/* SDL_Rect dest; */
for (yy = -FOAM_RADIUS; yy < FOAM_RADIUS; yy++)
{
for (xx = -FOAM_RADIUS; xx < FOAM_RADIUS; xx++)
{
if (api->in_circle(xx, yy, FOAM_RADIUS))
{
nx = (x / FOAM_PROP) + xx;
ny = (y / FOAM_PROP) + yy;
if (nx >= 0 && ny >= 0 &&
nx < foam_mask_w &&
ny < foam_mask_h)
{
foam_mask[ny * foam_mask_w + nx] = 1;
}
}
}
}
}
// Affect the canvas on drag:
void foam_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_foam);
foam_release(api, which, canvas, last, x, y, update_rect);
/* FIXME */
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
api->playsound(foam_snd, (x * 255) / canvas->w, 255);
}
// Affect the canvas on click:
void foam_click(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
int i;
if (foam_mask == NULL)
{
foam_mask_w = canvas->w / FOAM_PROP;
foam_mask_h = canvas->h / FOAM_PROP;
foam_mask = (int *) malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
foam_mask_tmp = (int *) malloc(sizeof(int) * (foam_mask_w * foam_mask_h));
}
for (i = 0; i < foam_mask_w * foam_mask_h; i++)
foam_mask[i] = 0;
foam_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
int foam_mask_test(int r, int x, int y)
{
int xx, yy;
int tot, bub_r;
tot = 0;
for (yy = 0; yy < r; yy++)
{
for (xx = 0; xx < r; xx++)
{
if (x + xx < foam_mask_w && y + yy < foam_mask_h)
{
bub_r = foam_mask[((y + yy) * foam_mask_w) + (x + xx)];
tot = tot + bub_r;
}
}
}
return(tot);
}
// Affect the canvas on release:
void foam_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
int xx, yy;
int changes, max_iters;
SDL_Rect dest;
int n;
SDL_Surface * img;
SDL_BlitSurface(last, NULL, canvas, NULL);
memcpy(foam_mask_tmp, foam_mask, (sizeof(int) * (foam_mask_w * foam_mask_h)));
max_iters = 2;
do
{
changes = 0;
max_iters--;
for (yy = 0; yy < foam_mask_h - 7; yy++)
{
for (xx = 0; xx < foam_mask_w - 7; xx++)
{
if (foam_mask_test(7, xx, yy) >= 40)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 7;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 5)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 6)] = 1;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 3)] = 7;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 5)] = 3;
foam_mask[((yy + 5) * foam_mask_w) + (xx + 6)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 5)] = 0;
foam_mask[((yy + 6) * foam_mask_w) + (xx + 6)] = 2;
changes = 1;
}
else if (foam_mask_test(5, xx, yy) >= 30)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 4)] = 2;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 4)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 5;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 3)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 0)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 3)] = 2;
foam_mask[((yy + 3) * foam_mask_w) + (xx + 4)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 1)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 3)] = 1;
foam_mask[((yy + 4) * foam_mask_w) + (xx + 4)] = 0;
changes = 1;
}
else if (foam_mask_test(3, xx, yy) >= 8)
{
foam_mask[((yy + 0) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 0) * foam_mask_w) + (xx + 2)] = 1;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 0)] = 0;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 1)] = 3;
foam_mask[((yy + 1) * foam_mask_w) + (xx + 2)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 0)] = 1;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 1)] = 0;
foam_mask[((yy + 2) * foam_mask_w) + (xx + 2)] = 1;
changes = 1;
}
}
}
}
while (changes && max_iters > 0);
for (yy = 0; yy < foam_mask_h; yy++)
{
for (xx = 0; xx < foam_mask_w; xx++)
{
n = foam_mask[yy * foam_mask_w + xx];
img = NULL;
if (n == 1)
img = foam_1;
else if (n == 3)
img = foam_3;
else if (n == 5)
img = foam_5;
else if (n == 7)
img = foam_7;
if (img != NULL)
{
dest.x = (xx * FOAM_PROP) - (img->w / 2) + ((rand() % 15) - 7);
dest.y = (yy * FOAM_PROP) - (img->h / 2) + ((rand() % 15) - 7);
SDL_BlitSurface(img, NULL, canvas, &dest);
}
}
}
memcpy(foam_mask, foam_mask_tmp, (sizeof(int) * (foam_mask_w * foam_mask_h)));
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
// No setup happened:
void foam_shutdown(magic_api * api)
{
if (foam_snd != NULL)
Mix_FreeChunk(foam_snd);
if (foam_mask != NULL)
free(foam_mask);
if (foam_1 != NULL)
SDL_FreeSurface(foam_1);
if (foam_3 != NULL)
SDL_FreeSurface(foam_3);
if (foam_5 != NULL)
SDL_FreeSurface(foam_5);
if (foam_7 != NULL)
SDL_FreeSurface(foam_7);
}
// Record the color from Tux Paint:
void foam_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
foam_r = r;
foam_g = g;
foam_b = b;
}
// Use colors:
int foam_requires_colors(magic_api * api, int which)
{
return 0; /* FIXME: Would be nice to tint the bubbles */
}

View file

@ -79,10 +79,10 @@ void grass_drag(magic_api * api, int which, SDL_Surface * canvas,
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = ox - 32;
update_rect->y = oy - 32;
update_rect->w = 64;
update_rect->h = 64;
update_rect->x = ox - 64;
update_rect->y = oy - 64;
update_rect->w = 128;
update_rect->h = 192;
api->playsound(grass_snd,
(x * 255) / canvas->w, (y * 255) / canvas->h);

View file

@ -91,10 +91,10 @@ void negative_drag(magic_api * api, int which, SDL_Surface * canvas,
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = x - 16;
update_rect->y = y - 16;
update_rect->w = (ox + 16) - update_rect->x;
update_rect->h = (oy + 16) - update_rect->h;
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(negative_snd, (x * 255) / canvas->w, 255);

View file

@ -123,10 +123,10 @@ void rainbow_drag(magic_api * api, int which, SDL_Surface * canvas,
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = x - 16;
update_rect->y = y - 16;
update_rect->w = (ox + 16) - update_rect->x;
update_rect->h = (oy + 16) - update_rect->y;
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->y;
api->playsound(rainbow_snd, (x * 255) / canvas->w, 255);
}

View file

@ -104,10 +104,10 @@ void smudge_drag(magic_api * api, int which, SDL_Surface * canvas,
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = x - 16;
update_rect->y = y - 16;
update_rect->w = (ox + 16) - update_rect->x;
update_rect->h = (oy + 16) - update_rect->y;
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->y;
}
// Affect the canvas on click:

View file

@ -103,10 +103,10 @@ void tint_drag(magic_api * api, int which, SDL_Surface * canvas,
if (ox > x) { int tmp = ox; ox = x; x = tmp; }
if (oy > y) { int tmp = oy; oy = y; y = tmp; }
update_rect->x = x - 16;
update_rect->y = y - 16;
update_rect->w = (ox + 16) - update_rect->x;
update_rect->h = (oy + 16) - update_rect->y;
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->y;
api->playsound(tint_snd, (x * 255) / canvas->w, 255);
}

View file

@ -60,27 +60,20 @@ char * waves_get_description(magic_api * api, int which)
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);
SDL_BlitSurface(last, NULL, canvas, NULL);
width = ((x * 10) / canvas->w) + 10;
height = ((canvas->h - y) / 10) + 1;
for (yy = 0; yy < canvas->h; yy++)
{
xx = sin(((yy + offset) * height) * M_PI / 180.0) * width;
xx = sin((yy * height) * M_PI / 180.0) * width;
src.x = 0;
src.y = yy;
@ -99,6 +92,14 @@ void waves_click(magic_api * api, int which,
update_rect->h = canvas->h;
}
// 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)
{
waves_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void waves_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,

View file

@ -1341,6 +1341,7 @@ void magic_line_func(int which, SDL_Surface * canvas, SDL_Surface * last,
Uint8 magic_linear_to_sRGB(float lin);
float magic_sRGB_to_linear(Uint8 srgb);
int magic_button_down(void);
SDL_Surface * magic_scale(SDL_Surface * surf, int w, int h, int aspect);
#ifdef DEBUG
static char *debug_gettext(const char *str);
@ -15847,6 +15848,9 @@ void load_magic_plugins(void)
magic_api_struct->button_down = magic_button_down;
magic_api_struct->rgbtohsv = rgbtohsv;
magic_api_struct->hsvtorgb = hsvtorgb;
magic_api_struct->canvas_w = canvas->w;
magic_api_struct->canvas_h = canvas->h;
magic_api_struct->scale = magic_scale;
d = opendir(MAGIC_PREFIX);
@ -16313,3 +16317,9 @@ int magic_button_down(void)
{
return(button_down);
}
SDL_Surface * magic_scale(SDL_Surface * surf, int w, int h, int aspect)
{
return(thumbnail2(surf, w, h, aspect, 1));
}