1 /*
2 blind.c
3
4 BLIND Magic Tools Plugin
5 Tux Paint - A simple drawing program for children.
6
7 By Pere Pujal Carabantes
8
9 Copyright (c) 2009-2021
10 http://www.tuxpaint.org/
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 (See COPYING.txt)
26 */
27
28 #include "tp_magic_api.h"
29 #include "SDL_image.h"
30 #include "SDL_mixer.h"
31
32 int BLIND_RADIUS = 16;
33 int BLIND_OPAQUE = 20;
34 int BLIND_THICKNESS = 30;
35 int blind_side; /* 0 top, 1 left, 2 bottom, 3 right */
36
37 static Uint8 blind_r, blind_g, blind_b, blind_light;
38 enum blind_sides
39 {
40 BLIND_SIDE_TOP,
41 BLIND_SIDE_LEFT,
42 BLIND_SIDE_BOTTOM,
43 BLIND_SIDE_RIGHT
44 };
45
46 enum blind_tools
47 {
48 BLIND_TOOL_BLIND,
49 BLIND_NUMTOOLS
50 };
51
52 Mix_Chunk *blind_snd;
53
54 // Prototypes
55 Uint32 blind_api_version(void);
56 void blind_set_color(magic_api * api, Uint8 r, Uint8 g, Uint8 b);
57 int blind_init(magic_api * api);
58 int blind_get_tool_count(magic_api * api);
59 SDL_Surface *blind_get_icon(magic_api * api, int which);
60 char *blind_get_name(magic_api * api, int which);
61 char *blind_get_description(magic_api * api, int which, int mode);
62 int blind_requires_colors(magic_api * api, int which);
63 void blind_release(magic_api * api, int which,
64 SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y, SDL_Rect * update_rect);
65 void blind_shutdown(magic_api * api);
66 void blind_paint_blind(void *ptr_to_api, int which_tool, SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y);
67 void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
68 SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect);
69 void blind_click(magic_api * api, int which, int mode,
70 SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect);
71 void blind_switchin(magic_api * api, int which, int mode, SDL_Surface * canvas);
72 void blind_switchout(magic_api * api, int which, int mode, SDL_Surface * canvas);
73 int blind_modes(magic_api * api, int which);
74
75 // Housekeeping functions
76
blind_api_version(void)77 Uint32 blind_api_version(void)
78 {
79 return (TP_MAGIC_API_VERSION);
80 }
81
blind_set_color(magic_api * api ATTRIBUTE_UNUSED,Uint8 r,Uint8 g,Uint8 b)82 void blind_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, Uint8 b) //get the colors from API and store it in structure
83 {
84 blind_r = r;
85 blind_g = g;
86 blind_b = b;
87 }
88
blind_init(magic_api * api)89 int blind_init(magic_api * api)
90 {
91 char fname[1024];
92
93 snprintf(fname, sizeof(fname), "%s/sounds/magic/blind.ogg", api->data_directory);
94 blind_snd = Mix_LoadWAV(fname);
95
96 return (1);
97 }
98
blind_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)99 int blind_get_tool_count(magic_api * api ATTRIBUTE_UNUSED)
100 {
101 return BLIND_NUMTOOLS;
102 }
103
blind_get_icon(magic_api * api,int which ATTRIBUTE_UNUSED)104 SDL_Surface *blind_get_icon(magic_api * api, int which ATTRIBUTE_UNUSED)
105 {
106 char fname[1024];
107
108 snprintf(fname, sizeof(fname), "%s/images/magic/blind.png", api->data_directory);
109
110 return (IMG_Load(fname));
111 }
112
blind_get_name(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)113 char *blind_get_name(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
114 {
115 return strdup(gettext_noop("Blind"));
116 }
117
blind_get_description(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED)118 char *blind_get_description(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
119 {
120 return
121 strdup(gettext_noop
122 ("Click towards the edge of your picture to pull window blinds over it. Move perpendicularly to open or close the blinds."));
123 }
124
blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)125 int blind_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
126 {
127 return 1;
128 }
129
blind_release(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED,SDL_Surface * snapshot ATTRIBUTE_UNUSED,int x ATTRIBUTE_UNUSED,int y ATTRIBUTE_UNUSED,SDL_Rect * update_rect ATTRIBUTE_UNUSED)130 void blind_release(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED,
131 SDL_Surface * canvas ATTRIBUTE_UNUSED, SDL_Surface * snapshot ATTRIBUTE_UNUSED,
132 int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect ATTRIBUTE_UNUSED)
133 {
134 }
135
blind_shutdown(magic_api * api ATTRIBUTE_UNUSED)136 void blind_shutdown(magic_api * api ATTRIBUTE_UNUSED)
137 {
138 Mix_FreeChunk(blind_snd);
139 }
140
141 // Interactivity functions
142
blind_paint_blind(void * ptr_to_api,int which_tool ATTRIBUTE_UNUSED,SDL_Surface * canvas,SDL_Surface * snapshot ATTRIBUTE_UNUSED,int x,int y)143 void blind_paint_blind(void *ptr_to_api, int which_tool ATTRIBUTE_UNUSED,
144 SDL_Surface * canvas, SDL_Surface * snapshot ATTRIBUTE_UNUSED, int x, int y)
145 {
146 magic_api *api = (magic_api *) ptr_to_api;
147
148 api->putpixel(canvas, x, y,
149 SDL_MapRGB(canvas->format, (blind_r + blind_light) / 2, (blind_g + blind_light) / 2,
150 (blind_b + blind_light) / 2));
151 }
152
153 /* void blind_do_blind(void * ptr_to_api, int which_tool,
154 SDL_Surface * canvas, SDL_Surface * snapshot, int x, int y)
155 {
156 magic_api * api = (magic_api *) ptr_to_api;
157
158 api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 128, 128, 165));
159 //api->putpixel(canvas, x, y, SDL_MapRGB(canvas->format, 0, 0, 255));
160 }
161
162 */
blind_drag(magic_api * api,int which,SDL_Surface * canvas,SDL_Surface * snapshot,int ox,int oy,int x,int y,SDL_Rect * update_rect)163 void blind_drag(magic_api * api, int which, SDL_Surface * canvas,
164 SDL_Surface * snapshot, int ox, int oy, int x, int y, SDL_Rect * update_rect)
165 {
166 int opaque;
167
168 SDL_BlitSurface(snapshot, NULL, canvas, NULL);
169 switch (blind_side)
170 {
171 int i, j;
172
173 case BLIND_SIDE_TOP:
174 opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
175 for (i = y; i >= 0; i -= BLIND_THICKNESS)
176 {
177 blind_light = 255;
178 for (j = i; j > i - opaque / 2; j--)
179 {
180 api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
181 blind_light -= 20;
182 }
183 for (j = i - opaque / 2; j > i - opaque; j--)
184 {
185 api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
186 blind_light += 20;
187 }
188 }
189 update_rect->x = 0;
190 update_rect->y = 0;
191 update_rect->w = canvas->w;
192 update_rect->h = max(oy, y);
193 api->playsound(blind_snd, 128, 255);
194 break;
195
196 case BLIND_SIDE_BOTTOM:
197 opaque = max((x * BLIND_THICKNESS) / canvas->w + 2, 2);
198 for (i = y; i <= canvas->h; i += BLIND_THICKNESS)
199 {
200 blind_light = 255;
201 for (j = i; j < i + opaque / 2; j++)
202 {
203 api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
204 blind_light -= 20;
205 }
206 for (j = i + opaque / 2; j < i + opaque; j++)
207 {
208 api->line(api, which, canvas, snapshot, 0, j, canvas->w, j, 1, blind_paint_blind);
209 blind_light += 20;
210 }
211 }
212
213 update_rect->x = 0;
214 update_rect->y = min(oy, y);
215 update_rect->w = canvas->w;
216 update_rect->h = canvas->h - update_rect->y;
217 api->playsound(blind_snd, 128, 255);
218 break;
219
220 case BLIND_SIDE_RIGHT:
221 opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
222 for (i = x; i <= canvas->w; i += BLIND_THICKNESS)
223 {
224 blind_light = 255;
225 for (j = i; j < i + opaque / 2; j++)
226 {
227 api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
228 blind_light -= 20;
229 }
230 for (j = i + opaque / 2; j < i + opaque; j++)
231 {
232 api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
233 blind_light += 20;
234 }
235 }
236
237 update_rect->x = min(ox, x);
238 update_rect->y = 0;
239 update_rect->w = canvas->w - update_rect->x;
240 update_rect->h = canvas->h;
241 api->playsound(blind_snd, (x * 255) / canvas->w, 255);
242 break;
243
244 case BLIND_SIDE_LEFT:
245 opaque = max((y * BLIND_THICKNESS) / canvas->h + 2, 2);
246 for (i = x; i >= 0; i -= BLIND_THICKNESS)
247 {
248 blind_light = 255;
249 for (j = i; j > i - opaque / 2; j--)
250 {
251 api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
252 blind_light -= 20;
253 }
254 for (j = i - opaque / 2; j > i - opaque; j--)
255 {
256 api->line(api, which, canvas, snapshot, j, 0, j, canvas->h, 1, blind_paint_blind);
257 blind_light += 20;
258 }
259 }
260 update_rect->x = 0;
261 update_rect->y = 0;
262 update_rect->w = max(ox, x);
263 update_rect->h = canvas->h;
264 api->playsound(blind_snd, (x * 255) / canvas->w, 255);
265 break;
266
267 }
268 }
269
blind_click(magic_api * api,int which,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas,SDL_Surface * last,int x,int y,SDL_Rect * update_rect)270 void blind_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED,
271 SDL_Surface * canvas, SDL_Surface * last, int x, int y, SDL_Rect * update_rect)
272 {
273 if (y < canvas->h / 2)
274
275 {
276 if (x < y)
277 blind_side = BLIND_SIDE_LEFT;
278 else if (canvas->w - x < y)
279 blind_side = BLIND_SIDE_RIGHT;
280 else
281 blind_side = BLIND_SIDE_TOP;
282 }
283 else
284 {
285 if (x < canvas->h - y)
286 blind_side = BLIND_SIDE_LEFT;
287 else if (canvas->w - x < canvas->h - y)
288 blind_side = BLIND_SIDE_RIGHT;
289 else
290 blind_side = BLIND_SIDE_BOTTOM;
291 }
292
293 blind_drag(api, which, canvas, last, x, y, x, y, update_rect);
294 }
295
blind_switchin(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED)296 void blind_switchin(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
297 SDL_Surface * canvas ATTRIBUTE_UNUSED)
298 {
299
300 }
301
blind_switchout(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED,int mode ATTRIBUTE_UNUSED,SDL_Surface * canvas ATTRIBUTE_UNUSED)302 void blind_switchout(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED,
303 SDL_Surface * canvas ATTRIBUTE_UNUSED)
304 {
305
306 }
307
blind_modes(magic_api * api ATTRIBUTE_UNUSED,int which ATTRIBUTE_UNUSED)308 int blind_modes(magic_api * api ATTRIBUTE_UNUSED, int which ATTRIBUTE_UNUSED)
309 {
310 return (MODE_FULLSCREEN | MODE_PAINT);
311 }
312