1 /*
2 shift.c
3
4 Shift 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 #include "math.h"
37
38 /* Our globals: */
39
40 static int shift_x, shift_y;
41 static Mix_Chunk *shift_snd;
42
43
44 /* Local function prototypes: */
45
46 static void shift_doit(magic_api * api, int which, SDL_Surface * canvas,
47 SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect, int crosshairs);
48 Uint32 shift_api_version(void);
49 int shift_init(magic_api * api);
50 int shift_get_tool_count(magic_api * api);
51 SDL_Surface *shift_get_icon(magic_api * api, int which);
52 char *shift_get_name(magic_api * api, int which);
53 char *shift_get_description(magic_api * api, int which, int mode);
54 void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
55 SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect);
56 void shift_click(magic_api * api, int which, int mode,
57 SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
58 void shift_release(magic_api * api, int which,
59 SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
60 void shift_shutdown(magic_api * api);
61 void shift_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
62 int shift_requires_colors(magic_api * api, int which);
63
64 void shift_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
65 void shift_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
66 int shift_modes(magic_api * api, int which);
67
68
69
shift_api_version(void)70 Uint32 shift_api_version(void)
71 {
72 return (TP_MAGIC_API_VERSION);
73 }
74
75
76 // No setup required:
shift_init(magic_api * api)77 int shift_init(magic_api * api)
78 {
79 char fname[1024];
80
81 snprintf(fname, sizeof(fname), "%s/sounds/magic/shift.ogg", api->data_directory);
82 shift_snd = Mix_LoadWAV(fname);
83
84 return (1);
85 }
86
87 // We have multiple tools:
shift_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)88 int shift_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
89 {
90 return (1);
91 }
92
93 // Load our icons:
shift_get_icon(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)94 SDL_Surface *shift_get_icon(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
95 {
96 char fname[1024];
97
98 snprintf(fname, sizeof(fname), "%s/images/magic/shift.png", api->data_directory);
99
100 return (IMG_Load(fname));
101 }
102
103 // Return our names, localized:
shift_get_name(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)104 char *shift_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
105 {
106 return (strdup(gettext_noop("Shift")));
107 }
108
109 // Return our descriptions, localized:
shift_get_description(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED)110 char *shift_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
111 {
112 return (strdup(gettext_noop("Click and drag to shift your picture around on the canvas.")));
113 }
114
115
116 // Affect the canvas on drag:
shift_drag(magic_api * api,int which,SDL_Surface * canvas,SDL_Surface * last,int ox,int oy,int x,int y,SDL_Rect * update_rect)117 void shift_drag(magic_api * api, int which, SDL_Surface * canvas,
118 SDL_Surface * last, int ox, int oy, int x, int y, SDL_Rect * update_rect)
119 {
120 if (ox == x && oy == y)
121 return; /* No-op */
122
123 shift_doit(api, which, canvas, last, ox, oy, x, y, update_rect, 1);
124 }
125
shift_doit(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,SDL_Surface * canvas,SDL_Surface * last,int ox ATTRIBUTE_UNUSED,int oy ATTRIBUTE_UNUSED,int x,int y,SDL_Rect * update_rect,int crosshairs)126 static void shift_doit(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, SDL_Surface * canvas,
127 SDL_Surface * last, int ox ATTRIBUTE_UNUSED, int oy ATTRIBUTE_UNUSED, int x, int y,
128 SDL_Rect * update_rect, int crosshairs)
129 {
130 SDL_Rect dest;
131 int dx, dy;
132
133
134
135 dx = x - shift_x;
136 dy = y - shift_y;
137
138 while (dx < -canvas->w)
139 dx += canvas->w;
140 while (dx > canvas->w)
141 dx -= canvas->w;
142
143 while (dy < -canvas->h)
144 dy += canvas->h;
145 while (dy > canvas->h)
146 dy -= canvas->h;
147
148
149 /* Center */
150
151 dest.x = dx;
152 dest.y = dy;
153
154 SDL_BlitSurface(last, NULL, canvas, &dest);
155
156
157 if (dy > 0)
158 {
159 if (dx > 0)
160 {
161 /* Top Left */
162
163 dest.x = dx - canvas->w;
164 dest.y = dy - canvas->h;
165
166 SDL_BlitSurface(last, NULL, canvas, &dest);
167 }
168
169
170 /* Top */
171
172 dest.x = dx;
173 dest.y = dy - canvas->h;
174
175 SDL_BlitSurface(last, NULL, canvas, &dest);
176
177
178 if (dx < 0)
179 {
180 /* Top Right */
181
182 dest.x = dx + canvas->w;
183 dest.y = dy - canvas->h;
184
185 SDL_BlitSurface(last, NULL, canvas, &dest);
186 }
187 }
188
189
190 if (dx > 0)
191 {
192 /* Left */
193
194 dest.x = dx - canvas->w;
195 dest.y = dy;
196
197 SDL_BlitSurface(last, NULL, canvas, &dest);
198 }
199
200 if (dx < 0)
201 {
202 /* Right */
203
204 dest.x = dx + canvas->w;
205 dest.y = dy;
206
207 SDL_BlitSurface(last, NULL, canvas, &dest);
208 }
209
210
211 if (dy < 0)
212 {
213 if (dx > 0)
214 {
215 /* Bottom Left */
216
217 dest.x = dx - canvas->w;
218 dest.y = dy + canvas->h;
219
220 SDL_BlitSurface(last, NULL, canvas, &dest);
221 }
222
223
224 /* Bottom */
225
226 dest.x = dx;
227 dest.y = dy + canvas->h;
228
229 SDL_BlitSurface(last, NULL, canvas, &dest);
230
231
232 if (dx < 0)
233 {
234 /* Bottom Right */
235
236 dest.x = dx + canvas->w;
237 dest.y = dy + canvas->h;
238
239 SDL_BlitSurface(last, NULL, canvas, &dest);
240 }
241 }
242
243
244 if (crosshairs)
245 {
246 dest.x = (canvas->w / 2) - 1;
247 dest.y = 0;
248 dest.w = 3;
249 dest.h = canvas->h;
250
251 SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
252
253 dest.x = 0;
254 dest.y = (canvas->h / 2) - 1;
255 dest.w = canvas->w;
256 dest.h = 3;
257
258 SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 255, 255, 255));
259
260
261 dest.x = canvas->w / 2;
262 dest.y = 0;
263 dest.w = 1;
264 dest.h = canvas->h;
265
266 SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
267
268 dest.x = 0;
269 dest.y = canvas->h / 2;
270 dest.w = canvas->w;
271 dest.h = 1;
272
273 SDL_FillRect(canvas, &dest, SDL_MapRGB(canvas->format, 0, 0, 0));
274 }
275
276
277 /* Update everything! */
278
279 update_rect->x = 0;
280 update_rect->y = 0;
281 update_rect->w = canvas->w;
282 update_rect->h = canvas->h;
283
284 api->playsound(shift_snd, (x * 255) / canvas->w, 255);
285 }
286
287 // Affect the canvas on click:
shift_click(magic_api * api,int which,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas,SDL_Surface * last,int x,int y,SDL_Rect * update_rect)288 void shift_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
289 SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
290 {
291 shift_x = x;
292 shift_y = y;
293
294 shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 1);
295 }
296
297 // Affect the canvas on release:
shift_release(magic_api * api,int which,SDL_Surface * canvas,SDL_Surface * last,int x,int y,SDL_Rect * update_rect)298 void shift_release(magic_api * api, int which,
299 SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
300 {
301 shift_doit(api, which, canvas, last, x, y, x, y, update_rect, 0);
302 api->stopsound();
303 }
304
305
306 // No setup happened:
shift_shutdown(magic_api * api ATTRIBUTE_UNUSED)307 void shift_shutdown(magic_api * api ATTRIBUTE_UNUSED)
308 {
309 if (shift_snd != NULL)
310 Mix_FreeChunk(shift_snd);
311 }
312
313 // Record the color from Tux Paint:
shift_set_color(magic_api * api ATTRIBUTE_UNUSED,Uint8 r ATTRIBUTE_UNUSED,Uint8 g ATTRIBUTE_UNUSED,Uint8 b ATTRIBUTE_UNUSED)314 void shift_set_color(magic_api * api ATTRIBUTE_UNUSED,
315 Uint8 r ATTRIBUTE_UNUSED, Uint8 g ATTRIBUTE_UNUSED, Uint8 b ATTRIBUTE_UNUSED)
316 {
317 }
318
319 // Use colors:
shift_requires_colors(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)320 int shift_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
321 {
322 return 0;
323 }
324
shift_switchin(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED)325 void shift_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
326 SDL_Surface * canvas ATTRIBUTE_UNUSED)
327 {
328 }
329
shift_switchout(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED)330 void shift_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
331 SDL_Surface * canvas ATTRIBUTE_UNUSED)
332 {
333 }
334
shift_modes(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)335 int shift_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
336 {
337 return (MODE_PAINT_WITH_PREVIEW);
338 }
339