From 1f0d12ba91412b5ae7d1069e785de8aa11b34270 Mon Sep 17 00:00:00 2001 From: William Kendrick Date: Wed, 11 Jul 2007 06:20:05 +0000 Subject: [PATCH] Finished flower tool. Added foam tool. Cleanup. --- docs/CHANGES.txt | 4 +- magic/Makefile | 7 +- magic/icons/flower_base.png | Bin 0 -> 1418 bytes magic/icons/flower_leaf.png | Bin 0 -> 605 bytes magic/icons/flower_petals.png | Bin 0 -> 844 bytes magic/icons/foam_data.png | Bin 0 -> 9089 bytes magic/src/bricks.c | 8 +- magic/src/emboss.c | 4 +- magic/src/flower.c | 444 ++++++++++++++++++++++++++++++---- magic/src/foam.c | 390 +++++++++++++++++++++++++++++ magic/src/grass.c | 8 +- magic/src/negative.c | 8 +- magic/src/rainbow.c | 8 +- magic/src/smudge.c | 8 +- magic/src/tint.c | 8 +- magic/src/waves.c | 25 +- src/tuxpaint.c | 10 + 17 files changed, 840 insertions(+), 92 deletions(-) create mode 100644 magic/icons/flower_base.png create mode 100644 magic/icons/flower_leaf.png create mode 100644 magic/icons/flower_petals.png create mode 100644 magic/icons/foam_data.png create mode 100644 magic/src/foam.c diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index bae1fcca2..62d91368c 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -42,7 +42,9 @@ $Id$ * Emboss * Metal Paint * Waves - * Flower [unfinished] + * Flower + (utilizes Bezier curve example code from Wikipedia.org) + * Foam * New Localizations: ------------------ diff --git a/magic/Makefile b/magic/Makefile index 0a985f265..9c4fb55ae 100644 --- a/magic/Makefile +++ b/magic/Makefile @@ -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 $@ $< + diff --git a/magic/icons/flower_base.png b/magic/icons/flower_base.png new file mode 100644 index 0000000000000000000000000000000000000000..b1626219403e7b5a28ea9cb670dd7a061fef110d GIT binary patch literal 1418 zcmV;51$Fv~P)WFU8GbZ8({Xk{QrNlj4iWF>9@00izyL_t(Y$DLK(YZO-$ z|J|88-@7|IlVsHxUDru839bfBLZA>ESp?zwF(iSYG|3ImE=u2M; zKG+tNU`Vl}K;V>HB=nEgn0XLoky&h%wt*Cj&f4+hT6J?H$+IdjfE1pfoQ zKlJVfa23E705*WbcTU~8*QjHqtu_EhvIE)go9(T%bqqj%b|8C!Yxp?W^=sE#oi{oU zHz~inNepEG?Eo|YtpNHq(fJC%r<;(s8H&*#(_)KO+8X2O&)eLFA_F;pgvj7$VB$}Kk z07%2T({z3ofB|4zvu(miyr&3CcemdiH+eI{0l?_p(POD_>a-vVD@sU_l2?;Y>iWX~ z-mE)p#PJ510Qlv(|Lfr-7&riV0Bry;k{LOcnoZr1sFd8}?Wu%F=l}q405DOSn5Ljw z(o4p=VqKsDHTI3~%fZJ^_=o|BHI?#cgB&yk_c;h!0C)g?0#NRm?)g|2CVAclUatC=zK!8YYYoQX{VbII~Hk1ppX;k$U#; z^CkWOcvQiI>(D#S8H$nW&^ty;xsvRay^0>_9snUga0fvCSr1H>CNCAMMb2lwu-)H| zWIS0=!|GGP69V4mWl|+?TWRaOmA1M8JgO5j06u`f0D!Z(FPXvsK$5A<@^*eoX7W&F zwPFa8@Z^wuNan#)0Fw*u!o%!9c8YGKQuK>+0UykiYvmr3no_&p9-|#}ZYDQ_Qcxll zw<0ouy#pTbLSC7cs0To*m-tV1JT=0`)oW|lNOmAQwZY482*Np`W!+!D z6&K@g05GCTv=WxWPR*;iOU0#7kJ+=V2+Go0am~`GR`MOclle>{JPBIDEwxs))i9`` z#{GD>X4eYLW09Pl)0a!j9wEdrHS_V6(v^<@T+ff??Zz2?4t+QKzBr+uI0azG#)vtd zqbw8`ctbI2il{g~e1ASSPbzLDYDGP9L1U*vv;>wDGL8HMn2d|N1U* z*J~mXcW~f5AAX_03YV|1UZ0tLX?CpX%KjTbA{9=ZHh5#0fIMbkT;9v)CrT5aWCyb2 zoAHqUvVPCco^Q)kGoJx~&g)MJ$nRr4W8<4`Ish06jeN@y&gH=`-mc#Mak6i6{6)V1 Y0nUT}NDLOSu>b%707*qoM6N<$f>@t}u>b%7 literal 0 HcmV?d00001 diff --git a/magic/icons/flower_leaf.png b/magic/icons/flower_leaf.png new file mode 100644 index 0000000000000000000000000000000000000000..37323d68cc36fa35b36bcf850a1f7db76f048ba4 GIT binary patch literal 605 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 literal 0 HcmV?d00001 diff --git a/magic/src/bricks.c b/magic/src/bricks.c index 983010d35..798f1ea72 100644 --- a/magic/src/bricks.c +++ b/magic/src/bricks.c @@ -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); } diff --git a/magic/src/emboss.c b/magic/src/emboss.c index 09f217d86..e6ac1606a 100644 --- a/magic/src/emboss.c +++ b/magic/src/emboss.c @@ -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++) diff --git a/magic/src/flower.c b/magic/src/flower.c index a75f496b1..e30c6740b 100644 --- a/magic/src/flower.c +++ b/magic/src/flower.c @@ -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 + +*/ + +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); +} + diff --git a/magic/src/foam.c b/magic/src/foam.c new file mode 100644 index 000000000..4f2400f95 --- /dev/null +++ b/magic/src/foam.c @@ -0,0 +1,390 @@ +#include +#include +#include +#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 */ +} + diff --git a/magic/src/grass.c b/magic/src/grass.c index ce7206145..6b6973a2d 100644 --- a/magic/src/grass.c +++ b/magic/src/grass.c @@ -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); diff --git a/magic/src/negative.c b/magic/src/negative.c index 5c6551445..867b9c5d1 100644 --- a/magic/src/negative.c +++ b/magic/src/negative.c @@ -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); diff --git a/magic/src/rainbow.c b/magic/src/rainbow.c index 39d0d6c34..17d06c192 100644 --- a/magic/src/rainbow.c +++ b/magic/src/rainbow.c @@ -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); } diff --git a/magic/src/smudge.c b/magic/src/smudge.c index bb568ae3e..b496099fa 100644 --- a/magic/src/smudge.c +++ b/magic/src/smudge.c @@ -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: diff --git a/magic/src/tint.c b/magic/src/tint.c index ca55f20ff..8ad12c880 100644 --- a/magic/src/tint.c +++ b/magic/src/tint.c @@ -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); } diff --git a/magic/src/waves.c b/magic/src/waves.c index 7aa1b65db..1e72191e0 100644 --- a/magic/src/waves.c +++ b/magic/src/waves.c @@ -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, diff --git a/src/tuxpaint.c b/src/tuxpaint.c index fce2936d9..6c4c52aad 100644 --- a/src/tuxpaint.c +++ b/src/tuxpaint.c @@ -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)); +} +