Mercurial > audlegacy-plugins
comparison src/paranormal/xform.c @ 333:afc61c0efc05 trunk
[svn] - add Trans / Movement implementation
author | nenolod |
---|---|
date | Tue, 05 Dec 2006 02:16:09 -0800 |
parents | a1517b09cb3a |
children | a9f1bd76a3e6 |
comparison
equal
deleted
inserted
replaced
332:626f9f4d79a8 | 333:afc61c0efc05 |
---|---|
12 #include <glib.h> | 12 #include <glib.h> |
13 | 13 |
14 #include "paranormal.h" | 14 #include "paranormal.h" |
15 #include "actuators.h" | 15 #include "actuators.h" |
16 #include "pn_utils.h" | 16 #include "pn_utils.h" |
17 | |
18 #include "libcalc/calc.h" | |
17 | 19 |
18 struct xform_vector | 20 struct xform_vector |
19 { | 21 { |
20 gint32 offset; /* the offset of the top left pixel */ | 22 gint32 offset; /* the offset of the top left pixel */ |
21 guint16 w; /* 4:4:4:4 NE, NW, SE, SW pixel weights | 23 guint16 w; /* 4:4:4:4 NE, NW, SE, SW pixel weights |
440 "xform_halfrender", "Halfrender Transform", | 442 "xform_halfrender", "Halfrender Transform", |
441 "Divides the surface in half and renders it twice.", | 443 "Divides the surface in half and renders it twice.", |
442 0, xform_halfrender_opts, | 444 0, xform_halfrender_opts, |
443 NULL, NULL, xform_halfrender_exec | 445 NULL, NULL, xform_halfrender_exec |
444 }; | 446 }; |
447 | |
448 /* **************** xform_movement **************** */ | |
449 struct pn_actuator_option_desc xform_movement_opts[] = | |
450 { | |
451 { "formula", "The formula to evaluate.", | |
452 OPT_TYPE_STRING, { sval: "d = 0.15;" } }, | |
453 { NULL } | |
454 }; | |
455 | |
456 typedef struct { | |
457 int width, height; /* Previous width and height. */ | |
458 struct xform_vector *vfield; | |
459 } PnMovementData; | |
460 | |
461 static void | |
462 xform_movement_init (gpointer *data) | |
463 { | |
464 *data = g_new0(PnMovementData, 1); | |
465 } | |
466 | |
467 static void | |
468 xform_movement_cleanup (gpointer data) | |
469 { | |
470 PnMovementData *d = (PnMovementData *) data; | |
471 | |
472 if (d) | |
473 { | |
474 if (d->vfield) | |
475 g_free (d->vfield); | |
476 g_free (d); | |
477 } | |
478 } | |
479 | |
480 static void | |
481 xform_movement_exec (const struct pn_actuator_option *opts, | |
482 gpointer odata) | |
483 { | |
484 PnMovementData *d = (PnMovementData *) odata; | |
485 | |
486 if (d->width != pn_image_data->width | |
487 || d->height != pn_image_data->height) | |
488 { | |
489 gint i, j; | |
490 gdouble *rf, *df; | |
491 gdouble xf, yf; | |
492 gint xn, yn; | |
493 expression_t *expr; | |
494 symbol_dict_t *dict; | |
495 | |
496 d->width = pn_image_data->width; | |
497 d->height = pn_image_data->height; | |
498 | |
499 if (d->vfield) | |
500 { | |
501 g_free (d->vfield); | |
502 d->vfield = NULL; | |
503 } | |
504 | |
505 if (opts[0].val.sval == NULL) | |
506 return; | |
507 | |
508 dict = dict_new(); | |
509 expr = expr_compile_string(opts[0].val.sval, dict); | |
510 if (!expr) | |
511 { | |
512 dict_free(dict); | |
513 return; | |
514 } | |
515 | |
516 rf = dict_variable(dict, "r"); | |
517 df = dict_variable(dict, "d"); | |
518 | |
519 d->vfield = g_malloc (sizeof(struct xform_vector) | |
520 * d->width * d->height); | |
521 | |
522 for (j = 0; j < pn_image_data->height; j++) | |
523 for (i = 0; i < pn_image_data->width; i++) | |
524 { | |
525 /* Points (xf, yf) must be in a (-1..1) square. */ | |
526 xf = 2.0 * i / (pn_image_data->width - 1) - 1.0; | |
527 yf = 2.0 * j / (pn_image_data->height - 1) - 1.0; | |
528 | |
529 /* Now, convert to polar coordinates r and d. */ | |
530 *rf = hypot(xf, yf); | |
531 *df = atan2(yf, xf); | |
532 | |
533 /* Run the script. */ | |
534 expr_execute(expr, dict); | |
535 | |
536 /* Back to (-1..1) square. */ | |
537 xf = (*rf) * cos ((*df)); | |
538 yf = (*rf) * sin ((*df)); | |
539 | |
540 /* Convert back to physical coordinates. */ | |
541 xn = (int)(((xf + 1.0) * (pn_image_data->width - 1) / 2) + 0.5); | |
542 yn = (int)(((yf + 1.0) * (pn_image_data->height - 1) / 2) + 0.5); | |
543 | |
544 if (xn < 0 || xn >= pn_image_data->width || yn < 0 || yn >= pn_image_data->height) | |
545 { | |
546 xn = i; yn = j; | |
547 } | |
548 | |
549 xfvec (xn, yn, &d->vfield[PN_IMG_INDEX (i, j)]); | |
550 } | |
551 } | |
552 | |
553 apply_xform (d->vfield); | |
554 pn_swap_surfaces (); | |
555 } | |
556 | |
557 struct pn_actuator_desc builtin_xform_movement = | |
558 { | |
559 "xform_movement", "Movement Transform", | |
560 "A customizable blitter.", | |
561 0, xform_movement_opts, | |
562 xform_movement_init, xform_movement_cleanup, xform_movement_exec | |
563 }; |