Added toothpaste.c magic tool

This commit is contained in:
Andrew Corcoran 2008-08-04 16:42:47 +00:00
parent 14f38f95e2
commit 3086d42ac8
3 changed files with 226 additions and 1 deletions

View file

@ -46,7 +46,7 @@ $Id$
implied warranty. implied warranty.
Blur ('entire image' mode), Sharpen, Trace Contour, Silhouette, Blur ('entire image' mode), Sharpen, Trace Contour, Silhouette,
Snow Flake, Snow Ball, Black & White, Threshold, Alien, Snow Flake, Snow Ball, Black & White, Threshold, Alien, Toothpaste,
Tint ('Brush' mode), Noise, Rain and Mosaic Magic Tools. Tint ('Brush' mode), Noise, Rain and Mosaic Magic Tools.
Jigsaw 3x3 and Jigsaw 5x5 starter images. Jigsaw 3x3 and Jigsaw 5x5 starter images.
by Andrew 'akanewbie' Corcoran <akanewbie@gmail.com> by Andrew 'akanewbie' Corcoran <akanewbie@gmail.com>

View file

@ -30,6 +30,7 @@ $Id$
+ Noise - Adds random noise to the image. + Noise - Adds random noise to the image.
+ Mosaic - Gives the image a mosaic effect. + Mosaic - Gives the image a mosaic effect.
+ Rain - Adds rain drops to the image. + Rain - Adds rain drops to the image.
+ Toothpaste - Squirts "toothpaste" on to the image.
By Andrew 'akanewbie' Corcoran <akanewbie@gmail.com> By Andrew 'akanewbie' Corcoran <akanewbie@gmail.com>
(Part of Tux4Kids' participation in Google Summer of Code 2008) (Part of Tux4Kids' participation in Google Summer of Code 2008)

224
magic/src/toothpaste.c Normal file
View file

@ -0,0 +1,224 @@
/*
toothpaste.c
toothpaste, Add a toothpaste effect to the image
Tux Paint - A simple drawing program for children.
Credits: Andrew Corcoran <akanewbie@gmail.com>
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: June 6, 2008
$Id$
*/
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include "tp_magic_api.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include <math.h>
#include <limits.h>
#include <time.h>
#ifndef gettext_noop
#define gettext_noop(String) String
#endif
double pi;
static Uint8 toothpaste_r, toothpaste_g, toothpaste_b;
static const int toothpaste_RADIUS = 10;
double* toothpaste_weights = NULL;
enum {
TOOL_toothpaste,
toothpaste_NUM_TOOLS
};
static Mix_Chunk * toothpaste_snd_effect[toothpaste_NUM_TOOLS];
const char * toothpaste_snd_filenames[toothpaste_NUM_TOOLS] = {
"flip.wav",
};
const char * toothpaste_icon_filenames[toothpaste_NUM_TOOLS] = {
"flip.png",
};
const char * toothpaste_names[toothpaste_NUM_TOOLS] = {
gettext_noop("Toothpaste"),
};
const char * toothpaste_descs[toothpaste_NUM_TOOLS] = {
gettext_noop("Click and drag to squirt toothpaste onto the image."),
};
Uint32 toothpaste_api_version(void) { return(TP_MAGIC_API_VERSION); }
int toothpaste_init(magic_api * api){
int i;
char fname[1024];
//Load sounds
for (i = 0; i < toothpaste_NUM_TOOLS; i++){
snprintf(fname, sizeof(fname), "%s/sounds/magic/%s", api->data_directory, toothpaste_snd_filenames[i]);
toothpaste_snd_effect[i] = Mix_LoadWAV(fname);
}
//Set up weights
pi = acos(0.0) * 2;
toothpaste_weights = (double*)malloc(toothpaste_RADIUS*2 * toothpaste_RADIUS*2 * sizeof(double));
if (toothpaste_weights == NULL){
return(0);
}
int k,j;
for (k = - toothpaste_RADIUS; k < + toothpaste_RADIUS; k++){
for (j = - toothpaste_RADIUS; j < + toothpaste_RADIUS; j++){
if (api->in_circle(j , k, toothpaste_RADIUS)){
toothpaste_weights[(k+toothpaste_RADIUS)*((toothpaste_RADIUS*2) -1)+(j+toothpaste_RADIUS)] = ((fabs(atan2((double)(j),(double)(k))))/pi);
}
}
}
return(1);
}
int toothpaste_get_tool_count(magic_api * api){
return(toothpaste_NUM_TOOLS);
}
// Load our icons:
SDL_Surface * toothpaste_get_icon(magic_api * api, int which){
char fname[1024];
snprintf(fname, sizeof(fname), "%simages/magic/%s", api->data_directory, toothpaste_icon_filenames[which]);
return(IMG_Load(fname));
}
// Return our names, localized:
char * toothpaste_get_name(magic_api * api, int which){
return(strdup(gettext(toothpaste_names[which])));
}
// Return our descriptions, localized:
char * toothpaste_get_description(magic_api * api, int which, int mode){
return(strdup(gettext(toothpaste_descs[which])));
}
// Do the effect:
static void do_toothpaste(void * ptr, int which, SDL_Surface * canvas, SDL_Surface * last,
int x, int y){
magic_api * api = (magic_api *) ptr;
int xx, yy;
double colr;
float h,s,v;
Uint8 r,g,b;
for (yy = y - toothpaste_RADIUS; yy < y + toothpaste_RADIUS; yy++){
for (xx = x - toothpaste_RADIUS; xx < x + toothpaste_RADIUS; xx++){
if (api->in_circle(xx - x, yy - y, toothpaste_RADIUS) &&
!api->touched(xx, yy)){
api->rgbtohsv(toothpaste_r, toothpaste_g, toothpaste_b, &h, &s, &v);
api->hsvtorgb(h, s, toothpaste_weights[(yy-y+toothpaste_RADIUS)*((toothpaste_RADIUS*2) -1)+(xx-x+toothpaste_RADIUS)], &r, &g, &b);
api->putpixel(canvas, xx, yy, SDL_MapRGB(canvas->format, r, g, b));
}
}
}
}
// Affect the canvas on drag:
void toothpaste_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_toothpaste);
api->playsound(toothpaste_snd_effect[which], (x * 255) / canvas->w, 255);
update_rect->x = 0;
update_rect->y = 0;
update_rect->w = canvas->w;
update_rect->h = canvas->h;
}
// Affect the canvas on click:
void toothpaste_click(magic_api * api, int which, int mode,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect){
toothpaste_drag(api, which, canvas, last, x, y, x, y, update_rect);
}
// Affect the canvas on release:
void toothpaste_release(magic_api * api, int which,
SDL_Surface * canvas, SDL_Surface * last,
int x, int y, SDL_Rect * update_rect)
{
}
// No setup happened:
void toothpaste_shutdown(magic_api * api)
{
//Clean up sounds
int i;
for(i=0; i<toothpaste_NUM_TOOLS; i++){
if(toothpaste_snd_effect[i] != NULL){
Mix_FreeChunk(toothpaste_snd_effect[i]);
}
}
if (toothpaste_weights != NULL){
free(toothpaste_weights);
toothpaste_weights = NULL;
}
}
// Record the color from Tux Paint:
void toothpaste_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b)
{
toothpaste_r = r;
toothpaste_g = g;
toothpaste_b = b;
}
// Use colors:
int toothpaste_requires_colors(magic_api * api, int which)
{
return 1;
}
void toothpaste_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas)
{
}
void toothpaste_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas)
{
}
int toothpaste_modes(magic_api * api, int which)
{
return(MODE_PAINT);
}