comparison src/paranormal-ng/general.c @ 2078:1fa3c8cd366a

paranormal-ng: a GL visualiser. lots to do, most stuff won't work, but hey, this will do cool stuff too soon
author William Pitcock <nenolod@atheme.org>
date Mon, 15 Oct 2007 06:20:13 -0500
parents
children 551862ab5d86
comparison
equal deleted inserted replaced
2077:e5b639ab62b0 2078:1fa3c8cd366a
1 /*
2 * paranormal: iterated pipeline-driven visualization plugin
3 * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
4 * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; under version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 /* FIXME: what to name this file? */
21
22 #include <config.h>
23
24 #include "paranormal.h"
25 #include "actuators.h"
26 #include "pn_utils.h"
27 #include "libcalc/calc.h"
28
29 /* **************** general_fade **************** */
30 static struct pn_actuator_option_desc general_fade_opts[] =
31 {
32 { "amount", "The amount by which the color index of each "
33 "pixel should be decreased by each frame (MAX 255)",
34 OPT_TYPE_INT, { ival: 3 } },
35 { NULL }
36 };
37
38 static void
39 general_fade_exec (const struct pn_actuator_option *opts,
40 gpointer data)
41 {
42 int amt = opts[0].val.ival > 255 || opts[0].val.ival < 0 ? 3 : opts[0].val.ival;
43 int i, j;
44
45 for (j=0; j<pn_image_data->height; j++)
46 for (i=0; i<pn_image_data->width; i++)
47 pn_image_data->surface[0][PN_IMG_INDEX (i, j)] =
48 CAPLO (pn_image_data->surface[0][PN_IMG_INDEX (i, j)]
49 - amt, 0);
50 }
51
52 struct pn_actuator_desc builtin_general_fade =
53 {
54 "general_fade", "Fade-out", "Decreases the color index of each pixel",
55 0, general_fade_opts,
56 NULL, NULL, general_fade_exec
57 };
58
59 /* **************** general_blur **************** */
60 /* FIXME: add a variable radius */
61 /* FIXME: SPEEEED */
62 static void
63 general_blur_exec (const struct pn_actuator_option *opts,
64 gpointer data)
65 {
66 int i,j;
67 register guchar *srcptr = pn_image_data->surface[0];
68 register guchar *destptr = pn_image_data->surface[1];
69 register int sum;
70
71 for (j=0; j<pn_image_data->height; j++)
72 for (i=0; i<pn_image_data->width; i++)
73 {
74 sum = *(srcptr)<<2;
75
76 /* top */
77 if (j > 0)
78 {
79 sum += *(srcptr-pn_image_data->width)<<1;
80 if (i > 0)
81 sum += *(srcptr-pn_image_data->width-1);
82 if (i < pn_image_data->width-1)
83 sum += *(srcptr-pn_image_data->width+1);
84 }
85 /* bottom */
86 if (j < pn_image_data->height-1)
87 {
88 sum += *(srcptr+pn_image_data->width)<<1;
89 if (i > 0)
90 sum += *(srcptr+pn_image_data->width-1);
91 if (i < pn_image_data->width-1)
92 sum += *(srcptr+pn_image_data->width+1);
93 }
94 /* left */
95 if (i > 0)
96 sum += *(srcptr-1)<<1;
97 /* right */
98 if (i < pn_image_data->width-1)
99 sum += *(srcptr+1)<<1;
100
101 *destptr++ = (guchar)(sum >> 4);
102 srcptr++;
103 }
104
105 pn_swap_surfaces ();
106 }
107
108 struct pn_actuator_desc builtin_general_blur =
109 {
110 "general_blur", "Blur", "A simple 1 pixel radius blur",
111 0, NULL,
112 NULL, NULL, general_blur_exec
113 };
114
115 /* **************** general_mosaic **************** */
116 /* FIXME: add a variable radius */
117 /* FIXME: SPEEEED */
118 static struct pn_actuator_option_desc general_mosaic_opts[] =
119 {
120 { "radius", "The pixel radius that should be used for the effect.",
121 OPT_TYPE_INT, { ival: 6 } },
122 { NULL }
123 };
124
125 static void
126 general_mosaic_exec (const struct pn_actuator_option *opts,
127 gpointer data)
128 {
129 int i,j;
130 register guchar *srcptr = pn_image_data->surface[0];
131 register guchar *destptr = pn_image_data->surface[1];
132 register int sum;
133 int radius = opts[0].val.ival > 255 || opts[0].val.ival < 0 ? 6 : opts[0].val.ival;
134
135 for (j=0; j<pn_image_data->height; j += radius)
136 for (i=0; i<pn_image_data->width; i += radius)
137 {
138 int ii = 0, jj = 0;
139 guchar bval = 0;
140
141 /* find the brightest colour */
142 for (jj = 0; jj < radius && (j + jj < pn_image_data->height); jj++)
143 for (ii = 0; ii < radius && (i + ii < pn_image_data->width); ii++)
144 {
145 guchar val = srcptr[PN_IMG_INDEX(i + ii, j + jj)];
146
147 if (val > bval)
148 bval = val;
149 }
150
151 for (jj = 0; jj < radius && (j + jj < pn_image_data->height); jj++)
152 for (ii = 0; ii < radius && (i + ii < pn_image_data->width); ii++)
153 {
154 destptr[PN_IMG_INDEX(i + ii, j + jj)] = bval;
155 }
156 }
157
158 pn_swap_surfaces ();
159 }
160
161 struct pn_actuator_desc builtin_general_mosaic =
162 {
163 "general_mosaic", "Mosaic", "A simple mosaic effect.",
164 0, general_mosaic_opts,
165 NULL, NULL, general_mosaic_exec
166 };
167
168 /* **************** general_clear **************** */
169 static void
170 general_clear_exec (const struct pn_actuator_option *opts,
171 gpointer data)
172 {
173 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
174 }
175
176 struct pn_actuator_desc builtin_general_clear =
177 {
178 "general_clear", "Clear Surface", "Clears the surface.",
179 0, NULL,
180 NULL, NULL, general_clear_exec
181 };
182
183 /* **************** general_noop **************** */
184 static void
185 general_noop_exec (const struct pn_actuator_option *opts,
186 gpointer data)
187 {
188 return;
189 }
190
191 struct pn_actuator_desc builtin_general_noop =
192 {
193 "general_noop", "Do Nothing", "Does absolutely nothing.",
194 0, NULL,
195 NULL, NULL, general_noop_exec
196 };
197
198 /* **************** general_invert **************** */
199 static void
200 general_invert_exec (const struct pn_actuator_option *opts,
201 gpointer data)
202 {
203 int i, j;
204
205 for (j=0; j < pn_image_data->height; j++)
206 for (i=0; i < pn_image_data->width; i++)
207 pn_image_data->surface[0][PN_IMG_INDEX (i, j)] =
208 255 - pn_image_data->surface[0][PN_IMG_INDEX (i, j)];
209 }
210
211 struct pn_actuator_desc builtin_general_invert =
212 {
213 "general_invert", "Value Invert", "Performs a value invert.",
214 0, NULL,
215 NULL, NULL, general_invert_exec
216 };
217
218 /* **************** general_replace **************** */
219 static struct pn_actuator_option_desc general_replace_opts[] =
220 {
221 { "start", "The beginning colour value that should be replaced by the value of out.",
222 OPT_TYPE_INT, { ival: 250 } },
223 { "end", "The ending colour value that should be replaced by the value of out.",
224 OPT_TYPE_INT, { ival: 255 } },
225 { "out", "The colour value that in is replaced with.",
226 OPT_TYPE_INT, { ival: 0 } },
227 { NULL }
228 };
229
230 static void
231 general_replace_exec (const struct pn_actuator_option *opts,
232 gpointer data)
233 {
234 register int i, j;
235 register guchar val;
236 guchar begin = opts[0].val.ival > 255 || opts[0].val.ival < 0 ? 250 : opts[0].val.ival;
237 guchar end = opts[1].val.ival > 255 || opts[1].val.ival < 0 ? 255 : opts[1].val.ival;
238 guchar out = opts[2].val.ival > 255 || opts[2].val.ival < 0 ? 0 : opts[2].val.ival;
239
240 for (j=0; j < pn_image_data->height; j++)
241 for (i=0; i < pn_image_data->width; i++)
242 {
243 val = pn_image_data->surface[0][PN_IMG_INDEX (i, j)];
244 if (val >= begin && val <= end)
245 pn_image_data->surface[0][PN_IMG_INDEX (i, j)] = out;
246 }
247 }
248
249 struct pn_actuator_desc builtin_general_replace =
250 {
251 "general_replace", "Value Replace", "Performs a value replace on a range of values.",
252 0, general_replace_opts,
253 NULL, NULL, general_replace_exec
254 };
255
256 /* **************** general_swap **************** */
257 static void
258 general_swap_exec (const struct pn_actuator_option *opts,
259 gpointer data)
260 {
261 pn_swap_surfaces ();
262 }
263
264 struct pn_actuator_desc builtin_general_swap =
265 {
266 "general_swap", "Swap Surface", "Swaps the surface.",
267 0, NULL,
268 NULL, NULL, general_swap_exec
269 };
270
271 /* **************** general_copy **************** */
272 static void
273 general_copy_exec (const struct pn_actuator_option *opts,
274 gpointer data)
275 {
276 memcpy(pn_image_data->surface[1], pn_image_data->surface[0],
277 (pn_image_data->width * pn_image_data->height));
278 }
279
280 struct pn_actuator_desc builtin_general_copy =
281 {
282 "general_copy", "Copy Surface", "Copies the surface to the other surface.",
283 0, NULL,
284 NULL, NULL, general_copy_exec
285 };
286
287 /* **************** general_flip **************** */
288 static struct pn_actuator_option_desc general_flip_opts[] =
289 {
290 { "direction", "Negative is horizontal, positive is vertical.",
291 OPT_TYPE_INT, { ival: -1 } },
292 { NULL }
293 };
294
295 static void
296 general_flip_exec (const struct pn_actuator_option *opts,
297 gpointer data)
298 {
299 gint x, y;
300
301 if (opts[0].val.ival < 0)
302 {
303 for (y = 0; y < pn_image_data->height; y++)
304 for (x = 0; x < pn_image_data->width; x++)
305 {
306 pn_image_data->surface[1][PN_IMG_INDEX(pn_image_data->width - x, y)] =
307 pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
308 }
309 }
310 else
311 {
312 for (y = 0; y < pn_image_data->height; y++)
313 for (x = 0; x < pn_image_data->width; x++)
314 {
315 pn_image_data->surface[1][PN_IMG_INDEX(x, pn_image_data->height - y)] =
316 pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
317 }
318 }
319
320 pn_swap_surfaces ();
321 }
322
323 struct pn_actuator_desc builtin_general_flip =
324 {
325 "general_flip", "Flip Surface", "Flips the surface.",
326 0, general_flip_opts,
327 NULL, NULL, general_flip_exec
328 };
329
330 /* ***************** general_evaluate ***************** */
331
332 static struct pn_actuator_option_desc general_evaluate_opts[] =
333 {
334 { "init_script", "Script to run on start.", OPT_TYPE_STRING, {sval: "global_reg0 = 27;"} },
335 { "frame_script", "Script to run.", OPT_TYPE_STRING, {sval: "global_reg0 = global_reg0 + 1;"} },
336 { NULL }
337 };
338
339 struct pn_evaluate_ctx
340 {
341 expression_t *expr_on_init, *expr_on_frame;
342 symbol_dict_t *dict;
343 gboolean reset;
344 };
345
346 static void
347 general_evaluate_init(gpointer *data)
348 {
349 *data = g_new0(struct pn_evaluate_ctx, 1);
350
351 ((struct pn_evaluate_ctx *)*data)->reset = TRUE;
352 }
353
354 static void
355 general_evaluate_cleanup(gpointer op_data)
356 {
357 struct pn_evaluate_ctx *data = (struct pn_evaluate_ctx *) op_data;
358
359 g_return_if_fail(data != NULL);
360
361 if (data->expr_on_init)
362 expr_free(data->expr_on_init);
363
364 if (data->expr_on_frame)
365 expr_free(data->expr_on_frame);
366
367 if (data->dict)
368 dict_free(data->dict);
369
370 if (data)
371 g_free(data);
372 }
373
374 static void
375 general_evaluate_exec(const struct pn_actuator_option *opts,
376 gpointer op_data)
377 {
378 struct pn_evaluate_ctx *data = (struct pn_evaluate_ctx *) op_data;
379
380 if (data->reset)
381 {
382 if (data->dict)
383 dict_free(data->dict);
384
385 data->dict = dict_new();
386
387 if (opts[0].val.sval != NULL);
388 data->expr_on_init = expr_compile_string(opts[0].val.sval, data->dict);
389
390 if (opts[1].val.sval != NULL);
391 data->expr_on_frame = expr_compile_string(opts[1].val.sval, data->dict);
392
393 if (data->expr_on_init != NULL)
394 expr_execute(data->expr_on_init, data->dict);
395
396 data->reset = FALSE;
397 }
398
399 if (data->expr_on_frame != NULL)
400 expr_execute(data->expr_on_frame, data->dict);
401 }
402
403 struct pn_actuator_desc builtin_general_evaluate =
404 {
405 "general_evaluate", "Evalulate VM Code",
406 "Evaluates arbitrary VM code. Does not draw anything.",
407 0, general_evaluate_opts,
408 general_evaluate_init, general_evaluate_cleanup, general_evaluate_exec
409 };
410