Mercurial > audlegacy-plugins
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 |