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