1 /*
2   metalpaint.c
3 
4   Metal Paint Magic Tool Plugin
5   Tux Paint - A simple drawing program for children.
6 
7   Copyright (c) 2002-2008 by Bill Kendrick and others; see AUTHORS.txt
8   bill@newbreedsoftware.com
9   http://www.tuxpaint.org/
10 
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2 of the License, or
14   (at your option) any later version.
15 
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20 
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24   (See COPYING.txt)
25 
26   Last updated: July 8, 2008
27   $Id$
28 */
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include "tp_magic_api.h"
33 #include "SDL_image.h"
34 #include "SDL_mixer.h"
35 
36 /* Our globals: */
37 
38 static Mix_Chunk *metalpaint_snd;
39 static Uint8 metalpaint_r, metalpaint_g, metalpaint_b;
40 
41 Uint32 metalpaint_api_version(void);
42 int metalpaint_init(magic_api * api);
43 int metalpaint_get_tool_count(magic_api * api);
44 SDL_Surface *metalpaint_get_icon(magic_api * api, int which);
45 char *metalpaint_get_name(magic_api * api, int which);
46 char *metalpaint_get_description(magic_api * api, int which, int mode);
47 static void do_metalpaint(void *ptr, int which, SDL_Surface * canvas, SDL_Surface * last, int x, int y);
48 void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
49                      SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
50 void metalpaint_click(magic_api * api, int which, int mode,
51                       SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
52 void metalpaint_release(magic_api * api, int which,
53                         SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
54 void metalpaint_shutdown(magic_api * api);
55 void metalpaint_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
56 int metalpaint_requires_colors(magic_api * api, int which);
57 void metalpaint_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
58 void metalpaint_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
59 int metalpaint_modes(magic_api * api, int which);
60 
61 
metalpaint_api_version(void)62 Uint32 metalpaint_api_version(void)
63 {
64   return (TP_MAGIC_API_VERSION);
65 }
66 
67 
68 // No setup required:
metalpaint_init(magic_api * api)69 int metalpaint_init(magic_api * api)
70 {
71   char fname[1024];
72 
73   snprintf(fname, sizeof(fname), "%s/sounds/magic/metalpaint.wav", api->data_directory);
74   metalpaint_snd = Mix_LoadWAV(fname);
75 
76   return (1);
77 }
78 
79 // We have multiple tools:
metalpaint_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)80 int metalpaint_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
81 {
82   return (1);
83 }
84 
85 // Load our icons:
metalpaint_get_icon(magic_api * api,int which ATTRIBUTE_UNUSED)86 SDL_Surface *metalpaint_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
87 {
88   char fname[1024];
89 
90   snprintf(fname, sizeof(fname), "%s/images/magic/metalpaint.png", api->data_directory);
91 
92   return (IMG_Load(fname));
93 }
94 
95 // Return our names, localized:
metalpaint_get_name(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)96 char *metalpaint_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
97 {
98   return (strdup(gettext_noop("Metal Paint")));
99 }
100 
101 // Return our descriptions, localized:
metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED)102 char *metalpaint_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
103                                  int mode ATTRIBUTE_UNUSED)
104 {
105   return (strdup(gettext_noop("Click and drag the mouse to paint with a metallic color.")));
106 }
107 
108 #define METALPAINT_CYCLE 32
109 
110 /* Based on 'Golden' gradient in The GIMP: */
111 
112 static int metalpaint_gradient[METALPAINT_CYCLE] = {
113   56, 64, 73, 83, 93, 102, 113, 123,
114   139, 154, 168, 180, 185, 189, 183, 174,
115   164, 152, 142, 135, 129, 138, 149, 158,
116   166, 163, 158, 149, 140, 122, 103, 82
117 };
118 
119 // Do the effect:
120 
do_metalpaint(void * ptr,int which ATTRIBUTE_UNUSED,SDL_Surface * canvas,SDL_Surface * last ATTRIBUTE_UNUSED,int x,int y)121 static void do_metalpaint(void *ptr, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
122                           SDL_Surface * last ATTRIBUTE_UNUSED, int x, int y)
123 {
124   magic_api *api = (magic_api *) ptr;
125   int xx, yy;
126   int n;
127   Uint8 r, g, b;
128 
129   for (yy = -8; yy < 8; yy++)
130     {
131       for (xx = -8; xx < 8; xx++)
132         {
133           n = metalpaint_gradient[((x + xx + y + yy) / 4) % METALPAINT_CYCLE];
134 
135           r = (metalpaint_r * n) / 255;
136           g = (metalpaint_g * n) / 255;
137           b = (metalpaint_b * n) / 255;
138 
139           api->putpixel(canvas, x + xx, y + yy, SDL_MapRGB(canvas->format, r, g, b));
140         }
141     }
142 }
143 
144 // Affect the canvas on drag:
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)145 void metalpaint_drag(magic_api * api, int which, SDL_Surface * canvas,
146                      SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
147 {
148   api->line((void *)api, which, canvas, last, ox, oy, x, y, 1, do_metalpaint);
149 
150   if (ox > x)
151     {
152       int tmp = ox;
153 
154       ox = x;
155       x = tmp;
156     }
157   if (oy > y)
158     {
159       int tmp = oy;
160 
161       oy = y;
162       y = tmp;
163     }
164 
165   update_rect->x = ox - 8;
166   update_rect->y = oy - 8;
167   update_rect->w = (x + 8) - update_rect->x;
168   update_rect->h = (y + 8) - update_rect->h;
169 
170   api->playsound(metalpaint_snd, (x * 255) / canvas->w, 255);
171 }
172 
173 // Affect the canvas on click:
metalpaint_click(magic_api * api,int which,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas,SDL_Surface * last,int x,int y,SDL_Rect * update_rect)174 void metalpaint_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
175                       SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
176 {
177   metalpaint_drag(api, which, canvas, last, x, y, x, y, update_rect);
178 }
179 
180 // Affect the canvas on release:
metalpaint_release(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED,SDL_Surface * last ATTRIBUTE_UNUSED,int x ATTRIBUTE_UNUSED,int y ATTRIBUTE_UNUSED,SDL_Rect * update_rect ATTRIBUTE_UNUSED)181 void metalpaint_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
182                         SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * last ATTRIBUTE_UNUSED,
183                         int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
184 {
185 }
186 
187 // No setup happened:
metalpaint_shutdown(magic_api * api ATTRIBUTE_UNUSED)188 void metalpaint_shutdown(magic_api * api ATTRIBUTE_UNUSED)
189 {
190   if (metalpaint_snd != NULL)
191     Mix_FreeChunk(metalpaint_snd);
192 }
193 
194 // Record the color from Tux Paint:
metalpaint_set_color(magic_api * api ATTRIBUTE_UNUSED,Uint8 r,Uint8 g,Uint8 b)195 void metalpaint_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b)
196 {
197   metalpaint_r = min(255, r + 64);
198   metalpaint_g = min(255, g + 64);
199   metalpaint_b = min(255, b + 64);
200 }
201 
202 // Use colors:
metalpaint_requires_colors(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)203 int metalpaint_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
204 {
205   return 1;
206 }
207 
metalpaint_switchin(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED)208 void metalpaint_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
209                          SDL_Surface * canvas ATTRIBUTE_UNUSED)
210 {
211 }
212 
metalpaint_switchout(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED)213 void metalpaint_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
214                           SDL_Surface * canvas ATTRIBUTE_UNUSED)
215 {
216 }
217 
metalpaint_modes(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)218 int metalpaint_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
219 {
220   return (MODE_PAINT);
221 }
222