changeset 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 e5b639ab62b0
children 551862ab5d86
files src/paranormal-ng/.depend src/paranormal-ng/Makefile src/paranormal-ng/TODO src/paranormal-ng/actuators.c src/paranormal-ng/actuators.h src/paranormal-ng/beatdetect.c src/paranormal-ng/builtins.c src/paranormal-ng/cfg.c src/paranormal-ng/cmaps.c src/paranormal-ng/containers.c src/paranormal-ng/containers.h src/paranormal-ng/drawing.c src/paranormal-ng/drawing.h src/paranormal-ng/freq.c src/paranormal-ng/general.c src/paranormal-ng/libcalc/.depend src/paranormal-ng/libcalc/.deps src/paranormal-ng/libcalc/calc.h src/paranormal-ng/libcalc/dict.c src/paranormal-ng/libcalc/dict.h src/paranormal-ng/libcalc/execute.c src/paranormal-ng/libcalc/execute.h src/paranormal-ng/libcalc/function.c src/paranormal-ng/libcalc/function.h src/paranormal-ng/libcalc/parser.c src/paranormal-ng/libcalc/parser.h src/paranormal-ng/libcalc/parser.yacc src/paranormal-ng/libcalc/storage.c src/paranormal-ng/libcalc/storage.h src/paranormal-ng/misc.c src/paranormal-ng/paranormal.c src/paranormal-ng/paranormal.h src/paranormal-ng/plugin.c src/paranormal-ng/pn_utils.h src/paranormal-ng/presets.c src/paranormal-ng/presets.h src/paranormal-ng/presets/.depend src/paranormal-ng/presets/.depend-done src/paranormal-ng/presets/Makefile src/paranormal-ng/presets/aerdan_-_bloody_vortex.pnv src/paranormal-ng/presets/aerdan_-_cloudscape.pnv src/paranormal-ng/presets/aerdan_-_cloudscape2.pnv src/paranormal-ng/presets/aerdan_-_dancing_snow.pnv src/paranormal-ng/presets/aerdan_-_portal_to_hell.pnv src/paranormal-ng/presets/aerdan_-_stonervision.pnv src/paranormal-ng/presets/aerdan_-_telestatic.pnv src/paranormal-ng/presets/nazca_-_smoke_on_the_water.pnv src/paranormal-ng/presets/nenolod_-_3d_wave.pnv src/paranormal-ng/presets/nenolod_-_aquamarine_dream.pnv src/paranormal-ng/presets/nenolod_-_beatscope.pnv src/paranormal-ng/presets/nenolod_-_branchscope.pnv src/paranormal-ng/presets/nenolod_-_bumblebees.pnv src/paranormal-ng/presets/nenolod_-_cubism.pnv src/paranormal-ng/presets/nenolod_-_flying_into_pastels.pnv src/paranormal-ng/presets/nenolod_-_interlaced.pnv src/paranormal-ng/presets/nenolod_-_kaliedoscope.pnv src/paranormal-ng/presets/nenolod_-_phosphor_flame.pnv src/paranormal-ng/presets/nenolod_-_psuedo_starfield.pnv src/paranormal-ng/presets/nenolod_-_purple_flower.pnv src/paranormal-ng/presets/nenolod_-_quakingscope.pnv src/paranormal-ng/presets/nenolod_-_quasar.pnv src/paranormal-ng/presets/nenolod_-_retroscope.pnv src/paranormal-ng/presets/nenolod_-_rush.pnv src/paranormal-ng/presets/nenolod_-_scopefun.pnv src/paranormal-ng/presets/nenolod_-_simple_yet_pretty.pnv src/paranormal-ng/presets/nenolod_-_smoke.pnv src/paranormal-ng/presets/nenolod_-_swarm.pnv src/paranormal-ng/presets/nenolod_-_technicolour_nightmare.pnv src/paranormal-ng/presets/nenolod_-_transform_fun.pnv src/paranormal-ng/presets/nenolod_-_trapped.pnv src/paranormal-ng/presets/nenolod_-_tunnel_vision.pnv src/paranormal-ng/presets/nenolod_-_value_replace_fun.pnv src/paranormal-ng/presets/nenolod_-_worms.pnv src/paranormal-ng/presets/ticpu_-_colored_beat-o-scope.pnv src/paranormal-ng/wave.c src/paranormal-ng/xform.c
diffstat 72 files changed, 10953 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/Makefile	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,33 @@
+PLUGIN = paranormal-ng${PLUGIN_SUFFIX}
+
+SRCS = actuators.c		\
+       beatdetect.c		\
+       builtins.c		\
+       cfg.c			\
+       cmaps.c			\
+       containers.c		\
+       drawing.c		\
+       freq.c			\
+       general.c		\
+       misc.c			\
+       paranormal.c		\
+       plugin.c			\
+       presets.c		\
+       wave.c			\
+       xform.c			\
+       libcalc/dict.c		\
+       libcalc/execute.c	\
+       libcalc/function.c	\
+       libcalc/parser.c		\
+       libcalc/storage.c
+
+SUBDIRS = presets
+
+include ../../buildsys.mk
+include ../../extra.mk
+
+plugindir := ${plugindir}/${VISUALIZATION_PLUGIN_DIR}
+
+CFLAGS += ${PLUGIN_CFLAGS}
+CPPFLAGS += ${PLUGIN_CPPFLAGS} ${MOWGLI_CFLAGS} ${DBUS_CFLAGS} ${GTK_CFLAGS} ${GLIB_CFLAGS} ${PANGO_CFLAGS} ${ARCH_DEFINES} ${XML_CPPFLAGS} ${SDL_CFLAGS} -I../../intl -I../.. -I.
+LIBS += ${GTK_LIBS} ${GLIB_LIBS} ${PANGO_LIBS} ${XML_LIBS} ${SDL_LIBS} -lGL
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/TODO	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,13 @@
+More immediate points:
+
+- blend surface
+
+- container_stepped
+  executes <step> amount of instructions.. step increases or decreases 
+  on beat
+
+- container_repeat
+  executes the child instructions <step> amount of times.. step 
+  increases or decreases on beat
+
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/actuators.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,196 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include "actuators.h"
+//#include "containers.h"
+
+/* FIXME: container options override containees - fix this? */
+/* FIXME: add actuator groups (by a group name string) */
+
+/* FIXME: add support for copying containers' children (optionally) */
+struct pn_actuator *
+copy_actuator (const struct pn_actuator *a)
+{
+  struct pn_actuator *actuator;
+  int i;    
+
+  actuator = g_new (struct pn_actuator, 1);
+
+  actuator->desc = a->desc;
+
+  /* Make an options table */
+  if (actuator->desc->option_descs)
+    {
+      /* count the options */
+      for (i=0; actuator->desc->option_descs[i].name; i++);
+
+      actuator->options = g_new (struct pn_actuator_option, i + 1);
+      for (i=0; actuator->desc->option_descs[i].name; i++)
+	{
+	  actuator->options[i].desc = &actuator->desc->option_descs[i];
+
+	  /* copy the default options */
+	  switch (actuator->desc->option_descs[i].type)
+	    {
+	    case OPT_TYPE_INT:
+	    case OPT_TYPE_COLOR_INDEX:
+	    case OPT_TYPE_FLOAT:
+	    case OPT_TYPE_COLOR:
+	    case OPT_TYPE_BOOLEAN:
+	      memcpy (&actuator->options[i].val,
+		      &a->options[i].val,
+		      sizeof (union actuator_option_val));
+	      break;
+	    case OPT_TYPE_STRING:
+              actuator->options[i].val.sval = g_strdup(a->options[i].val.sval);
+              break;
+	    default:
+	      break;
+	    }
+	}
+
+      /* the NULL option */
+      actuator->options[i].desc = NULL;
+    }
+  else
+    actuator->options = NULL;
+
+  if (actuator->desc->init)
+    actuator->desc->init (&actuator->data);
+
+  return actuator;
+}
+
+struct pn_actuator_desc *
+get_actuator_desc (const char *name)
+{
+  int i;
+
+  for (i=0; builtin_table[i]; i++)
+    if (! g_strcasecmp (name, builtin_table[i]->name) || ! g_strcasecmp(name, builtin_table[i]->dispname))
+      break;
+
+  /* actuator not found */
+  if (! builtin_table[i])
+    return NULL;
+
+  return builtin_table[i];
+}
+
+struct pn_actuator *
+create_actuator (const char *name)
+{
+  int i;
+  struct pn_actuator_desc *desc;
+  struct pn_actuator *actuator;
+
+  /* find the actuatoreration */
+  desc = get_actuator_desc (name);
+
+  if (! desc)
+    return NULL;
+
+  actuator = g_new (struct pn_actuator, 1);
+  actuator->desc = desc;
+
+  /* Make an options table */
+  if (actuator->desc->option_descs)
+    {
+      /* count the options */
+      for (i=0; actuator->desc->option_descs[i].name != NULL; i++);
+
+      actuator->options = g_new0 (struct pn_actuator_option, i + 1);
+      for (i=0; actuator->desc->option_descs[i].name != NULL; i++)
+	{
+	  actuator->options[i].desc = &actuator->desc->option_descs[i];
+
+	  /* copy the default options */
+	  switch (actuator->desc->option_descs[i].type)
+	    {
+	    case OPT_TYPE_INT:
+	    case OPT_TYPE_COLOR_INDEX:
+	    case OPT_TYPE_FLOAT:
+	    case OPT_TYPE_COLOR:
+	    case OPT_TYPE_BOOLEAN:
+	      memcpy (&actuator->options[i].val,
+		      &actuator->desc->option_descs[i].default_val,
+		      sizeof (union actuator_option_val));
+	      break;
+	    case OPT_TYPE_STRING:
+	      /* NOTE: It's not realloc'ed so don't free it */
+	      actuator->options[i].val.sval =
+		actuator->desc->option_descs[i].default_val.sval;
+	      break;
+	    }
+	}
+
+      /* the NULL option */
+      actuator->options[i].desc = NULL;
+    }
+  else
+    actuator->options = NULL;
+
+  if (actuator->desc->init)
+    actuator->desc->init (&actuator->data);
+
+  return actuator;
+}
+
+void
+destroy_actuator (struct pn_actuator *actuator)
+{
+  int i;
+
+  if (actuator->desc->cleanup)
+    actuator->desc->cleanup (actuator->data);
+
+  /* find any option val's that need to be freed */
+  if (actuator->options)
+    for (i=0; actuator->options[i].desc; i++)
+      switch (actuator->options[i].desc->type)
+	{
+	case OPT_TYPE_INT:
+	case OPT_TYPE_FLOAT:
+	case OPT_TYPE_COLOR:
+	case OPT_TYPE_COLOR_INDEX:
+	case OPT_TYPE_BOOLEAN:
+	  break;
+	case OPT_TYPE_STRING:
+	  if (actuator->options[i].val.sval
+	      != actuator->options[i].desc->default_val.sval)
+	    g_free ((char *)actuator->options[i].val.sval);
+	}
+
+  g_free (actuator->options);
+  g_free (actuator);
+}
+
+void
+exec_actuator (struct pn_actuator *actuator)
+{
+  g_assert (actuator);
+  g_assert (actuator->desc);
+  g_assert (actuator->desc->exec);
+  actuator->desc->exec (actuator->options, actuator->data);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/actuators.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,117 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* FIXME: rename actuators to pn_actuators */
+/* FIXME: add a color type to the OPT_TYPE's */
+
+#ifndef _ACTUATORS_H
+#define _ACTUATORS_H
+
+#include <glib.h>
+#include <SDL.h>
+
+/* Helper macros for actuator functions */
+#define PN_ACTUATOR_INIT_FUNC(f) ((void (*) (gpointer *data))f)
+#define PN_ACTUATOR_CLEANUP_FUNC(f) ((void (*) (gpointer data))f)
+#define PN_ACTUATOR_EXEC_FUNC(f) \
+((void (*) (const struct pn_actuator_option *opts, gpointer data))f)
+
+struct pn_color
+{
+  guchar r, g, b, a;
+};
+
+
+union actuator_option_val
+{
+  int ival;
+  float fval;
+  const char *sval;
+  struct pn_color cval;
+  gboolean bval;
+};
+
+/* A actuator's option description */
+struct pn_actuator_option_desc
+{
+  const char *name;
+  const char *doc; /* option documentation */
+  enum
+  {
+    OPT_TYPE_INT = 0,
+    OPT_TYPE_FLOAT = 1,
+    OPT_TYPE_STRING = 2,
+    OPT_TYPE_COLOR = 3,
+    OPT_TYPE_COLOR_INDEX = 4, /* uses ival */
+    OPT_TYPE_BOOLEAN = 5
+  } type;
+  union actuator_option_val default_val;
+};
+
+/* The actual option instance */
+struct pn_actuator_option
+{
+  const struct pn_actuator_option_desc *desc;
+  union actuator_option_val val;
+};
+
+/* An operation's description */
+struct pn_actuator_desc
+{
+  const char *name;	/* e.g. "container_simple" */
+  const char *dispname;	/* e.g. "Simple Container" */
+  const char *doc; /* documentation txt */
+  const enum
+  {
+    ACTUATOR_FLAG_CONTAINER = 1<<0
+  } flags;
+
+  /* A null terminating (ie a actuator_option_desc == {0,...,0})
+     array - OPTIONAL (optional fields can be NULL) */
+  const struct pn_actuator_option_desc *option_descs;
+
+  /* Init function - data points to the actuator.data - OPTIONAL */
+  void (*init) (gpointer *data);
+  
+  /* Cleanup actuatortion - OPTIONAL */
+  void (*cleanup) (gpointer data);
+
+  /* Execute actuatortion - REQUIRED (duh!) */
+  void (*exec) (const struct pn_actuator_option *opts, gpointer data);
+};
+
+/* An actual operation instance */
+struct pn_actuator
+{
+  const struct pn_actuator_desc *desc;
+  struct pn_actuator_option *options;
+  gpointer data;
+};
+
+/* The array containing all operations (see builtins.c) */
+extern struct pn_actuator_desc *builtin_table[];
+
+/* functions for actuators */
+struct pn_actuator_desc *get_actuator_desc (const char *name);
+struct pn_actuator *copy_actuator (const struct pn_actuator *a);
+struct pn_actuator *create_actuator (const char *name);
+void destroy_actuator (struct pn_actuator *actuator);
+void exec_actuator (struct pn_actuator *actuator);
+
+#endif /* _ACTUATORS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/beatdetect.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,49 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "paranormal.h"
+
+/*
+ * This algorithm is by Janusz Gregorcyzk, the implementation is
+ * mine, however.
+ *
+ *   -- nenolod
+ */
+int
+pn_is_new_beat(void)
+{
+  gint i;
+  gint total = 0;
+  gboolean ret = FALSE;
+  static gint previous;
+
+  for (i = 1; i < 512; i++)
+    {
+       total += abs (pn_sound_data->pcm_data[0][i] -
+		     pn_sound_data->pcm_data[0][i - 1]);
+    }
+
+  total /= 512;
+
+  ret = (total > (2 * previous));
+
+  previous = total;
+
+  return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/builtins.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,121 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include "actuators.h"
+
+#define DECLARE_ACTUATOR(a) extern struct pn_actuator_desc builtin_##a;
+
+/* **************** containers **************** */
+
+DECLARE_ACTUATOR (container_simple);
+DECLARE_ACTUATOR (container_once);
+DECLARE_ACTUATOR (container_cycle);
+DECLARE_ACTUATOR (container_onbeat);
+
+/* **************** cmaps **************** */
+
+DECLARE_ACTUATOR (cmap_bwgradient);
+DECLARE_ACTUATOR (cmap_gradient);
+DECLARE_ACTUATOR (cmap_dynamic);
+
+/* **************** freq **************** */
+DECLARE_ACTUATOR (freq_dots);
+DECLARE_ACTUATOR (freq_drops);
+
+/* **************** general **************** */
+DECLARE_ACTUATOR (general_fade);
+DECLARE_ACTUATOR (general_blur);
+DECLARE_ACTUATOR (general_mosaic);
+DECLARE_ACTUATOR (general_clear);
+DECLARE_ACTUATOR (general_noop);
+DECLARE_ACTUATOR (general_invert);
+DECLARE_ACTUATOR (general_replace);
+DECLARE_ACTUATOR (general_swap);
+DECLARE_ACTUATOR (general_copy);
+DECLARE_ACTUATOR (general_flip);
+DECLARE_ACTUATOR (general_evaluate);
+
+/* **************** misc **************** */
+DECLARE_ACTUATOR (misc_floater);
+
+/* **************** wave **************** */
+DECLARE_ACTUATOR (wave_horizontal);
+DECLARE_ACTUATOR (wave_vertical);
+DECLARE_ACTUATOR (wave_normalize);
+DECLARE_ACTUATOR (wave_smooth);
+DECLARE_ACTUATOR (wave_radial);
+DECLARE_ACTUATOR (wave_scope);
+
+/* **************** xform **************** */
+DECLARE_ACTUATOR (xform_spin);
+DECLARE_ACTUATOR (xform_ripple);
+DECLARE_ACTUATOR (xform_bump_spin);
+DECLARE_ACTUATOR (xform_halfrender);
+DECLARE_ACTUATOR (xform_movement);
+DECLARE_ACTUATOR (xform_dynmovement);
+
+/* **************** builtin_table **************** */
+struct pn_actuator_desc *builtin_table[] =
+{
+  /* **************** containers **************** */
+  &builtin_container_simple,
+  &builtin_container_once,
+  &builtin_container_cycle,
+  &builtin_container_onbeat,
+
+  /* **************** cmaps **************** */
+  &builtin_cmap_bwgradient,
+  &builtin_cmap_gradient,
+  &builtin_cmap_dynamic,
+  /* **************** freq **************** */
+  &builtin_freq_dots,
+  &builtin_freq_drops,
+  /* **************** general **************** */
+  &builtin_general_fade,
+  &builtin_general_blur,
+  &builtin_general_mosaic,
+  &builtin_general_clear,
+  &builtin_general_noop,
+  &builtin_general_invert,
+  &builtin_general_replace,
+  &builtin_general_swap,
+  &builtin_general_copy,
+  &builtin_general_flip,
+  &builtin_general_evaluate,
+  /* **************** misc **************** */
+  &builtin_misc_floater,
+  /* **************** wave **************** */
+  &builtin_wave_horizontal,
+  &builtin_wave_vertical,
+  &builtin_wave_normalize,
+  &builtin_wave_smooth,
+  &builtin_wave_radial,
+  &builtin_wave_scope,
+  /* **************** xform **************** */
+  &builtin_xform_spin,
+  &builtin_xform_ripple,
+  &builtin_xform_bump_spin,
+  &builtin_xform_halfrender,
+  &builtin_xform_movement,
+  &builtin_xform_dynmovement,
+  /* **************** the end! **************** */
+  NULL
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/cfg.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,652 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* FIXME: prevent the user from dragging something above the root
+   actuator */
+
+#include <config.h>
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <audacious/plugin.h>
+
+#include <math.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "containers.h"
+#include "presets.h"
+
+/* DON'T CALL pn_fatal_error () IN HERE!!! */
+
+/* Actuator page stuffs */
+static GtkWidget *cfg_dialog, *actuator_tree, *option_frame, *actuator_option_table;
+static GtkWidget *actuator_add_opmenu, *actuator_add_button, *actuator_remove_button;
+static GtkCTreeNode *selected_actuator_node;
+static GtkTooltips *actuator_tooltips;
+
+/* This is used so that actuator_row_data_destroyed_cb won't free
+   the actuator associated w/ the node since we're going to be using it */
+gboolean destroy_row_data = TRUE;
+
+static void
+actuator_row_data_destroyed_cb (struct pn_actuator *a)
+{
+  if (a && destroy_row_data)
+    destroy_actuator (a);
+}
+
+static void
+add_actuator (struct pn_actuator *a, GtkCTreeNode *parent, gboolean copy)
+{
+  GtkCTreeNode *node;
+  GSList *l;
+
+  g_assert (cfg_dialog);
+  g_assert (actuator_tree);
+  g_assert (actuator_option_table);
+
+  node = gtk_ctree_insert_node (GTK_CTREE (actuator_tree), parent,
+				NULL, (gchar**)&a->desc->dispname, 0,
+				NULL, NULL, NULL, NULL,
+				a->desc->flags & ACTUATOR_FLAG_CONTAINER
+				? FALSE : TRUE,
+				TRUE);
+
+  if (a->desc->flags & ACTUATOR_FLAG_CONTAINER)
+    for (l=*(GSList **)a->data; l; l = l->next)
+      {
+	add_actuator (l->data, node, copy);
+      }
+
+  if (copy)
+    a = copy_actuator (a);
+  else if (a->desc->flags & ACTUATOR_FLAG_CONTAINER)
+    container_unlink_actuators (a);
+
+  gtk_ctree_node_set_row_data_full (GTK_CTREE (actuator_tree), node, a,
+				    ((GtkDestroyNotify) actuator_row_data_destroyed_cb));
+}
+
+static guchar
+gdk_colour_to_paranormal_colour(gint16 colour)
+{
+  return (guchar) (colour / 255);
+}
+
+static gint16
+paranormal_colour_to_gdk_colour(guchar colour)
+{
+  return (gint16) (colour * 255);
+}
+
+static void
+int_changed_cb (GtkSpinButton *sb, int *i)
+{
+  *i = gtk_spin_button_get_value_as_int (sb);
+}
+
+static void
+float_changed_cb (GtkSpinButton *sb, float *f)
+{
+  *f = gtk_spin_button_get_value_as_float (sb);
+}
+
+static void
+string_changed_cb (GtkEditable *t, char **s)
+{
+  if (*s != gtk_object_get_data (GTK_OBJECT (t), "DEFAULT_OP_STRING"))
+    g_free (*s);
+
+  *s = gtk_editable_get_chars (t, 0, -1);
+}
+
+static void
+color_changed_cb (GtkColorButton *cb, struct pn_color *c)
+{
+  GdkColor colour;
+
+  gtk_color_button_get_color(cb, &colour);
+
+  c->r = gdk_colour_to_paranormal_colour(colour.red);
+  c->g = gdk_colour_to_paranormal_colour(colour.green);
+  c->b = gdk_colour_to_paranormal_colour(colour.blue);
+}
+
+static void
+boolean_changed_cb (GtkToggleButton *tb, gboolean *b)
+{
+  *b = gtk_toggle_button_get_active (tb);
+}
+
+static void
+row_select_cb (GtkCTree *ctree, GtkCTreeNode *node,
+	       gint column, gpointer data)
+{
+  struct pn_actuator *a;
+  int opt_count = 0, i, j;
+  GtkWidget *w;
+  GtkObject *adj;
+
+  a = (struct pn_actuator *)gtk_ctree_node_get_row_data (ctree, node);
+
+  /* count the actuator's options (plus one) */
+  if (a->desc->option_descs)
+    while (a->desc->option_descs[opt_count++].name);
+  else
+    opt_count = 1;
+
+  gtk_table_resize (GTK_TABLE (actuator_option_table), opt_count, 2);
+
+  /* Actuator name */
+  gtk_frame_set_label (GTK_FRAME (option_frame), a->desc->dispname);
+
+  /* Actuator description */
+  w = gtk_label_new (a->desc->doc);
+  gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
+  gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT);
+  gtk_misc_set_alignment (GTK_MISC (w), 0, .5);
+  gtk_widget_show (w);
+  gtk_table_attach (GTK_TABLE (actuator_option_table), w, 0, 2, 0, 1,
+		    GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0,
+		    3, 3);
+
+  /* now add the options */
+  for (i=1, j=0; i<opt_count; j++, i++)
+    {
+      w = gtk_label_new (a->desc->option_descs[j].name);
+      gtk_widget_show (w);
+      gtk_table_attach (GTK_TABLE (actuator_option_table), w,
+			0, 1, i, i+1,
+			GTK_SHRINK | GTK_FILL, 0,
+			3, 3);
+      switch (a->desc->option_descs[j].type)
+	{
+	case OPT_TYPE_INT:
+	  adj = gtk_adjustment_new (a->options[j].val.ival,
+				    G_MININT, G_MAXINT,
+				    1, 2, 0);
+	  w = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, 0);
+	  gtk_signal_connect (GTK_OBJECT (w), "changed",
+			      GTK_SIGNAL_FUNC (int_changed_cb),
+			      &a->options[j].val.ival);
+	  break;
+	case OPT_TYPE_FLOAT:
+	  adj = gtk_adjustment_new (a->options[j].val.fval,
+				    -G_MAXFLOAT, G_MAXFLOAT,
+				    1, 2, 0);
+	  w = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, 5);
+	  gtk_signal_connect (GTK_OBJECT (w), "changed",
+			      GTK_SIGNAL_FUNC (float_changed_cb),
+			      &a->options[j].val.fval);
+	  break;
+	case OPT_TYPE_STRING:
+	  w = gtk_entry_new ();
+	  gtk_widget_show (w);
+	  gtk_entry_set_text (GTK_ENTRY (w), a->options[j].val.sval);
+	  gtk_object_set_data (GTK_OBJECT (w), "DEFAULT_OP_STRING",
+			       (gpointer)a->desc->option_descs[j].default_val.sval);
+	  gtk_signal_connect (GTK_OBJECT (w), "changed",
+			      GTK_SIGNAL_FUNC (string_changed_cb),
+			      &a->options[j].val.sval);
+	  break;
+	case OPT_TYPE_COLOR:
+	  {
+	    /* FIXME: add some color preview */
+            GdkColor *colour = g_new0(GdkColor, 1);
+
+            colour->red = paranormal_colour_to_gdk_colour(a->options[j].val.cval.r);
+            colour->green = paranormal_colour_to_gdk_colour(a->options[j].val.cval.g);
+            colour->blue = paranormal_colour_to_gdk_colour(a->options[j].val.cval.b);
+
+            w = gtk_color_button_new_with_color(colour);
+	    g_signal_connect(G_OBJECT (w), "color-set",
+			       G_CALLBACK (color_changed_cb),
+			       &a->options[j].val.cval);
+	    gtk_tooltips_set_tip (actuator_tooltips, GTK_WIDGET(w),
+				  a->desc->option_descs[j].doc, NULL);
+	  }
+	  break;	  
+	case OPT_TYPE_COLOR_INDEX:
+	  adj = gtk_adjustment_new (a->options[j].val.ival,
+				    0, 255,
+				    1, 2, 0);
+	  w = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, 0);
+	  gtk_signal_connect (GTK_OBJECT (w), "changed",
+			      GTK_SIGNAL_FUNC (int_changed_cb),
+			      &a->options[j].val.ival);
+	  break;
+	case OPT_TYPE_BOOLEAN:
+	  w = gtk_check_button_new ();
+	  gtk_widget_show (w);
+	  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w),
+					a->options[j].val.bval);
+	  gtk_signal_connect (GTK_OBJECT (w), "clicked",
+			      GTK_SIGNAL_FUNC (boolean_changed_cb),
+			      &a->options[j].val.bval);
+	  break;
+	}
+      gtk_widget_show (w);
+      gtk_tooltips_set_tip (actuator_tooltips, w,
+			    a->desc->option_descs[j].doc, NULL);
+      gtk_table_attach (GTK_TABLE (actuator_option_table), w,
+			1, 2, i, i+1,
+			GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+			0,
+			3, 3);
+    }
+
+  gtk_widget_set_sensitive (actuator_remove_button, TRUE);
+  gtk_widget_set_sensitive (actuator_add_button, a->desc->flags & ACTUATOR_FLAG_CONTAINER
+			? TRUE : FALSE);
+
+  selected_actuator_node = node;
+}
+
+static void
+table_remove_all_cb (GtkWidget *widget, gpointer data)
+{
+  gtk_container_remove (GTK_CONTAINER (actuator_option_table),
+			widget);
+}
+
+static void
+row_unselect_cb (GtkCTree *ctree, GList *node, gint column,
+		 gpointer user_data)
+{
+  gtk_frame_set_label (GTK_FRAME (option_frame), NULL);
+
+  gtk_container_foreach (GTK_CONTAINER (actuator_option_table),
+			 table_remove_all_cb, NULL);
+
+  /* Can't remove something if nothing's selected */
+  gtk_widget_set_sensitive (actuator_remove_button, FALSE);
+
+  selected_actuator_node = NULL;
+}
+
+static void
+add_actuator_cb (GtkButton *button, gpointer data)
+{
+  char *actuator_name;
+  struct pn_actuator *a;
+  
+  gtk_label_get (GTK_LABEL (GTK_BIN (actuator_add_opmenu)->child),
+                &actuator_name);
+
+  a = create_actuator (actuator_name);
+  g_assert (a);
+
+  add_actuator (a, selected_actuator_node, FALSE);
+}
+
+static void
+remove_actuator_cb (GtkButton *button, gpointer data)
+{
+  if (selected_actuator_node)
+    gtk_ctree_remove_node (GTK_CTREE (actuator_tree),
+			   selected_actuator_node);
+}
+
+/* Connect a node to its parent and replace the row data with
+   a copy of the node */
+static void
+connect_actuators_cb (GtkCTree *ctree, GtkCTreeNode *node,
+		      struct pn_actuator **root_ptr)
+{
+  struct pn_actuator *actuator, *parent, *copy;
+
+  actuator = (struct pn_actuator *) gtk_ctree_node_get_row_data (ctree, node);
+  if (GTK_CTREE_ROW (node)->parent)
+    {
+      /* Connect it to the parent */
+      parent = (struct pn_actuator *)
+	gtk_ctree_node_get_row_data (ctree, GTK_CTREE_ROW (node)->parent);
+      container_add_actuator (parent, actuator);
+    }
+  else
+    /* This is the root node; still gotta copy it, but we need to
+       save the original to *root_ptr */
+    *root_ptr = actuator;
+
+  /* we don't want our copy getting destroyed */
+  destroy_row_data = FALSE;
+
+  copy = copy_actuator (actuator);
+  gtk_ctree_node_set_row_data_full (ctree, node, copy,
+				    ((GtkDestroyNotify)actuator_row_data_destroyed_cb));
+
+  /* Ok, now you can destroy it */
+  destroy_row_data = TRUE;
+}
+
+/* Extract (and connect) the actuators in the tree */
+static struct pn_actuator *
+extract_actuator (void)
+{
+  GtkCTreeNode *root, *selected;
+  struct pn_actuator *root_actuator = NULL;
+
+  root = gtk_ctree_node_nth (GTK_CTREE (actuator_tree), 0);
+  if (root)
+    gtk_ctree_post_recursive (GTK_CTREE (actuator_tree), root,
+			      GTK_CTREE_FUNC (connect_actuators_cb),
+			      &root_actuator);
+
+  if (selected_actuator_node)
+    {
+      selected = selected_actuator_node;
+      gtk_ctree_unselect (GTK_CTREE (actuator_tree), GTK_CTREE_NODE (selected));
+      gtk_ctree_select (GTK_CTREE (actuator_tree), GTK_CTREE_NODE (selected));
+    }
+
+  return root_actuator;
+}
+
+/* If selector != NULL, then it's 'OK', otherwise it's 'Cancel' */
+static void
+load_sel_cb (GtkButton *button, GtkFileSelection *selector)
+{
+  if (selector)
+    {
+      static const char *fname;
+      struct pn_actuator *a;
+      GtkCTreeNode *root;
+      ConfigDb *db;
+
+      db = bmp_cfg_db_open();
+      fname = (char *) gtk_file_selection_get_filename (selector);
+      a = load_preset (fname);
+      bmp_cfg_db_set_string(db, "paranormal", "last_path", (char*)fname);
+      bmp_cfg_db_close(db);
+      if (! a)
+	pn_error ("Unable to load file: \"%s\"", fname);
+      else
+	{
+	  if ((root = gtk_ctree_node_nth (GTK_CTREE (actuator_tree), 0)))
+	    gtk_ctree_remove_node (GTK_CTREE (actuator_tree), root);
+	  add_actuator (a, NULL, FALSE);
+	}
+    }
+
+  gtk_widget_set_sensitive (cfg_dialog, TRUE);
+}
+
+static void
+load_button_cb (GtkButton *button, gpointer data)
+{
+  GtkWidget *selector;
+  ConfigDb *db;
+  gchar *last_path;
+
+  db = bmp_cfg_db_open();
+  selector = gtk_file_selection_new ("Load Preset");
+  if(bmp_cfg_db_get_string(db, "paranormal", "last_path", &last_path)) {
+     gtk_file_selection_set_filename(GTK_FILE_SELECTION(selector), last_path);
+  }
+  bmp_cfg_db_close(db);
+
+  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
+		      "clicked", GTK_SIGNAL_FUNC (load_sel_cb), selector);
+  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
+		      "clicked", GTK_SIGNAL_FUNC (load_sel_cb), NULL);
+
+  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
+			     "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+			     (gpointer) selector);
+  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
+			     "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+			     (gpointer) selector);
+
+  gtk_widget_set_sensitive (cfg_dialog, FALSE);
+  gtk_widget_show (selector);
+}
+
+static void
+save_sel_cb (GtkButton *button, GtkFileSelection *selector)
+{
+  if (selector)
+    {
+      const char *fname;
+      struct pn_actuator *a;
+
+      fname = (char *) gtk_file_selection_get_filename (selector);
+      a = extract_actuator ();
+
+      if (! save_preset (fname, a))
+	pn_error ("unable to save preset to file: %s", fname);
+    }
+
+  gtk_widget_set_sensitive (cfg_dialog, TRUE);
+}
+
+static void
+save_button_cb (GtkButton *button, gpointer data)
+{
+  GtkWidget *selector;
+
+  selector = gtk_file_selection_new ("Save Preset");
+
+  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
+		      "clicked", GTK_SIGNAL_FUNC (save_sel_cb), selector);
+  gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
+		      "clicked", GTK_SIGNAL_FUNC (save_sel_cb), NULL);
+
+  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->ok_button),
+			     "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+			     (gpointer) selector);
+  gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (selector)->cancel_button),
+			     "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
+			     (gpointer) selector);
+
+  gtk_widget_set_sensitive (cfg_dialog, FALSE);
+  gtk_widget_show (selector);
+}
+
+static void
+apply_settings (void)
+{
+  struct pn_rc rc;
+
+  rc.actuator = extract_actuator ();
+
+  pn_set_rc (&rc);
+}
+
+static void
+apply_button_cb (GtkButton *button, gpointer data)
+{
+  apply_settings ();
+}
+
+static void
+ok_button_cb (GtkButton *button, gpointer data)
+{
+  apply_settings ();
+  gtk_widget_hide (cfg_dialog);
+}
+
+static void
+cancel_button_cb (GtkButton *button, gpointer data)
+{
+  gtk_widget_destroy (cfg_dialog);
+  cfg_dialog = NULL;
+}
+
+void
+pn_configure (void)
+{
+  GtkWidget *notebook, *label, *scrollwindow, *menu, *menuitem;
+  GtkWidget *paned, *vbox, *table, *bbox, *button;
+  int i;
+  
+
+  if (! cfg_dialog)
+    {
+      /* The dialog */
+      cfg_dialog = gtk_dialog_new ();
+      gtk_window_set_title (GTK_WINDOW (cfg_dialog), "Paranormal Visualization Studio - Editor");
+      gtk_widget_set_usize (cfg_dialog, 530, 370);
+      gtk_container_border_width (GTK_CONTAINER (cfg_dialog), 8);
+      gtk_signal_connect_object (GTK_OBJECT (cfg_dialog), "delete-event",
+				 GTK_SIGNAL_FUNC (gtk_widget_hide),
+				 GTK_OBJECT (cfg_dialog));
+
+      /* The notebook */
+      notebook = gtk_notebook_new ();
+      gtk_widget_show (notebook);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cfg_dialog)->vbox), notebook,
+			  TRUE, TRUE, 0);
+
+      /* Actuator page */
+      paned = gtk_hpaned_new ();
+      gtk_widget_show (paned);
+      label = gtk_label_new ("Actuators");
+      gtk_widget_show (label);
+      gtk_notebook_append_page (GTK_NOTEBOOK (notebook), paned, label);
+      vbox = gtk_vbox_new (FALSE, 3);
+      gtk_widget_show (vbox);
+      gtk_paned_pack1 (GTK_PANED (paned), vbox, TRUE, FALSE);
+      scrollwindow = gtk_scrolled_window_new (NULL, NULL);
+      gtk_widget_show (scrollwindow);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwindow),
+				      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+      gtk_box_pack_start (GTK_BOX (vbox), scrollwindow, TRUE, TRUE, 3);
+      actuator_tree = gtk_ctree_new (1, 0);
+      gtk_widget_show (actuator_tree);
+      gtk_ctree_set_reorderable (GTK_CTREE (actuator_tree), TRUE);
+      gtk_signal_connect (GTK_OBJECT (actuator_tree), "tree-select-row",
+			  GTK_SIGNAL_FUNC (row_select_cb), NULL);
+      gtk_signal_connect (GTK_OBJECT (actuator_tree), "tree-unselect-row",
+			  GTK_SIGNAL_FUNC (row_unselect_cb), NULL);
+      gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwindow),
+					     actuator_tree);
+      table = gtk_table_new (3, 2, TRUE);
+      gtk_widget_show (table);
+      gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 3);      
+      actuator_add_opmenu = gtk_option_menu_new ();
+      gtk_widget_show (actuator_add_opmenu);
+      menu = gtk_menu_new ();
+      gtk_widget_show (menu);
+      for (i=0; builtin_table[i]; i++)
+	{
+	  /* FIXME: Add actuator group support */
+	  menuitem = gtk_menu_item_new_with_label (builtin_table[i]->dispname);
+	  gtk_widget_show (menuitem);
+	  gtk_menu_append (GTK_MENU (menu), menuitem);
+	}
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (actuator_add_opmenu), menu);
+      gtk_table_attach (GTK_TABLE (table), actuator_add_opmenu,
+			0, 2, 0, 1,
+			GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0,
+			3, 3);
+      actuator_add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+      gtk_widget_show (actuator_add_button);
+      gtk_signal_connect (GTK_OBJECT (actuator_add_button), "clicked",
+			  GTK_SIGNAL_FUNC (add_actuator_cb), NULL);
+      gtk_table_attach (GTK_TABLE (table), actuator_add_button,
+			0, 1, 1, 2,
+			GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0,
+			3, 3);
+      actuator_remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+      gtk_widget_set_sensitive (actuator_remove_button, FALSE);
+      gtk_widget_show (actuator_remove_button);
+      gtk_signal_connect (GTK_OBJECT (actuator_remove_button), "clicked",
+			  GTK_SIGNAL_FUNC (remove_actuator_cb), NULL);
+      gtk_table_attach (GTK_TABLE (table), actuator_remove_button,
+			1, 2, 1, 2,
+			GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0,
+			3, 3);
+      button = gtk_button_new_from_stock(GTK_STOCK_OPEN);
+      gtk_widget_show (button);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+			  GTK_SIGNAL_FUNC (load_button_cb), NULL);
+      gtk_table_attach (GTK_TABLE (table), button,
+			0, 1, 2, 3,
+			GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0,
+			3, 3);
+      button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
+      gtk_widget_show (button);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+			  GTK_SIGNAL_FUNC (save_button_cb), NULL);
+      gtk_table_attach (GTK_TABLE (table), button,
+			1, 2, 2, 3,
+			GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0,
+			3, 3);
+
+      /* Option table */
+      option_frame = gtk_frame_new (NULL);
+      gtk_widget_show (option_frame);
+      gtk_container_set_border_width (GTK_CONTAINER (option_frame), 3);
+      gtk_paned_pack2 (GTK_PANED (paned), option_frame, TRUE, TRUE);
+      scrollwindow = gtk_scrolled_window_new (NULL, NULL);
+      gtk_widget_show (scrollwindow);
+      gtk_container_set_border_width (GTK_CONTAINER (scrollwindow), 3);
+      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwindow),
+				      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+      gtk_container_add (GTK_CONTAINER (option_frame), scrollwindow);
+      actuator_option_table = gtk_table_new (0, 2, FALSE);
+      gtk_widget_show (actuator_option_table);
+      gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwindow),
+					     actuator_option_table);
+      gtk_paned_set_position (GTK_PANED (paned), 0);
+      actuator_tooltips = gtk_tooltips_new ();
+      gtk_tooltips_enable (actuator_tooltips);
+
+      /* Build the initial actuator actuator_tree */
+      if (pn_rc->actuator)
+	{
+	  add_actuator (pn_rc->actuator, NULL, TRUE);
+	  gtk_widget_set_sensitive (actuator_add_button, FALSE);
+	}
+
+      /* OK / Apply / Cancel */
+      bbox = gtk_hbutton_box_new ();
+      gtk_widget_show (bbox);
+      gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+      gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 8);
+      gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 64, 0);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cfg_dialog)->action_area),
+			  bbox, FALSE, FALSE, 0);
+
+      button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+      gtk_widget_show (button);
+      gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+			  GTK_SIGNAL_FUNC (cancel_button_cb), NULL);
+      gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+
+      button = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+      gtk_widget_show (button);
+      gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+			  GTK_SIGNAL_FUNC (apply_button_cb), NULL);
+      gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+
+      button = gtk_button_new_from_stock (GTK_STOCK_OK);
+      gtk_widget_show (button);
+      gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NORMAL);
+      gtk_signal_connect (GTK_OBJECT (button), "clicked",
+			  GTK_SIGNAL_FUNC (ok_button_cb), NULL);
+      gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+    }
+
+  gtk_widget_show (cfg_dialog);
+  gtk_widget_grab_focus (cfg_dialog);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/cmaps.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,202 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+
+#include "libcalc/calc.h"
+
+#define STD_CMAP_OPTS { "low_index", "The lowest index of the \
+color map that should be altered", OPT_TYPE_COLOR_INDEX, { ival: 0 } },\
+{ "high_index", "The highest index of the color map that should be \
+altered", OPT_TYPE_COLOR_INDEX, { ival: 255 } }
+
+static struct pn_color black = {0, 0, 0};
+static struct pn_color white = {255, 255, 255};
+
+/* **************** cmap generation funcs **************** */
+static void
+cmap_gen_gradient (int step, const struct pn_color *a,
+		   const struct pn_color *b,
+		   struct pn_color *c)
+{
+  c->r = a->r + step * ((((float)b->r) - ((float)a->r)) / 256.0);
+  c->g = a->g + step * ((((float)b->g) - ((float)a->g)) / 256.0);
+  c->b = a->b + step * ((((float)b->b) - ((float)a->b)) / 256.0);
+}
+
+/* **************** cmap_gradient **************** */
+static struct pn_actuator_option_desc cmap_gradient_opts[] =
+{
+  STD_CMAP_OPTS,
+  { "lcolor", "The low color used in the gradient generation",
+    OPT_TYPE_COLOR, { cval: {0, 0, 0} } },
+  { "hcolor", "The high color used in the gradient generation",
+    OPT_TYPE_COLOR, { cval: {0, 0, 0} } },
+  { NULL }
+};
+
+static void
+cmap_gradient_exec (const struct pn_actuator_option *opts,
+		    gpointer data)
+{
+  int i;
+
+  for (i=opts[0].val.ival; i<=opts[1].val.ival; i++)
+    cmap_gen_gradient (((i-opts[0].val.ival)<<8)/(opts[1].val.ival
+						  - opts[0].val.ival),
+		       &opts[2].val.cval, &opts[3].val.cval,
+		       &pn_image_data->cmap[i]);
+}
+
+struct pn_actuator_desc builtin_cmap_gradient =
+{
+  "cmap_gradient",
+  "Normal colourmap",
+  "Sets the colormap to a gradient going from <lcolor> to "
+  "<hcolor>",
+  0, cmap_gradient_opts,
+  NULL, NULL, cmap_gradient_exec
+};
+
+/* **************** cmap_bwgradient **************** */
+static struct pn_actuator_option_desc cmap_bwgradient_opts[] =
+{
+  STD_CMAP_OPTS,
+  { "color", "The intermediate color to use in the gradient",
+    OPT_TYPE_COLOR, { cval: {191, 191, 191} } },
+  { NULL }
+};
+
+static void
+cmap_bwgradient_exec (const struct pn_actuator_option *opts,
+		      gpointer data)
+{
+  int i;
+
+  for (i=opts[0].val.ival; i<128 && i<=opts[1].val.ival; i++)
+    cmap_gen_gradient (i<<1, &black, &opts[2].val.cval,
+		       &pn_image_data->cmap[i]);
+
+  for (i=128; i<256 && i<=opts[1].val.ival; i++)
+    cmap_gen_gradient ((i-128)<<1, &opts[2].val.cval, &white,
+		       &pn_image_data->cmap[i]);
+}
+    
+struct pn_actuator_desc builtin_cmap_bwgradient =
+{
+  "cmap_bwgradient",
+  "Value-based colourmap",
+  "Sets the colormap to a gradient going from black to "
+  "white, via an intermediate color",
+  0, cmap_bwgradient_opts,
+  NULL, NULL, cmap_bwgradient_exec
+};
+
+/* **************** cmap_dynamic **************** */
+static struct pn_actuator_option_desc cmap_dynamic_opts[] =
+{
+  STD_CMAP_OPTS,
+  { "script", "The script to run on each step.",
+    OPT_TYPE_STRING, { sval: "red = red + 0.01; blue = blue + 0.01; green = green + 0.01;" } },
+  { NULL }
+};
+
+typedef struct {
+  expression_t *expr;
+  symbol_dict_t *dict;
+} PnDynamicColourmapData;
+
+static void
+cmap_dynamic_init(gpointer *data)
+{
+  *data = g_new0(PnDynamicColourmapData, 1);
+}
+
+static void
+cmap_dynamic_cleanup(gpointer data)
+{
+  PnDynamicColourmapData *d = (PnDynamicColourmapData *) data;
+
+  if (d->expr)
+    expr_free(d->expr);
+  if (d->dict)
+    dict_free(d->dict);
+
+  g_free(d);
+}
+
+static void
+cmap_dynamic_exec(const struct pn_actuator_option *opts,
+		  gpointer data)
+{
+  PnDynamicColourmapData *d = (PnDynamicColourmapData *) data;
+  gint i, j;
+  gdouble *rf, *bf, *gf, *inf;
+  gint rn, bn, gn;
+
+  if (!d->dict && !d->expr)
+    {
+       d->dict = dict_new();
+       if (!d->dict)
+         return;
+
+       d->expr = expr_compile_string(opts[2].val.sval, d->dict);
+       if (!d->expr)
+         {
+           dict_free(d->dict);
+           d->dict = NULL;
+           return;
+         }
+    }
+
+  rf = dict_variable(d->dict, "red");
+  gf = dict_variable(d->dict, "green");
+  bf = dict_variable(d->dict, "blue");
+  inf = dict_variable(d->dict, "index");
+
+  for (i = opts[0].val.ival; i < 255 && i <= opts[1].val.ival; i++)
+    {
+       *inf = ((gdouble)i / 255.0);
+
+       expr_execute(d->expr, d->dict);
+
+       /* Convert rf/bf/gf to realworld values. */
+       rn = (gdouble)(*rf * 255);
+       gn = (gdouble)(*gf * 255);
+       bn = (gdouble)(*bf * 255);
+
+       pn_image_data->cmap[i].r = rn;
+       pn_image_data->cmap[i].g = gn;
+       pn_image_data->cmap[i].b = bn;
+    }
+}
+
+struct pn_actuator_desc builtin_cmap_dynamic =
+{
+  "cmap_dynamic",
+  "Dynamic Colourmap",
+  "Scriptable colourmap modifier.",
+  0, cmap_dynamic_opts,
+  cmap_dynamic_init, cmap_dynamic_cleanup, cmap_dynamic_exec
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/containers.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,267 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <glib.h>
+
+#include "actuators.h"
+#include "paranormal.h"
+
+/* **************** all containers **************** */
+
+/* Add a actuator to a container (end of list) */
+void
+container_add_actuator (struct pn_actuator *container, struct pn_actuator *a)
+{
+  g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER);
+  g_assert (a);
+
+  *((GSList **)container->data) =
+    g_slist_append (*(GSList **)container->data, a);
+}  
+
+void
+container_remove_actuator (struct pn_actuator *container, struct pn_actuator *a)
+{
+  g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER);
+  g_assert (a);
+
+  *((GSList **)container->data) =
+    g_slist_remove (*(GSList **)container->data, a);
+} 
+
+/* clear the containee list */
+void
+container_unlink_actuators (struct pn_actuator *container)
+{
+  g_assert (container->desc->flags & ACTUATOR_FLAG_CONTAINER);
+
+  g_slist_free (*(GSList **)container->data);
+  *(GSList **)container->data = NULL;
+}
+
+/* this does NOT free data */
+static void
+container_cleanup (GSList** data)
+{
+  GSList *child;
+
+  for (child = *data; child; child = child->next)
+    destroy_actuator ((struct pn_actuator *) child->data);
+
+  g_slist_free (*data);
+}
+
+/* **************** container_simple **************** */
+static void
+container_simple_init (GSList ***data)
+{
+  *data = g_new0 (GSList *, 1);
+}
+
+static void
+container_simple_cleanup (GSList **data)
+{
+  container_cleanup (data);
+  g_free (data);
+}
+
+static void
+container_simple_exec (const struct pn_actuator_option *opts,
+		     GSList **data)
+{
+  GSList *child;
+
+  for (child = *data; child; child = child->next)
+    exec_actuator ((struct pn_actuator *) child->data);
+}
+
+struct pn_actuator_desc builtin_container_simple =
+{
+  "container_simple",
+  "Simple Container",
+  "A simple (unconditional) container\n\n"
+  "This is usually used as the root actuator of a list",
+  ACTUATOR_FLAG_CONTAINER, NULL,
+  PN_ACTUATOR_INIT_FUNC (container_simple_init),
+  PN_ACTUATOR_CLEANUP_FUNC (container_simple_cleanup),
+  PN_ACTUATOR_EXEC_FUNC (container_simple_exec)
+};
+
+/* **************** container_once **************** */
+struct container_once_data
+{
+  GSList *children; /* This MUST be first! */
+
+  gboolean done;
+};
+
+static void
+container_once_init (struct container_once_data **data)
+{
+  *data = g_new0 (struct container_once_data, 1);
+}
+
+static void
+container_once_cleanup (GSList **data)
+{
+  container_cleanup (data);
+  g_free (data);
+}
+
+static void
+container_once_exec (const struct pn_actuator_option *opts,
+		     struct container_once_data *data)
+{
+  if (! data->done)
+    {
+      GSList *child;
+
+      for (child = data->children; child; child = child->next)
+	exec_actuator ((struct pn_actuator *) child->data);
+
+      data->done = TRUE;
+    }
+}
+
+struct pn_actuator_desc builtin_container_once =
+{
+  "container_once",
+  "Initialization Container",
+  "A container whose contents get executed exactly once.\n\n"
+  "This is often used to set initial graphics states such as the\n"
+  "pixel depth, or to display some text (such as credits)",
+  ACTUATOR_FLAG_CONTAINER, NULL,
+  PN_ACTUATOR_INIT_FUNC (container_once_init),
+  PN_ACTUATOR_CLEANUP_FUNC (container_once_cleanup),
+  PN_ACTUATOR_EXEC_FUNC (container_once_exec)
+};
+
+/* **************** container_cycle ***************** */
+static struct pn_actuator_option_desc container_cycle_opts[] =
+{
+  { "change_interval", "The number of seconds between changing the "
+    "child to be executed", OPT_TYPE_INT, { ival: 20 } },
+  { "beat", "Whether or not the change should only occur on a beat",
+    OPT_TYPE_BOOLEAN, { bval: TRUE } },
+  { NULL }
+};
+
+struct container_cycle_data
+{
+  GSList *children;
+  GSList *current;
+  int last_change;
+};
+
+static void
+container_cycle_init (gpointer *data)
+{
+  *data = g_new0 (struct container_cycle_data, 1);
+}
+
+static void
+container_cycle_cleanup (gpointer data)
+{
+  container_cleanup (data);
+  g_free (data);
+}
+
+static void
+container_cycle_exec (const struct pn_actuator_option *opts,
+		      gpointer data)
+{
+  struct container_cycle_data *cdata = (struct container_cycle_data*)data;
+  int now;
+
+  /*
+   * Change branch if all of the requirements are met for the branch to change.
+   */
+  if ((opts[1].val.bval == TRUE && pn_new_beat != FALSE) || opts[1].val.bval == FALSE)
+    {
+       now = SDL_GetTicks();	
+
+       if (now - cdata->last_change
+           > opts[0].val.ival * 1000)
+         {
+            cdata->last_change = now;
+
+            /* FIXME: add randomization support */
+            if (cdata->current)
+              cdata->current = cdata->current->next;
+         }
+    }
+
+  if (! cdata->current)
+    cdata->current = cdata->children;
+
+  if (cdata->current)
+    exec_actuator ((struct pn_actuator*)cdata->current->data);
+}
+
+struct pn_actuator_desc builtin_container_cycle =
+{
+  "container_cycle",
+  "Branched-execution Container",
+  "A container that alternates which of its children is executed;  it "
+  "can either change on an interval, or only on a beat.",
+  ACTUATOR_FLAG_CONTAINER, container_cycle_opts,
+  container_cycle_init, container_cycle_cleanup, container_cycle_exec
+};
+
+/* **************** container_onbeat **************** */
+static void
+container_onbeat_init (GSList ***data)
+{
+  *data = g_new0 (GSList *, 1);
+}
+
+static void
+container_onbeat_cleanup (GSList **data)
+{
+  container_cleanup (data);
+  g_free (data);
+}
+
+static void
+container_onbeat_exec (const struct pn_actuator_option *opts,
+		     GSList **data)
+{
+  GSList *child;
+
+  if (pn_new_beat == TRUE)
+    {
+      for (child = *data; child; child = child->next)
+        exec_actuator ((struct pn_actuator *) child->data);
+    }
+}
+
+struct pn_actuator_desc builtin_container_onbeat =
+{
+  "container_onbeat",
+  "OnBeat Container",
+  "A simple container which only triggers on a beat.",
+  ACTUATOR_FLAG_CONTAINER, NULL,
+  PN_ACTUATOR_INIT_FUNC (container_onbeat_init),
+  PN_ACTUATOR_CLEANUP_FUNC (container_onbeat_cleanup),
+  PN_ACTUATOR_EXEC_FUNC (container_onbeat_exec)
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/containers.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,27 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _PN_CONTAINERS_H
+#define _PN_CONTAINERS_H
+
+void container_add_actuator (struct pn_actuator *container, struct pn_actuator *a);
+void container_remove_actuator (struct pn_actuator *container, struct pn_actuator *a);
+void container_unlink_actuators (struct pn_actuator *container);
+
+#endif /* _CONTAINERS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/drawing.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,62 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <math.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "pn_utils.h"
+
+void
+pn_draw_dot (guint x, guint y, guchar value)
+{
+  if (x > pn_image_data->width || x < 0 || y > pn_image_data->height || y < 0)
+    return;
+
+  pn_image_data->surface[0][PN_IMG_INDEX(x, y)] = value;
+}
+
+void
+pn_draw_line (guint _x0, guint _y0, guint _x1, guint _y1, guchar value)
+{
+  gint x0 = _x0;
+  gint y0 = _y0;
+  gint x1 = _x1;
+  gint y1 = _y1;
+
+  gint dx = x1 - x0;
+  gint dy = y1 - y0;
+
+  pn_draw_dot(x0, y0, value);
+
+  if (dx != 0)
+    {
+      gfloat m = (gfloat) dy / (gfloat) dx;
+      gfloat b = y0 - m * x0;
+
+      dx = (x1 > x0) ? 1 : - 1;
+      while (x0 != x1)
+        {
+          x0 += dx;
+          y0 = m * x0 + b;
+
+          pn_draw_dot(x0, y0, value);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/drawing.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,28 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <glib.h>
+
+#ifndef PN_DRAWING_H
+#define PN_DRAWING_H
+
+void pn_draw_dot (guint x, guint y, guchar value);
+void pn_draw_line (guint _x0, guint _y0, guint _x1, guint _y1, guchar value);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/freq.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,81 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "pn_utils.h"
+
+/* **************** freq_dots **************** */
+/* FIXME: take this piece of crap out */
+static void
+freq_dots_exec (const struct pn_actuator_option *opts,
+		gpointer data)
+{
+  int i, basex;
+
+  basex = (pn_image_data->width>>1)-128;
+  for (i=basex < 0 ? -basex : 0 ; i < 256; i++)
+    {
+      pn_image_data->surface[0][PN_IMG_INDEX (basex+i, (pn_image_data->height>>1)
+					      - CAP (pn_sound_data->freq_data[0][i], 120))]
+	= 0xff;
+      pn_image_data->surface[0][PN_IMG_INDEX (basex+256-i, (pn_image_data->height>>1)
+					      + CAP (pn_sound_data->freq_data[1][i], 120))]
+	= 0xff;
+    }
+}
+
+struct pn_actuator_desc builtin_freq_dots =
+{
+  "freq_dots",
+  "Frequency Scope",
+  "Draws dots varying vertically with the freqency data.",
+  0, NULL,
+  NULL, NULL, freq_dots_exec
+};
+
+/* **************** freq_drops **************** */
+static void
+freq_drops_exec (const struct pn_actuator_option *opts,
+		gpointer data)
+{
+  int i,j;
+  
+  for (i=0; i<256; i++)
+    for (j=0; j<pn_sound_data->freq_data[0][i]>>3; i++)
+      pn_image_data->surface[0][PN_IMG_INDEX (rand() % pn_image_data->width,
+					      rand() % pn_image_data->height)]
+	= 0xff;
+}
+
+struct pn_actuator_desc builtin_freq_drops =
+{
+  "freq_drops",
+  "Random Dots",
+  "Draws dots at random on the image (louder music = more dots)",
+  0, NULL,
+  NULL, NULL, freq_drops_exec
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/general.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,410 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* FIXME: what to name this file? */
+
+#include <config.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "pn_utils.h"
+#include "libcalc/calc.h"
+
+/* **************** general_fade **************** */
+static struct pn_actuator_option_desc general_fade_opts[] =
+{
+  { "amount", "The amount by which the color index of each "
+    "pixel should be decreased by each frame (MAX 255)",
+    OPT_TYPE_INT, { ival: 3 } },
+  { NULL }
+};
+
+static void
+general_fade_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  int amt = opts[0].val.ival > 255 || opts[0].val.ival < 0 ? 3 : opts[0].val.ival;
+  int i, j;
+
+  for (j=0; j<pn_image_data->height; j++)
+    for (i=0; i<pn_image_data->width; i++)
+      pn_image_data->surface[0][PN_IMG_INDEX (i, j)] =
+	CAPLO (pn_image_data->surface[0][PN_IMG_INDEX (i, j)]
+	       - amt, 0);
+}
+
+struct pn_actuator_desc builtin_general_fade =
+{
+  "general_fade", "Fade-out", "Decreases the color index of each pixel",
+  0, general_fade_opts,
+  NULL, NULL, general_fade_exec
+};
+
+/* **************** general_blur **************** */
+/* FIXME: add a variable radius */
+/* FIXME: SPEEEED */
+static void
+general_blur_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  int i,j;
+  register guchar *srcptr = pn_image_data->surface[0];
+  register guchar *destptr = pn_image_data->surface[1];
+  register int sum;
+
+  for (j=0; j<pn_image_data->height; j++)
+    for (i=0; i<pn_image_data->width; i++)
+      {
+	sum = *(srcptr)<<2;
+
+	/* top */
+	if (j > 0)
+	  {
+	    sum += *(srcptr-pn_image_data->width)<<1;
+	    if (i > 0)
+	      sum += *(srcptr-pn_image_data->width-1);
+	    if (i < pn_image_data->width-1)
+	      sum += *(srcptr-pn_image_data->width+1);
+	  }
+	/* bottom */
+	if (j < pn_image_data->height-1)
+	  {
+	    sum += *(srcptr+pn_image_data->width)<<1;
+	    if (i > 0)
+	      sum += *(srcptr+pn_image_data->width-1);
+	    if (i < pn_image_data->width-1)
+	      sum += *(srcptr+pn_image_data->width+1);
+	  }
+	/* left */
+	if (i > 0)
+	  sum += *(srcptr-1)<<1;
+	/* right */
+	if (i < pn_image_data->width-1)
+	  sum += *(srcptr+1)<<1;
+
+	*destptr++ = (guchar)(sum >> 4);
+	srcptr++;
+      }
+
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_general_blur = 
+{
+  "general_blur", "Blur", "A simple 1 pixel radius blur",
+  0, NULL,
+  NULL, NULL, general_blur_exec
+};
+
+/* **************** general_mosaic **************** */
+/* FIXME: add a variable radius */
+/* FIXME: SPEEEED */
+static struct pn_actuator_option_desc general_mosaic_opts[] =
+{
+  { "radius", "The pixel radius that should be used for the effect.",
+    OPT_TYPE_INT, { ival: 6 } },
+  { NULL }
+};
+
+static void
+general_mosaic_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  int i,j;
+  register guchar *srcptr = pn_image_data->surface[0];
+  register guchar *destptr = pn_image_data->surface[1];
+  register int sum;
+  int radius = opts[0].val.ival > 255 || opts[0].val.ival < 0 ? 6 : opts[0].val.ival;
+
+  for (j=0; j<pn_image_data->height; j += radius)
+    for (i=0; i<pn_image_data->width; i += radius)
+      {
+        int ii = 0, jj = 0;
+        guchar bval = 0;
+
+        /* find the brightest colour */
+        for (jj = 0; jj < radius && (j + jj < pn_image_data->height); jj++)
+          for (ii = 0; ii < radius && (i + ii < pn_image_data->width); ii++)
+            {
+               guchar val = srcptr[PN_IMG_INDEX(i + ii,  j + jj)];
+
+               if (val > bval)
+                 bval = val;
+            }
+
+        for (jj = 0; jj < radius && (j + jj < pn_image_data->height); jj++)
+          for (ii = 0; ii < radius && (i + ii < pn_image_data->width); ii++)
+            {
+               destptr[PN_IMG_INDEX(i + ii, j + jj)] = bval;
+            }
+      }
+
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_general_mosaic = 
+{
+  "general_mosaic", "Mosaic", "A simple mosaic effect.",
+  0, general_mosaic_opts,
+  NULL, NULL, general_mosaic_exec
+};
+
+/* **************** general_clear **************** */
+static void
+general_clear_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
+struct pn_actuator_desc builtin_general_clear =
+{
+  "general_clear", "Clear Surface", "Clears the surface.",
+  0, NULL,
+  NULL, NULL, general_clear_exec
+};
+
+/* **************** general_noop **************** */
+static void
+general_noop_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  return;
+}
+
+struct pn_actuator_desc builtin_general_noop =
+{
+  "general_noop", "Do Nothing", "Does absolutely nothing.",
+  0, NULL,
+  NULL, NULL, general_noop_exec
+};
+
+/* **************** general_invert **************** */
+static void
+general_invert_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  int i, j;
+
+  for (j=0; j < pn_image_data->height; j++)
+    for (i=0; i < pn_image_data->width; i++)
+      pn_image_data->surface[0][PN_IMG_INDEX (i, j)] =
+	255 - pn_image_data->surface[0][PN_IMG_INDEX (i, j)];
+}
+
+struct pn_actuator_desc builtin_general_invert =
+{
+  "general_invert", "Value Invert", "Performs a value invert.",
+  0, NULL,
+  NULL, NULL, general_invert_exec
+};
+
+/* **************** general_replace **************** */
+static struct pn_actuator_option_desc general_replace_opts[] =
+{
+  { "start", "The beginning colour value that should be replaced by the value of out.",
+    OPT_TYPE_INT, { ival: 250 } },
+  { "end", "The ending colour value that should be replaced by the value of out.",
+    OPT_TYPE_INT, { ival: 255 } },
+  { "out", "The colour value that in is replaced with.",
+    OPT_TYPE_INT, { ival: 0 } },
+  { NULL }
+};
+
+static void
+general_replace_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  register int i, j;
+  register guchar val;
+  guchar begin = opts[0].val.ival > 255 || opts[0].val.ival < 0 ? 250 : opts[0].val.ival;
+  guchar end = opts[1].val.ival > 255 || opts[1].val.ival < 0 ? 255 : opts[1].val.ival;
+  guchar out = opts[2].val.ival > 255 || opts[2].val.ival < 0 ? 0 : opts[2].val.ival;
+
+  for (j=0; j < pn_image_data->height; j++)
+    for (i=0; i < pn_image_data->width; i++)
+      {
+        val = pn_image_data->surface[0][PN_IMG_INDEX (i, j)];
+        if (val >= begin && val <= end)
+          pn_image_data->surface[0][PN_IMG_INDEX (i, j)] = out;
+      }
+}
+
+struct pn_actuator_desc builtin_general_replace =
+{
+  "general_replace", "Value Replace", "Performs a value replace on a range of values.",
+  0, general_replace_opts,
+  NULL, NULL, general_replace_exec
+};
+
+/* **************** general_swap **************** */
+static void
+general_swap_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_general_swap =
+{
+  "general_swap", "Swap Surface", "Swaps the surface.",
+  0, NULL,
+  NULL, NULL, general_swap_exec
+};
+
+/* **************** general_copy **************** */
+static void
+general_copy_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  memcpy(pn_image_data->surface[1], pn_image_data->surface[0], 
+         (pn_image_data->width * pn_image_data->height));
+}
+
+struct pn_actuator_desc builtin_general_copy =
+{
+  "general_copy", "Copy Surface", "Copies the surface to the other surface.",
+  0, NULL,
+  NULL, NULL, general_copy_exec
+};
+
+/* **************** general_flip **************** */
+static struct pn_actuator_option_desc general_flip_opts[] =
+{
+  { "direction", "Negative is horizontal, positive is vertical.",
+    OPT_TYPE_INT, { ival: -1 } },
+  { NULL }
+};
+
+static void
+general_flip_exec (const struct pn_actuator_option *opts,
+	   gpointer data)
+{
+  gint x, y;
+
+  if (opts[0].val.ival < 0)
+    {
+      for (y = 0; y < pn_image_data->height; y++)
+        for (x = 0; x < pn_image_data->width; x++)
+          {
+             pn_image_data->surface[1][PN_IMG_INDEX(pn_image_data->width - x, y)] = 
+               pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
+          }
+    }
+  else
+    {
+      for (y = 0; y < pn_image_data->height; y++)
+        for (x = 0; x < pn_image_data->width; x++)
+          {
+             pn_image_data->surface[1][PN_IMG_INDEX(x, pn_image_data->height - y)] = 
+               pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
+          }
+    }
+
+    pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_general_flip =
+{
+  "general_flip", "Flip Surface", "Flips the surface.",
+  0, general_flip_opts,
+  NULL, NULL, general_flip_exec
+};
+
+/* ***************** general_evaluate ***************** */
+
+static struct pn_actuator_option_desc general_evaluate_opts[] =
+{
+  { "init_script", "Script to run on start.", OPT_TYPE_STRING, {sval: "global_reg0 = 27;"} },
+  { "frame_script", "Script to run.", OPT_TYPE_STRING, {sval: "global_reg0 = global_reg0 + 1;"} },
+  { NULL }
+};
+
+struct pn_evaluate_ctx
+{
+  expression_t *expr_on_init, *expr_on_frame;
+  symbol_dict_t *dict;
+  gboolean reset;
+};
+
+static void
+general_evaluate_init(gpointer *data)
+{
+  *data = g_new0(struct pn_evaluate_ctx, 1);
+
+  ((struct pn_evaluate_ctx *)*data)->reset = TRUE;
+}
+
+static void
+general_evaluate_cleanup(gpointer op_data)
+{
+  struct pn_evaluate_ctx *data = (struct pn_evaluate_ctx *) op_data;
+
+  g_return_if_fail(data != NULL);
+
+  if (data->expr_on_init)
+    expr_free(data->expr_on_init);
+
+  if (data->expr_on_frame)
+    expr_free(data->expr_on_frame);
+
+  if (data->dict)
+    dict_free(data->dict);
+
+  if (data)
+    g_free(data);
+}
+
+static void
+general_evaluate_exec(const struct pn_actuator_option *opts,
+                      gpointer op_data)
+{
+  struct pn_evaluate_ctx *data = (struct pn_evaluate_ctx *) op_data;
+
+  if (data->reset)
+    {
+       if (data->dict)
+         dict_free(data->dict);
+
+       data->dict = dict_new();
+
+       if (opts[0].val.sval != NULL);
+         data->expr_on_init = expr_compile_string(opts[0].val.sval, data->dict);
+
+       if (opts[1].val.sval != NULL);
+         data->expr_on_frame = expr_compile_string(opts[1].val.sval, data->dict);
+
+       if (data->expr_on_init != NULL)
+         expr_execute(data->expr_on_init, data->dict);
+
+       data->reset = FALSE;
+    }
+
+  if (data->expr_on_frame != NULL)
+    expr_execute(data->expr_on_frame, data->dict);
+}
+
+struct pn_actuator_desc builtin_general_evaluate =
+{
+  "general_evaluate", "Evalulate VM Code",
+  "Evaluates arbitrary VM code. Does not draw anything.",
+  0, general_evaluate_opts,
+  general_evaluate_init, general_evaluate_cleanup, general_evaluate_exec
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/.deps	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,425 @@
+dict.o: dict.c /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib64/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stddef.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/limits.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/syslimits.h \
+  /usr/include/limits.h /usr/include/gentoo-multilib/amd64/limits.h \
+  /usr/include/features.h /usr/include/gentoo-multilib/amd64/features.h \
+  /usr/include/sys/cdefs.h /usr/include/gentoo-multilib/amd64/sys/cdefs.h \
+  /usr/include/bits/wordsize.h \
+  /usr/include/gentoo-multilib/amd64/bits/wordsize.h \
+  /usr/include/gnu/stubs.h /usr/include/gentoo-multilib/amd64/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/include/gentoo-multilib/amd64/gnu/stubs-64.h \
+  /usr/include/bits/posix1_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/local_lim.h \
+  /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix2_lim.h \
+  /usr/include/bits/xopen_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/xopen_lim.h \
+  /usr/include/bits/stdio_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/stdio_lim.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gbase64.h \
+  /usr/include/glib-2.0/glib/gbookmarkfile.h /usr/include/time.h \
+  /usr/include/gentoo-multilib/amd64/time.h /usr/include/bits/time.h \
+  /usr/include/gentoo-multilib/amd64/bits/time.h \
+  /usr/include/bits/types.h \
+  /usr/include/gentoo-multilib/amd64/bits/types.h \
+  /usr/include/bits/typesizes.h \
+  /usr/include/gentoo-multilib/amd64/bits/typesizes.h \
+  /usr/include/xlocale.h /usr/include/gentoo-multilib/amd64/xlocale.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h /usr/include/glib-2.0/glib/gslice.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gkeyfile.h \
+  /usr/include/glib-2.0/glib/gmappedfile.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/goption.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/string.h /usr/include/gentoo-multilib/amd64/string.h \
+  dict.h
+execute.o: execute.c /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib64/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stddef.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/limits.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/syslimits.h \
+  /usr/include/limits.h /usr/include/gentoo-multilib/amd64/limits.h \
+  /usr/include/features.h /usr/include/gentoo-multilib/amd64/features.h \
+  /usr/include/sys/cdefs.h /usr/include/gentoo-multilib/amd64/sys/cdefs.h \
+  /usr/include/bits/wordsize.h \
+  /usr/include/gentoo-multilib/amd64/bits/wordsize.h \
+  /usr/include/gnu/stubs.h /usr/include/gentoo-multilib/amd64/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/include/gentoo-multilib/amd64/gnu/stubs-64.h \
+  /usr/include/bits/posix1_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/local_lim.h \
+  /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix2_lim.h \
+  /usr/include/bits/xopen_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/xopen_lim.h \
+  /usr/include/bits/stdio_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/stdio_lim.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gbase64.h \
+  /usr/include/glib-2.0/glib/gbookmarkfile.h /usr/include/time.h \
+  /usr/include/gentoo-multilib/amd64/time.h /usr/include/bits/time.h \
+  /usr/include/gentoo-multilib/amd64/bits/time.h \
+  /usr/include/bits/types.h \
+  /usr/include/gentoo-multilib/amd64/bits/types.h \
+  /usr/include/bits/typesizes.h \
+  /usr/include/gentoo-multilib/amd64/bits/typesizes.h \
+  /usr/include/xlocale.h /usr/include/gentoo-multilib/amd64/xlocale.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h /usr/include/glib-2.0/glib/gslice.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gkeyfile.h \
+  /usr/include/glib-2.0/glib/gmappedfile.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/goption.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/math.h /usr/include/gentoo-multilib/amd64/math.h \
+  /usr/include/bits/huge_val.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_val.h \
+  /usr/include/bits/huge_valf.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_valf.h \
+  /usr/include/bits/huge_vall.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_vall.h \
+  /usr/include/bits/inf.h /usr/include/gentoo-multilib/amd64/bits/inf.h \
+  /usr/include/bits/nan.h /usr/include/gentoo-multilib/amd64/bits/nan.h \
+  /usr/include/bits/mathdef.h \
+  /usr/include/gentoo-multilib/amd64/bits/mathdef.h \
+  /usr/include/bits/mathcalls.h \
+  /usr/include/gentoo-multilib/amd64/bits/mathcalls.h execute.h dict.h \
+  storage.h function.h
+function.o: function.c /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib64/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stddef.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/limits.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/syslimits.h \
+  /usr/include/limits.h /usr/include/gentoo-multilib/amd64/limits.h \
+  /usr/include/features.h /usr/include/gentoo-multilib/amd64/features.h \
+  /usr/include/sys/cdefs.h /usr/include/gentoo-multilib/amd64/sys/cdefs.h \
+  /usr/include/bits/wordsize.h \
+  /usr/include/gentoo-multilib/amd64/bits/wordsize.h \
+  /usr/include/gnu/stubs.h /usr/include/gentoo-multilib/amd64/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/include/gentoo-multilib/amd64/gnu/stubs-64.h \
+  /usr/include/bits/posix1_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/local_lim.h \
+  /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix2_lim.h \
+  /usr/include/bits/xopen_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/xopen_lim.h \
+  /usr/include/bits/stdio_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/stdio_lim.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gbase64.h \
+  /usr/include/glib-2.0/glib/gbookmarkfile.h /usr/include/time.h \
+  /usr/include/gentoo-multilib/amd64/time.h /usr/include/bits/time.h \
+  /usr/include/gentoo-multilib/amd64/bits/time.h \
+  /usr/include/bits/types.h \
+  /usr/include/gentoo-multilib/amd64/bits/types.h \
+  /usr/include/bits/typesizes.h \
+  /usr/include/gentoo-multilib/amd64/bits/typesizes.h \
+  /usr/include/xlocale.h /usr/include/gentoo-multilib/amd64/xlocale.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h /usr/include/glib-2.0/glib/gslice.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gkeyfile.h \
+  /usr/include/glib-2.0/glib/gmappedfile.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/goption.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/math.h /usr/include/gentoo-multilib/amd64/math.h \
+  /usr/include/bits/huge_val.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_val.h \
+  /usr/include/bits/huge_valf.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_valf.h \
+  /usr/include/bits/huge_vall.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_vall.h \
+  /usr/include/bits/inf.h /usr/include/gentoo-multilib/amd64/bits/inf.h \
+  /usr/include/bits/nan.h /usr/include/gentoo-multilib/amd64/bits/nan.h \
+  /usr/include/bits/mathdef.h \
+  /usr/include/gentoo-multilib/amd64/bits/mathdef.h \
+  /usr/include/bits/mathcalls.h \
+  /usr/include/gentoo-multilib/amd64/bits/mathcalls.h \
+  /usr/include/string.h /usr/include/gentoo-multilib/amd64/string.h \
+  function.h execute.h dict.h storage.h
+parser.o: parser.c /usr/include/ctype.h \
+  /usr/include/gentoo-multilib/amd64/ctype.h /usr/include/features.h \
+  /usr/include/gentoo-multilib/amd64/features.h /usr/include/sys/cdefs.h \
+  /usr/include/gentoo-multilib/amd64/sys/cdefs.h \
+  /usr/include/bits/wordsize.h \
+  /usr/include/gentoo-multilib/amd64/bits/wordsize.h \
+  /usr/include/gnu/stubs.h /usr/include/gentoo-multilib/amd64/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/include/gentoo-multilib/amd64/gnu/stubs-64.h \
+  /usr/include/bits/types.h \
+  /usr/include/gentoo-multilib/amd64/bits/types.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stddef.h \
+  /usr/include/bits/typesizes.h \
+  /usr/include/gentoo-multilib/amd64/bits/typesizes.h \
+  /usr/include/endian.h /usr/include/gentoo-multilib/amd64/endian.h \
+  /usr/include/bits/endian.h \
+  /usr/include/gentoo-multilib/amd64/bits/endian.h /usr/include/xlocale.h \
+  /usr/include/gentoo-multilib/amd64/xlocale.h \
+  /usr/include/glib-2.0/glib.h /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib64/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/limits.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/syslimits.h \
+  /usr/include/limits.h /usr/include/gentoo-multilib/amd64/limits.h \
+  /usr/include/bits/posix1_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/local_lim.h \
+  /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix2_lim.h \
+  /usr/include/bits/xopen_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/xopen_lim.h \
+  /usr/include/bits/stdio_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/stdio_lim.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gbase64.h \
+  /usr/include/glib-2.0/glib/gbookmarkfile.h /usr/include/time.h \
+  /usr/include/gentoo-multilib/amd64/time.h /usr/include/bits/time.h \
+  /usr/include/gentoo-multilib/amd64/bits/time.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h /usr/include/glib-2.0/glib/gslice.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gkeyfile.h \
+  /usr/include/glib-2.0/glib/gmappedfile.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/goption.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  /usr/include/locale.h /usr/include/gentoo-multilib/amd64/locale.h \
+  /usr/include/bits/locale.h \
+  /usr/include/gentoo-multilib/amd64/bits/locale.h /usr/include/math.h \
+  /usr/include/gentoo-multilib/amd64/math.h /usr/include/bits/huge_val.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_val.h \
+  /usr/include/bits/huge_valf.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_valf.h \
+  /usr/include/bits/huge_vall.h \
+  /usr/include/gentoo-multilib/amd64/bits/huge_vall.h \
+  /usr/include/bits/inf.h /usr/include/gentoo-multilib/amd64/bits/inf.h \
+  /usr/include/bits/nan.h /usr/include/gentoo-multilib/amd64/bits/nan.h \
+  /usr/include/bits/mathdef.h \
+  /usr/include/gentoo-multilib/amd64/bits/mathdef.h \
+  /usr/include/bits/mathcalls.h \
+  /usr/include/gentoo-multilib/amd64/bits/mathcalls.h \
+  /usr/include/stdio.h /usr/include/gentoo-multilib/amd64/stdio.h \
+  /usr/include/libio.h /usr/include/gentoo-multilib/amd64/libio.h \
+  /usr/include/_G_config.h /usr/include/gentoo-multilib/amd64/_G_config.h \
+  /usr/include/wchar.h /usr/include/gentoo-multilib/amd64/wchar.h \
+  /usr/include/bits/wchar.h \
+  /usr/include/gentoo-multilib/amd64/bits/wchar.h /usr/include/gconv.h \
+  /usr/include/gentoo-multilib/amd64/gconv.h \
+  /usr/include/bits/sys_errlist.h \
+  /usr/include/gentoo-multilib/amd64/bits/sys_errlist.h \
+  /usr/include/string.h /usr/include/gentoo-multilib/amd64/string.h \
+  dict.h execute.h storage.h function.h parser.h \
+  /usr/include/audacious/vfs.h /usr/include/sys/types.h \
+  /usr/include/gentoo-multilib/amd64/sys/types.h \
+  /usr/include/sys/select.h \
+  /usr/include/gentoo-multilib/amd64/sys/select.h \
+  /usr/include/bits/select.h \
+  /usr/include/gentoo-multilib/amd64/bits/select.h \
+  /usr/include/bits/sigset.h \
+  /usr/include/gentoo-multilib/amd64/bits/sigset.h \
+  /usr/include/sys/sysmacros.h \
+  /usr/include/gentoo-multilib/amd64/sys/sysmacros.h \
+  /usr/include/bits/pthreadtypes.h \
+  /usr/include/gentoo-multilib/amd64/bits/pthreadtypes.h \
+  /usr/include/audacious/vfs_buffer.h /usr/include/audacious/vfs.h
+storage.o: storage.c /usr/include/glib-2.0/glib.h \
+  /usr/include/glib-2.0/glib/galloca.h \
+  /usr/include/glib-2.0/glib/gtypes.h \
+  /usr/lib64/glib-2.0/include/glibconfig.h \
+  /usr/include/glib-2.0/glib/gmacros.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stddef.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/limits.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/syslimits.h \
+  /usr/include/limits.h /usr/include/gentoo-multilib/amd64/limits.h \
+  /usr/include/features.h /usr/include/gentoo-multilib/amd64/features.h \
+  /usr/include/sys/cdefs.h /usr/include/gentoo-multilib/amd64/sys/cdefs.h \
+  /usr/include/bits/wordsize.h \
+  /usr/include/gentoo-multilib/amd64/bits/wordsize.h \
+  /usr/include/gnu/stubs.h /usr/include/gentoo-multilib/amd64/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/include/gentoo-multilib/amd64/gnu/stubs-64.h \
+  /usr/include/bits/posix1_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix1_lim.h \
+  /usr/include/bits/local_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/local_lim.h \
+  /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/posix2_lim.h \
+  /usr/include/bits/xopen_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/xopen_lim.h \
+  /usr/include/bits/stdio_lim.h \
+  /usr/include/gentoo-multilib/amd64/bits/stdio_lim.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/float.h \
+  /usr/include/glib-2.0/glib/garray.h \
+  /usr/include/glib-2.0/glib/gasyncqueue.h \
+  /usr/include/glib-2.0/glib/gthread.h \
+  /usr/include/glib-2.0/glib/gerror.h /usr/include/glib-2.0/glib/gquark.h \
+  /usr/include/glib-2.0/glib/gatomic.h \
+  /usr/include/glib-2.0/glib/gbacktrace.h \
+  /usr/include/glib-2.0/glib/gbase64.h \
+  /usr/include/glib-2.0/glib/gbookmarkfile.h /usr/include/time.h \
+  /usr/include/gentoo-multilib/amd64/time.h /usr/include/bits/time.h \
+  /usr/include/gentoo-multilib/amd64/bits/time.h \
+  /usr/include/bits/types.h \
+  /usr/include/gentoo-multilib/amd64/bits/types.h \
+  /usr/include/bits/typesizes.h \
+  /usr/include/gentoo-multilib/amd64/bits/typesizes.h \
+  /usr/include/xlocale.h /usr/include/gentoo-multilib/amd64/xlocale.h \
+  /usr/include/glib-2.0/glib/gcache.h /usr/include/glib-2.0/glib/glist.h \
+  /usr/include/glib-2.0/glib/gmem.h /usr/include/glib-2.0/glib/gslice.h \
+  /usr/include/glib-2.0/glib/gcompletion.h \
+  /usr/include/glib-2.0/glib/gconvert.h \
+  /usr/include/glib-2.0/glib/gdataset.h \
+  /usr/include/glib-2.0/glib/gdate.h /usr/include/glib-2.0/glib/gdir.h \
+  /usr/include/glib-2.0/glib/gfileutils.h \
+  /usr/include/glib-2.0/glib/ghash.h /usr/include/glib-2.0/glib/ghook.h \
+  /usr/include/glib-2.0/glib/giochannel.h \
+  /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gslist.h \
+  /usr/include/glib-2.0/glib/gstring.h \
+  /usr/include/glib-2.0/glib/gunicode.h \
+  /usr/include/glib-2.0/glib/gutils.h \
+  /usr/lib/gcc/x86_64-pc-linux-gnu/4.2.0/include/stdarg.h \
+  /usr/include/glib-2.0/glib/gkeyfile.h \
+  /usr/include/glib-2.0/glib/gmappedfile.h \
+  /usr/include/glib-2.0/glib/gmarkup.h \
+  /usr/include/glib-2.0/glib/gmessages.h \
+  /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/goption.h \
+  /usr/include/glib-2.0/glib/gpattern.h \
+  /usr/include/glib-2.0/glib/gprimes.h \
+  /usr/include/glib-2.0/glib/gqsort.h /usr/include/glib-2.0/glib/gqueue.h \
+  /usr/include/glib-2.0/glib/grand.h /usr/include/glib-2.0/glib/grel.h \
+  /usr/include/glib-2.0/glib/gscanner.h \
+  /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gspawn.h \
+  /usr/include/glib-2.0/glib/gstrfuncs.h \
+  /usr/include/glib-2.0/glib/gthreadpool.h \
+  /usr/include/glib-2.0/glib/gtimer.h /usr/include/glib-2.0/glib/gtree.h \
+  storage.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/calc.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,30 @@
+/* calc.h -- an all-in-one include file for libcalc
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef Included_CALC_H
+#define Included_CALC_H
+
+#include "dict.h"
+#include "execute.h"
+#include "parser.h"
+#include "storage.h"
+
+#endif /* Included_CALC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/dict.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,128 @@
+/* dict.c -- symbol dictionary structures
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+ 
+#define V_SPACE_INIT 8
+#define V_SPACE_INCR 8
+ 
+#include <glib.h>
+#include <string.h>
+
+#include "dict.h"
+
+static int global_dict_initialized = 0;
+static symbol_dict_t global_dict;
+
+static void more_variables (symbol_dict_t *dict) {
+  var_t *new_var;
+
+  dict->v_space += V_SPACE_INCR;
+
+  new_var = g_new(var_t, dict->v_space + 1);
+  memcpy (new_var, dict->variables, dict->v_count * sizeof(var_t));
+  g_free (dict->variables);
+
+  dict->variables = new_var;
+}
+
+static int dict_define_variable (symbol_dict_t *dict, const char *name) {
+  var_t *var;
+
+  if (dict->v_count >= dict->v_space)
+    more_variables (dict);
+
+  var = &dict->variables[dict->v_count];
+
+  var->value = 0.0;
+  var->name = g_strdup (name);
+
+  return dict->v_count++;
+}
+
+symbol_dict_t *dict_new (void) {
+  symbol_dict_t *dict;
+
+  if (global_dict_initialized != 1) {
+    int i;
+
+    global_dict.v_count = 0;
+    global_dict.v_space = V_SPACE_INIT;
+    global_dict.variables = (var_t *) g_new(var_t, global_dict.v_space + 1);
+    global_dict_initialized = 1;
+
+    for (i = 0; i < 100; i++) {
+      gchar tmpbuf[40];
+      g_snprintf(tmpbuf, 40, "global_reg%d", i);
+      dict_define_variable(&global_dict, tmpbuf);
+    }
+  }
+
+  dict = g_new(symbol_dict_t, 1);
+
+  /* Allocate space for variables. */
+  dict->v_count = 0;
+  dict->v_space = V_SPACE_INIT;
+  dict->variables = (var_t *) g_new (var_t, dict->v_space + 1);
+  
+  return dict;
+}
+
+void dict_free (symbol_dict_t *dict) {
+  int i;
+
+  if (!dict)
+    return;
+
+  /* Free memory used by variables. */
+  for (i = 0; i < dict->v_count; i++)
+    g_free (dict->variables[i].name);
+  g_free (dict->variables);
+
+  g_free (dict);
+}
+
+int dict_lookup (symbol_dict_t *dict, const char *name) {
+  int i;
+
+  for (i = 0; i < global_dict.v_count; i++) {
+    if (strcmp (global_dict.variables[i].name, name) == 0)
+      return -i;
+  }
+
+  for (i = 0; i < dict->v_count; i++) {
+    if (strcmp (dict->variables[i].name, name) == 0)
+      return i;
+  }
+  
+  /* Not defined -- define a new variable. */
+  return dict_define_variable (dict, name);
+}
+
+double *dict_variable (symbol_dict_t *dict, const char *var_name) {
+  int id = dict_lookup (dict, var_name);
+
+  /* global variables are presented as negative offset. negating
+   * a negative number results in a positive offset. --nenolod
+   */
+  if (id < 0)
+    return &global_dict.variables[-id].value;
+
+  return &dict->variables[id].value;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/dict.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,46 @@
+/* dict.h -- symbol dictionary structures
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef Included_DICT_H
+#define Included_DICT_H
+
+/* A variable. */
+typedef struct {
+  char *name;
+  double value;
+} var_t;
+
+/* A symbol dictionary. */
+typedef struct {
+  /* Variables. */
+  var_t *variables;
+  int v_count;
+  int v_space;
+} symbol_dict_t;
+
+/* Prototypes. */
+symbol_dict_t *dict_new (void);
+void dict_free (symbol_dict_t *dict);
+
+int dict_lookup (symbol_dict_t *calc, const char *name);
+double* dict_variable (symbol_dict_t *calc, const char *var_name);
+
+#endif /* Included_DICT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/execute.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,121 @@
+/* execute.c -- execute precompiled expression expr
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+ 
+#include <glib.h>
+#include <math.h>
+ 
+#include "execute.h"
+#include "function.h"
+
+/* Execution stack. */
+
+gboolean check_stack (ex_stack *stack, int depth) {
+  if (stack->sp < depth) {
+    g_warning ("Stack error");
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+void push (ex_stack *stack, double value) {
+  g_assert (stack);
+
+  if (stack->sp < STACK_DEPTH) {
+    stack->value[stack->sp++] = value;
+  } else {
+    g_warning ("Stack overflow");
+  }
+}
+
+double pop (ex_stack *stack) {
+  g_assert (stack);
+
+  if (stack->sp > 0) {
+    return stack->value[--stack->sp];
+  } else {
+    g_warning ("Stack error (stack empty)");
+    return 0.0;
+  }
+}
+
+/* */
+
+void expr_execute (expression_t *expr, symbol_dict_t *dict) {
+  char op, *str = expr->data->str;
+  ex_stack stack = { 0, { 0.0 }};
+
+  while ((op = *str++)) {
+    switch (op) { 
+    case 'l': /* Load a variable. */
+      push (&stack, dict->variables[load_int (str)].value);
+      str += sizeof (int);
+      break;
+      
+    case 's': /* Store to a variable. */
+      dict->variables[load_int (str)].value = pop (&stack);
+      str += sizeof (int);
+      break;
+   
+    case 'f': /* Call a function. */
+      function_call (load_int (str), &stack);
+      str += sizeof (int);
+      break;
+      
+    case 'c': /* Load a constant. */
+      push (&stack, load_double (str));
+      str += sizeof (double);
+      break;
+
+    case 'n': /* Do a negation. */
+      push (&stack, -pop (&stack));
+      break;
+
+    case '+': /* Do an addition. */
+      push (&stack, pop (&stack) + pop (&stack));
+      break;
+    case '-': /* Do a subtraction. */
+      push (&stack, pop (&stack) - pop (&stack));
+      break;
+    case '*': /* Do a multiplication. */
+      push (&stack, pop (&stack) * pop (&stack));
+      break;
+    case '/': /* Do a division. */
+      if (check_stack (&stack, 2)) {
+        double y = stack.value[stack.sp - 2] / stack.value[stack.sp - 1];
+	stack.sp -= 2;
+	push (&stack, y);
+      }
+      break;
+    case '^': /* Do an exponentiation. */
+      if (check_stack (&stack, 2)) {
+        double y = pow (stack.value[stack.sp - 2], stack.value[stack.sp - 1]);
+	stack.sp -= 2;
+	push (&stack, y);
+      }
+      break;
+
+    default:
+      g_warning ("Invalid opcode: %c", op);
+      return;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/execute.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,46 @@
+/* execute.h -- execute precompiled expression code
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef Included_EXECUTE_H
+#define Included_EXECUTE_H
+
+#include <glib.h>
+
+#include "dict.h"
+#include "storage.h"
+
+/* Execution stack. */
+
+typedef struct { 
+#define STACK_DEPTH 64
+  int sp;			/* stack pointer */
+  double value[STACK_DEPTH];
+} ex_stack;
+
+/* Prototypes. */
+
+gboolean check_stack (ex_stack *stack, int depth);
+void push (ex_stack *stack, double value);
+double pop (ex_stack *stack);
+
+void expr_execute (expression_t *expr, symbol_dict_t *dict);
+
+#endif /* Included_EXECUTE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/function.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,111 @@
+/* function.c --
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+ 
+#include <glib.h>
+#include <math.h>
+#include <string.h>
+ 
+#include "function.h"
+
+/* Function pointer type. */
+typedef struct {
+  char *name;
+  double (*funcptr)(ex_stack *stack);
+} func_t;
+
+/* */
+
+static double f_log (ex_stack *stack) {
+  return log (pop (stack));
+}
+
+static double f_sin (ex_stack *stack) {
+  return sin (pop (stack));
+}
+
+static double f_cos (ex_stack *stack) {
+  return cos (pop (stack));
+}
+
+static double f_tan (ex_stack *stack) {
+  return tan (pop (stack));
+}
+
+static double f_asin (ex_stack *stack) {
+  return asin (pop (stack));
+}
+
+static double f_acos (ex_stack *stack) {
+  return acos (pop (stack));
+}
+
+static double f_atan (ex_stack *stack) {
+  return atan (pop (stack));
+}
+
+static double f_if (ex_stack *stack) {
+  double a = pop (stack);
+  double b = pop (stack);
+  return (pop (stack) != 0.0) ? a : b;
+}
+
+static double f_div (ex_stack *stack) {
+  int y = (int)pop (stack);
+  int x = (int)pop (stack);
+  return (y == 0) ? 0 : (x / y);
+}
+
+static double f_rand (ex_stack *stack) {
+  return g_random_double_range((double) pop(stack), (double) pop(stack));
+}
+
+/* */
+
+static const func_t init[] = {
+  { "sin", f_sin },
+  { "cos", f_cos },
+  { "tan", f_tan },
+  { "asin", f_asin },
+  { "acos", f_acos },
+  { "atan", f_atan },
+  { "log", f_log },
+  { "if", f_if },
+  { "div", f_div },
+  { "rand", f_rand }
+};
+
+int function_lookup (const char *name) {
+  int i;
+
+  for (i = 0; i < sizeof (init) / sizeof (init[0]); i++)
+    if (strcmp (init[i].name, name) == 0)
+      return i;
+
+  g_warning ("Unknown function: %s\n", name);
+  return -1;
+}
+
+void function_call (int func_id, ex_stack *stack) {
+  g_assert (func_id >= 0);
+  g_assert (func_id < sizeof (init) / sizeof (init[0]));
+
+  push (stack, (*init[func_id].funcptr)(stack));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/function.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,32 @@
+/* function.h --
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef Included_FUNCTION
+#define Included_FUNCTION
+
+#include "execute.h"
+
+/* Prototypes. */
+
+int function_lookup (const char *name);
+void function_call (int func_id, ex_stack *stack);
+
+#endif /* Included_FUNCTION */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/parser.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,1521 @@
+/* A Bison parser, made by GNU Bison 1.875d.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     NAME = 258,
+     NUMBER = 259,
+     NEG = 260
+   };
+#endif
+#define NAME 258
+#define NUMBER 259
+#define NEG 260
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 26 "parser.y"
+
+#include <ctype.h>
+#include <glib.h>
+#include <locale.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "dict.h"
+#include "execute.h"
+#include "function.h"
+#include "parser.h"
+#include "storage.h"
+
+#define YYPARSE_PARAM yyparam
+#define YYLEX_PARAM yyparam
+
+static gboolean expr_add_compile (expression_t *expr, symbol_dict_t *dict,
+				  char *str);
+
+#define GENERATE(str) if (!expr_add_compile (((parser_control *)yyparam)->expr, \
+				        ((parser_control *)yyparam)->dict, str)) \
+                   YYABORT;
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 54 "parser.y"
+typedef union YYSTYPE {
+char *s_value;
+char c_value;
+double d_value;
+int i_value;
+} YYSTYPE;
+/* Line 191 of yacc.c.  */
+#line 118 "parser.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 214 of yacc.c.  */
+#line 130 "parser.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+#  define YYFREE free
+# endif
+# ifndef YYMALLOC
+#  define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   define YYSTACK_ALLOC alloca
+#  endif
+# else
+#  if defined (alloca) || defined (_ALLOCA_H)
+#   define YYSTACK_ALLOC alloca
+#  else
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE))			\
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   65
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  18
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  5
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  22
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  37
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   260
+
+#define YYTRANSLATE(YYX) 						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      14,    15,     8,     7,    13,     6,     2,     9,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    12,
+      17,     5,    16,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,    11,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+      10
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned char yyprhs[] =
+{
+       0,     0,     3,     4,     7,     8,    10,    13,    16,    18,
+      22,    24,    26,    30,    35,    39,    43,    47,    51,    55,
+      59,    62,    66
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      19,     0,    -1,    -1,    19,    20,    -1,    -1,    22,    -1,
+      20,    12,    -1,     1,    12,    -1,    22,    -1,    21,    13,
+      22,    -1,     4,    -1,     3,    -1,     3,     5,    22,    -1,
+       3,    14,    21,    15,    -1,    22,    16,    22,    -1,    22,
+      17,    22,    -1,    22,     7,    22,    -1,    22,     6,    22,
+      -1,    22,     8,    22,    -1,    22,     9,    22,    -1,     6,
+      22,    -1,    22,    11,    22,    -1,    14,    22,    15,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned char yyrline[] =
+{
+       0,    76,    76,    77,    81,    82,    84,    85,    90,    93,
+      98,   104,   110,   116,   123,   125,   128,   130,   132,   134,
+     136,   138,   140
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "NAME", "NUMBER", "'='", "'-'", "'+'",
+  "'*'", "'/'", "NEG", "'^'", "';'", "','", "'('", "')'", "'>'", "'<'",
+  "$accept", "input", "expression_list", "argument_list", "expression", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,    61,    45,    43,    42,    47,
+     260,    94,    59,    44,    40,    41,    62,    60
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    18,    19,    19,    20,    20,    20,    20,    21,    21,
+      22,    22,    22,    22,    22,    22,    22,    22,    22,    22,
+      22,    22,    22
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     0,     2,     0,     1,     2,     2,     1,     3,
+       1,     1,     3,     4,     3,     3,     3,     3,     3,     3,
+       2,     3,     3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       2,     0,     1,     0,    11,    10,     0,     0,     3,     5,
+       7,     0,     0,    20,     0,     6,     0,     0,     0,     0,
+       0,     0,     0,    12,     0,     8,    22,    17,    16,    18,
+      19,    21,    14,    15,     0,    13,     9
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+      -1,     1,     8,    24,     9
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -10
+static const yysigned_char yypact[] =
+{
+     -10,    17,   -10,    -8,    22,   -10,    47,    47,    -3,    38,
+     -10,    47,    47,    -9,    26,   -10,    47,    47,    47,    47,
+      47,    47,    47,    38,     9,    38,   -10,    48,    48,    -9,
+      -9,    -9,    38,    38,    47,   -10,    38
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yysigned_char yypgoto[] =
+{
+     -10,   -10,   -10,   -10,    -6
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -5
+static const yysigned_char yytable[] =
+{
+      13,    14,    20,     0,    10,    23,    25,    21,    22,    15,
+      27,    28,    29,    30,    31,    32,    33,     2,     3,     0,
+       4,     5,    34,     6,    35,     0,     0,    11,    36,    -4,
+       0,     7,    16,    17,    18,    19,    12,    20,     0,     0,
+       0,    26,    21,    22,    16,    17,    18,    19,     0,    20,
+       4,     5,     0,     6,    21,    22,    18,    19,     0,    20,
+       0,     7,     0,     0,    21,    22
+};
+
+static const yysigned_char yycheck[] =
+{
+       6,     7,    11,    -1,    12,    11,    12,    16,    17,    12,
+      16,    17,    18,    19,    20,    21,    22,     0,     1,    -1,
+       3,     4,    13,     6,    15,    -1,    -1,     5,    34,    12,
+      -1,    14,     6,     7,     8,     9,    14,    11,    -1,    -1,
+      -1,    15,    16,    17,     6,     7,     8,     9,    -1,    11,
+       3,     4,    -1,     6,    16,    17,     8,     9,    -1,    11,
+      -1,    14,    -1,    -1,    16,    17
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    19,     0,     1,     3,     4,     6,    14,    20,    22,
+      12,     5,    14,    22,    22,    12,     6,     7,     8,     9,
+      11,    16,    17,    22,    21,    22,    15,    22,    22,    22,
+      22,    22,    22,    22,    13,    15,    22
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)		\
+   ((Current).first_line   = (Rhs)[1].first_line,	\
+    (Current).first_column = (Rhs)[1].first_column,	\
+    (Current).last_line    = (Rhs)[N].last_line,	\
+    (Current).last_column  = (Rhs)[N].last_column)
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+
+# define YYDSYMPRINT(Args)			\
+do {						\
+  if (yydebug)					\
+    yysymprint Args;				\
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location)		\
+do {								\
+  if (yydebug)							\
+    {								\
+      YYFPRINTF (stderr, "%s ", Title);				\
+      yysymprint (stderr, 					\
+                  Token, Value);	\
+      YYFPRINTF (stderr, "\n");					\
+    }								\
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (Rule);		\
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+    {
+      YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+    }
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  /* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  register short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short int *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyoverflowlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short int *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+  YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 5:
+#line 83 "parser.y"
+    { ;}
+    break;
+
+  case 7:
+#line 86 "parser.y"
+    { yyerrok; ;}
+    break;
+
+  case 8:
+#line 91 "parser.y"
+    {
+                            ;}
+    break;
+
+  case 9:
+#line 94 "parser.y"
+    {
+                            ;}
+    break;
+
+  case 10:
+#line 99 "parser.y"
+    { 
+                              char *buf = g_strdup_printf ("c%f:", yyvsp[0].d_value);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            ;}
+    break;
+
+  case 11:
+#line 105 "parser.y"
+    { 
+                              char *buf = g_strdup_printf ("l%s:", yyvsp[0].s_value);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            ;}
+    break;
+
+  case 12:
+#line 111 "parser.y"
+    { 
+                              char *buf = g_strdup_printf ("s%s:", yyvsp[-2].s_value);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            ;}
+    break;
+
+  case 13:
+#line 117 "parser.y"
+    {
+                              char *buf = g_strdup_printf ("f%s:", yyvsp[-3].s_value);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            ;}
+    break;
+
+  case 14:
+#line 124 "parser.y"
+    { GENERATE (">"); ;}
+    break;
+
+  case 15:
+#line 126 "parser.y"
+    { GENERATE ("<"); ;}
+    break;
+
+  case 16:
+#line 129 "parser.y"
+    { GENERATE ("+"); ;}
+    break;
+
+  case 17:
+#line 131 "parser.y"
+    { GENERATE ("-"); ;}
+    break;
+
+  case 18:
+#line 133 "parser.y"
+    { GENERATE ("*"); ;}
+    break;
+
+  case 19:
+#line 135 "parser.y"
+    { GENERATE ("/"); ;}
+    break;
+
+  case 20:
+#line 137 "parser.y"
+    { GENERATE ("n"); ;}
+    break;
+
+  case 21:
+#line 139 "parser.y"
+    { GENERATE ("^"); ;}
+    break;
+
+  case 22:
+#line 141 "parser.y"
+    { ;}
+    break;
+
+
+    }
+
+/* Line 1010 of yacc.c.  */
+#line 1140 "parser.c"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  YYSIZE_T yysize = 0;
+	  int yytype = YYTRANSLATE (yychar);
+	  const char* yyprefix;
+	  char *yymsg;
+	  int yyx;
+
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  int yyxbegin = yyn < 0 ? -yyn : 0;
+
+	  /* Stay within bounds of both yycheck and yytname.  */
+	  int yychecklim = YYLAST - yyn;
+	  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+	  int yycount = 0;
+
+	  yyprefix = ", expecting ";
+	  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      {
+		yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+		yycount += 1;
+		if (yycount == 5)
+		  {
+		    yysize = 0;
+		    break;
+		  }
+	      }
+	  yysize += (sizeof ("syntax error, unexpected ")
+		     + yystrlen (yytname[yytype]));
+	  yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg != 0)
+	    {
+	      char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+	      yyp = yystpcpy (yyp, yytname[yytype]);
+
+	      if (yycount < 5)
+		{
+		  yyprefix = ", expecting ";
+		  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+		      {
+			yyp = yystpcpy (yyp, yyprefix);
+			yyp = yystpcpy (yyp, yytname[yyx]);
+			yyprefix = " or ";
+		      }
+		}
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    yyerror ("syntax error; also virtual memory exhausted");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror ("syntax error");
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+          /* If at end of input, pop the error token,
+	     then the rest of the stack, then return failure.  */
+	  if (yychar == YYEOF)
+	     for (;;)
+	       {
+		 YYPOPSTACK;
+		 if (yyssp == yyss)
+		   YYABORT;
+		 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+		 yydestruct (yystos[*yyssp], yyvsp);
+	       }
+        }
+      else
+	{
+	  YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+	  yydestruct (yytoken, &yylval);
+	  yychar = YYEMPTY;
+
+	}
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+  /* Pacify GCC when the user code never invokes YYERROR and the label
+     yyerrorlab therefore never appears in user code.  */
+  if (0)
+     goto yyerrorlab;
+#endif
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+      yydestruct (yystos[yystate], yyvsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  YYDPRINTF ((stderr, "Shifting error token, "));
+
+  *++yyvsp = yylval;
+
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 144 "parser.y"
+
+/* End of grammar */
+
+/* Called by yyparse on error. */
+int yyerror (char *s) {
+  /* Ignore errors, just print a warning. */
+  g_warning ("%s\n", s);
+  return 0;
+}
+
+int yylex (YYSTYPE *yylval, void *yyparam) {
+  int c;
+  parser_control *pc = (parser_control *) yyparam;
+  
+  /* Ignore whitespace, get first nonwhite character. */
+  while ((c = aud_vfs_getc (pc->input)) == ' ' || c == '\t' || c == '\n');
+  
+  /* End of input ? */
+  if (c == EOF)
+    return 0;
+
+  /* Char starts a number => parse the number. */
+  if (isdigit (c)) {
+    aud_vfs_fseek (pc->input, -1, SEEK_CUR); /* Put the char back. */
+    {
+      char *old_locale, *saved_locale;
+
+      old_locale = setlocale (LC_ALL, NULL);
+      saved_locale = g_strdup (old_locale);
+      setlocale (LC_ALL, "C");
+      sscanf (((VFSBuffer *)(pc->input->handle))->iter, "%lf", &yylval->d_value);
+
+      while (isdigit(c) || c == '.')
+      {
+        c = aud_vfs_getc(pc->input);
+      }
+
+      aud_vfs_fseek(pc->input, -1, SEEK_CUR);
+
+      setlocale (LC_ALL, saved_locale);
+      g_free (saved_locale);
+    }
+    return NUMBER;
+  }
+     
+  /* Char starts an identifier => read the name. */
+  if (isalpha (c)) {
+    GString *sym_name;
+
+    sym_name = g_string_new (NULL);
+    
+    do {
+      sym_name = g_string_append_c (sym_name, c);
+
+      /* Get another character. */
+      c = aud_vfs_getc (pc->input);
+    } while (c != EOF && isalnum (c));
+    
+    aud_vfs_fseek (pc->input, -1, SEEK_CUR);
+
+    yylval->s_value = sym_name->str;
+    
+    g_string_free (sym_name, FALSE);
+    
+    return NAME;
+  }
+
+  /* Any other character is a token by itself. */
+  return c;
+}
+
+static int load_name (char *str, char **name) {
+  int count = 0;
+  GString *new = g_string_new (NULL);
+
+  while (*str != 0 && *str != ':') {
+    g_string_append_c (new, *str++);
+    count++;
+  }
+
+  *name = new->str;
+  g_string_free (new, FALSE);
+
+  return count;
+}
+
+static gboolean expr_add_compile (expression_t *expr, symbol_dict_t *dict, 
+				  char *str) {
+  char op;
+  double dval;
+  int i;
+  char *name;
+
+  while ((op = *str++)) {
+    switch (op) {
+    case 'c':			/* A constant. */
+      store_byte (expr, 'c');
+      sscanf (str, "%lf%n", &dval, &i);
+      str += i;
+      store_double (expr, dval);
+      str++;			/* Skip ';' */
+      break;
+
+    case 'f':			/* A function call. */
+      store_byte (expr, 'f');
+      str += load_name (str, &name);
+      i = function_lookup (name);
+      if (i < 0) return FALSE;	/* Fail on error. */
+      store_int (expr, i);
+      g_free (name);
+      str++;			/* Skip ';' */
+      break;
+
+    case 'l':			/* Load a variable. */
+    case 's':			/* Store a variable. */
+      store_byte (expr, op);
+      str += load_name (str, &name);
+      i = dict_lookup (dict, name);
+      store_int (expr, i);
+      g_free (name);
+      str++;			/* Skip ';' */
+      break;
+
+    default:			/* Copy verbatim. */
+      store_byte (expr, op);
+      break;
+    }
+  }
+
+  return TRUE;
+}
+     
+expression_t *expr_compile_string (const char* str, symbol_dict_t *dict)
+{
+  parser_control pc;
+  VFSFile *stream;
+
+  g_return_val_if_fail(str != NULL && dict != NULL, NULL);
+
+  stream = aud_vfs_buffer_new_from_string ( (char *) str );
+
+  pc.input = stream;
+  pc.expr = expr_new ();
+  pc.dict = dict;
+
+  if (yyparse (&pc) != 0) {
+    /* Check for error. */
+    expr_free (pc.expr);
+    pc.expr = NULL;
+  }
+
+  aud_vfs_fclose (stream);
+
+  return pc.expr;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/parser.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,42 @@
+/* parser.h -- header file for libexp
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef Included_PARSER_H
+#define Included_PARSER_H
+
+#include <glib.h>
+#include <stdio.h>
+#include <audacious/plugin.h>
+#include <audacious/vfs_buffer.h>
+
+#include "execute.h"
+
+/* Structure passed do yyparse. */
+typedef struct {
+  VFSFile *input;
+  expression_t *expr;
+  symbol_dict_t *dict;
+} parser_control;
+
+/* Prototypes. */
+expression_t *expr_compile_string (const char *str, symbol_dict_t *dict);
+
+#endif /* Included_PARSER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/parser.yacc	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,298 @@
+/* parser.y -- Bison parser for libexp
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+/* suppress conflict warnings */
+%expect 37
+
+/* C declarations. */
+%{
+#include <ctype.h>
+#include <glib.h>
+#include <locale.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "dict.h"
+#include "execute.h"
+#include "function.h"
+#include "parser.h"
+#include "storage.h"
+
+#define YYPARSE_PARAM yyparam
+#define YYLEX_PARAM yyparam
+
+static gboolean expr_add_compile (expression_t *expr, symbol_dict_t *dict,
+				  char *str);
+
+#define GENERATE(str) if (!expr_add_compile (((parser_control *)yyparam)->expr, \
+				        ((parser_control *)yyparam)->dict, str)) \
+                   YYABORT;
+%}
+
+%pure_parser
+     
+/* Data types. */
+%union {
+char *s_value;
+char c_value;
+double d_value;
+int i_value;
+}
+
+/* Terminal symbols. */     
+%token <s_value> NAME
+%token <d_value> NUMBER
+
+/* Precedence rules. */     
+%right '='
+%left '-' '+'
+%left '*' '/'
+%left NEG
+%right '^'
+     
+/* Grammar follows */
+%%
+
+/* Input consits of a (possibly empty) list of expressions. */
+input:			/* empty */
+			| input expression_list
+;
+
+/* expression_list is a ';' separated list of expressions. */
+expression_list:	/* empty */
+    			| expression
+			    { } 
+                        | expression_list ';'
+    			| error ';'	
+			    { yyerrok; }
+
+/* argument list is a comma separated list od expressions */
+argument_list:
+			expression
+                            {
+                            }
+                        | argument_list ',' expression
+                            {
+                            }
+     
+/* expression is a C-like expression. */
+expression:		NUMBER
+			    { 
+                              char *buf = g_strdup_printf ("c%f:", $1);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            }
+		        | NAME
+			    { 
+                              char *buf = g_strdup_printf ("l%s:", $1);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            }
+    			| NAME '=' expression
+			    { 
+                              char *buf = g_strdup_printf ("s%s:", $1);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            }
+                        | NAME '(' argument_list ')'
+                            {
+                              char *buf = g_strdup_printf ("f%s:", $1);
+                              GENERATE (buf); 
+                              g_free (buf);
+                            }
+
+			| expression '>' expression
+			    { GENERATE (">"); }
+			| expression '<' expression
+			    { GENERATE ("<"); }
+
+			| expression '+' expression
+			    { GENERATE ("+"); }
+			| expression '-' expression
+			    { GENERATE ("-"); }
+			| expression '*' expression
+			    { GENERATE ("*"); }
+			| expression '/' expression
+			    { GENERATE ("/"); }
+			| '-' expression %prec NEG
+			    { GENERATE ("n"); }
+			| expression '^' expression
+			    { GENERATE ("^"); }
+			| '(' expression ')'
+			    { }
+;
+
+%%
+/* End of grammar */
+
+/* Called by yyparse on error. */
+int yyerror (char *s) {
+  /* Ignore errors, just print a warning. */
+  g_warning ("%s\n", s);
+  return 0;
+}
+
+int yylex (YYSTYPE *yylval, void *yyparam) {
+  int c;
+  parser_control *pc = (parser_control *) yyparam;
+  
+  /* Ignore whitespace, get first nonwhite character. */
+  while ((c = vfs_getc (pc->input)) == ' ' || c == '\t' || c == '\n');
+  
+  /* End of input ? */
+  if (c == EOF)
+    return 0;
+
+  /* Char starts a number => parse the number. */
+  if (isdigit (c)) {
+    vfs_fseek (pc->input, -1, SEEK_CUR); /* Put the char back. */
+    {
+      char *old_locale, *saved_locale;
+
+      old_locale = setlocale (LC_ALL, NULL);
+      saved_locale = g_strdup (old_locale);
+      setlocale (LC_ALL, "C");
+      sscanf (((VFSBuffer *)(pc->input->handle))->iter, "%lf", &yylval->d_value);
+
+      while (isdigit(c) || c == '.')
+      {
+        c = vfs_getc(pc->input);
+      }
+
+      vfs_fseek(pc->input, -1, SEEK_CUR);
+
+      setlocale (LC_ALL, saved_locale);
+      g_free (saved_locale);
+    }
+    return NUMBER;
+  }
+     
+  /* Char starts an identifier => read the name. */
+  if (isalpha (c)) {
+    GString *sym_name;
+
+    sym_name = g_string_new (NULL);
+    
+    do {
+      sym_name = g_string_append_c (sym_name, c);
+
+      /* Get another character. */
+      c = vfs_getc (pc->input);
+    } while (c != EOF && isalnum (c));
+    
+    vfs_fseek (pc->input, -1, SEEK_CUR);
+
+    yylval->s_value = sym_name->str;
+    
+    g_string_free (sym_name, FALSE);
+    
+    return NAME;
+  }
+
+  /* Any other character is a token by itself. */
+  return c;
+}
+
+static int load_name (char *str, char **name) {
+  int count = 0;
+  GString *new = g_string_new (NULL);
+
+  while (*str != 0 && *str != ':') {
+    g_string_append_c (new, *str++);
+    count++;
+  }
+
+  *name = new->str;
+  g_string_free (new, FALSE);
+
+  return count;
+}
+
+static gboolean expr_add_compile (expression_t *expr, symbol_dict_t *dict, 
+				  char *str) {
+  char op;
+  double dval;
+  int i;
+  char *name;
+
+  while ((op = *str++)) {
+    switch (op) {
+    case 'c':			/* A constant. */
+      store_byte (expr, 'c');
+      sscanf (str, "%lf%n", &dval, &i);
+      str += i;
+      store_double (expr, dval);
+      str++;			/* Skip ';' */
+      break;
+
+    case 'f':			/* A function call. */
+      store_byte (expr, 'f');
+      str += load_name (str, &name);
+      i = function_lookup (name);
+      if (i < 0) return FALSE;	/* Fail on error. */
+      store_int (expr, i);
+      g_free (name);
+      str++;			/* Skip ';' */
+      break;
+
+    case 'l':			/* Load a variable. */
+    case 's':			/* Store a variable. */
+      store_byte (expr, op);
+      str += load_name (str, &name);
+      i = dict_lookup (dict, name);
+      store_int (expr, i);
+      g_free (name);
+      str++;			/* Skip ';' */
+      break;
+
+    default:			/* Copy verbatim. */
+      store_byte (expr, op);
+      break;
+    }
+  }
+
+  return TRUE;
+}
+     
+expression_t *expr_compile_string (const char* str, symbol_dict_t *dict)
+{
+  parser_control pc;
+  VFSFile *stream;
+
+  g_return_val_if_fail(str != NULL && dict != NULL, NULL);
+
+  stream = vfs_buffer_new_from_string ( (char *) str );
+
+  pc.input = stream;
+  pc.expr = expr_new ();
+  pc.dict = dict;
+
+  if (yyparse (&pc) != 0) {
+    /* Check for error. */
+    expr_free (pc.expr);
+    pc.expr = NULL;
+  }
+
+  vfs_fclose (stream);
+
+  return pc.expr;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/storage.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,79 @@
+/* storage.c --
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+ 
+#include <glib.h>
+#include <stddef.h>
+ 
+#include "storage.h"
+
+/* Code block. */
+
+expression_t *expr_new (void) {
+  expression_t *new_expr;
+
+  new_expr = (expression_t *)g_malloc (sizeof(expression_t));
+  new_expr->data = g_string_new (NULL);
+  return new_expr;
+}
+
+void expr_free (expression_t *expr) {
+  if (!expr)
+    return;
+
+  g_string_free (expr->data, TRUE);
+  g_free (expr);
+}
+
+static void load_data (char *str, void *dest, size_t size) {
+  char *ch = (char *)dest;
+  while (size--)
+    *ch++ = *str++;
+}
+
+int load_int (char *str) {
+  int val;
+  load_data (str, &val, sizeof(val));
+  return val;
+}
+
+double load_double (char *str) {
+  double val;
+  load_data (str, &val, sizeof(val));
+  return val;
+}
+
+static void store_data (expression_t *expr, void *src, size_t size) {
+  char *ch = (char *)src;
+  while (size--)
+    store_byte (expr, *ch++);
+}
+
+void store_byte (expression_t *expr, char byte) {
+  g_string_append_c (expr->data, byte);
+}
+
+void store_int (expression_t *expr, int val) {
+  store_data (expr, &val, sizeof(val));
+}
+
+void store_double (expression_t *expr, double val) {
+  store_data (expr, &val, sizeof(val));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/libcalc/storage.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,42 @@
+/* storage.h -- 
+ *
+ * Copyright (C) 2001 Janusz Gregorczyk <jgregor@kki.net.pl>
+ *
+ * This file is part of xvs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#ifndef Included_STORAGE_H
+#define Included_STORAGE_H
+
+#include <glib.h>
+
+typedef struct {
+  GString *data;
+} expression_t;
+
+/* Expr block. */
+expression_t *expr_new (void);
+void expr_free (expression_t *expr);
+
+int load_int (char *str);
+double load_double (char *str);
+
+void store_byte (expression_t *expr, char byte);
+void store_int (expression_t *expr, int val);
+void store_double (expression_t *expr, double val);
+
+#endif /* Included_STORAGE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/misc.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,145 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "pn_utils.h"
+
+/* ******************** misc_floater ******************** */
+static struct pn_actuator_option_desc misc_floater_opts[] =
+{
+  { "value", "The colour value for the floater.",
+    OPT_TYPE_INT, { ival: 255 } },
+  { NULL }
+};
+
+typedef enum
+{
+  float_up    = 0x1,
+  float_down  = 0x2,
+  float_left  = 0x4,
+  float_right = 0x8,
+} FloaterDirection;
+
+struct floater_state_data
+{
+  FloaterDirection dir;
+  gint x;
+  gint y;
+};
+
+static void
+misc_floater_init(gpointer *data)
+{
+  struct floater_state_data *opaque_data = g_new0(struct floater_state_data, 1);
+  *data = opaque_data;
+  opaque_data->x = rand() % pn_image_data->width;
+  opaque_data->y = rand() % pn_image_data->height;
+  opaque_data->dir = (FloaterDirection) rand() % 15; /* sum of all dir values */
+}
+
+static void
+misc_floater_cleanup(gpointer data)
+{
+  g_free(data);
+}
+
+/*
+ * This implementation isn't very great.
+ * Anyone want to improve it? :(
+ */
+static void
+misc_floater_exec(const struct pn_actuator_option *opts, gpointer data)
+{
+  struct floater_state_data *opaque_data = (struct floater_state_data *) data;
+  guchar value = (opts[0].val.ival < 0 || opts[0].val.ival > 255) ? 255 : opts[0].val.ival;
+
+  /* determine the root coordinate first */
+  if (opaque_data->dir & float_up)
+    opaque_data->y -= 1;
+  if (opaque_data->dir & float_down)
+    opaque_data->y += 1;
+
+  if (opaque_data->dir & float_left)
+    opaque_data->x -= 1;
+  if (opaque_data->dir & float_right)
+    opaque_data->x += 1;
+
+  /* make sure we're within surface boundaries. segfaults suck, afterall. */
+  if (opaque_data->x + 1 <= pn_image_data->width &&
+       opaque_data->x - 1 >= 0 &&
+       opaque_data->y + 1 <= pn_image_data->height &&
+       opaque_data->y - 1 >= 0)
+    {
+      /* draw it. i could use a loop here, but i don't see much reason in it,
+       * so i don't think i will at this time.  -nenolod
+       */
+      pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x, opaque_data->y)]     = value;
+      pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x + 1, opaque_data->y)] = value;
+      pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x - 1, opaque_data->y)] = value;
+      pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x, opaque_data->y + 1)] = value;
+      pn_image_data->surface[0][PN_IMG_INDEX(opaque_data->x, opaque_data->y - 1)] = value;
+    }
+
+  /* check if we need to change direction yet, and if so, do so. */
+  if (pn_new_beat == TRUE)
+    opaque_data->dir = (FloaterDirection) rand() % 15; /* sum of all dir values */
+
+  /* now adjust the direction so we stay in boundary */
+  if (opaque_data->x - 1 <= 0 && opaque_data->dir & float_left)
+    {
+      opaque_data->dir &= ~float_left;
+      opaque_data->dir |= float_right;
+    }
+
+  if (opaque_data->x + 1 >= pn_image_data->width && opaque_data->dir & float_right)
+    {
+      opaque_data->dir &= ~float_right;
+      opaque_data->dir |= float_left;
+    }
+
+  if (opaque_data->y - 1 <= 0 && opaque_data->dir & float_up)
+    {
+      opaque_data->dir &= ~float_up;
+      opaque_data->dir |= float_down;
+    }
+
+  if (opaque_data->y + 1 >= pn_image_data->height && opaque_data->dir & float_down)
+    {
+      opaque_data->dir &= ~float_down;
+      opaque_data->dir |= float_up;
+    }
+}
+
+struct pn_actuator_desc builtin_misc_floater =
+{
+  "misc_floater",
+  "Floating Particle",
+  "A floating particle.",
+  0, misc_floater_opts,
+  misc_floater_init, misc_floater_cleanup, misc_floater_exec
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/paranormal.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,214 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <SDL.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+
+/* SDL stuffs */
+SDL_Surface *screen;
+
+/* Globals */
+struct pn_rc         *pn_rc;
+struct pn_image_data *pn_image_data;
+struct pn_sound_data *pn_sound_data;
+
+/* Trig Pre-Computes */
+float sin_val[360];
+float cos_val[360];
+
+gboolean pn_new_beat;
+
+/* **************** drawing doodads **************** */
+
+static void
+blit_to_screen (void)
+{
+  SDL_GL_SwapBuffers();
+}
+
+static void
+resize_video (guint w, guint h)
+{
+  pn_image_data->width = w;
+  pn_image_data->height = h;
+
+  SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+  SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+  SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+  screen = SDL_SetVideoMode (w, h, 8, SDL_OPENGL | SDL_RESIZABLE);
+  if (! screen)
+    pn_fatal_error ("Unable to create a new SDL window: %s",
+		    SDL_GetError ());
+
+  glViewport(0, 0, w, h);
+  glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
+  glClearDepth(1.0f);
+}
+
+static void
+take_screenshot (void)
+{
+  char fname[32];
+  struct stat buf;
+  int i=0;
+
+  do
+    sprintf (fname, "pn_%05d.bmp", ++i);
+  while (stat (fname, &buf) == 0);
+
+  SDL_SaveBMP (screen, fname);
+}
+
+/* FIXME: This should resize the video to a user-set
+   fullscreen res */
+static void
+toggle_fullscreen (void)
+{
+  SDL_WM_ToggleFullScreen (screen);  
+  if (SDL_ShowCursor (SDL_QUERY) == SDL_ENABLE)
+    SDL_ShowCursor (SDL_DISABLE);
+  else
+    SDL_ShowCursor (SDL_ENABLE);
+}
+
+/* **************** basic renderer management **************** */
+void
+pn_init (void)
+{
+  int i;
+#ifdef FULLSCREEN_HACK
+  char SDL_windowhack[32];
+  GdkScreen *screen;
+#endif
+
+  pn_sound_data = g_new0 (struct pn_sound_data, 1);
+  pn_image_data = g_new0 (struct pn_image_data, 1);
+
+#ifdef FULLSCREEN_HACK
+  screen = gdk_screen_get_default();
+  sprintf(SDL_windowhack,"SDL_WINDOWID=%d",
+          GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(screen)));
+          putenv(SDL_windowhack);
+#endif
+
+  if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0)
+    pn_fatal_error ("Unable to initialize SDL: %s", SDL_GetError ());
+
+#ifndef FULLSCREEN_HACK
+  resize_video (640, 360);
+#else
+  resize_video (1280, 1024);
+#endif
+
+  SDL_WM_SetCaption ("Paranormal Visualization Studio", PACKAGE);
+
+  for(i=0; i<360; i++)
+    {
+      sin_val[i] = sin(i*(M_PI/180.0));
+      cos_val[i] = cos(i*(M_PI/180.0));
+    }
+}
+
+void
+pn_cleanup (void)
+{
+  SDL_FreeSurface (screen);
+  SDL_Quit ();
+
+
+  if (pn_image_data)
+    {
+      if (pn_image_data->surface[0])
+	g_free (pn_image_data->surface[0]);
+      if (pn_image_data->surface[1])
+	g_free (pn_image_data->surface[1]);
+      g_free (pn_image_data);
+    }
+  if (pn_sound_data)
+    g_free (pn_sound_data);
+}
+
+/* Renders one frame and handles the SDL window */
+void
+pn_render (void)
+{
+  SDL_Event event;
+
+  /* Handle window events */
+  while (SDL_PollEvent (&event))
+    {
+      switch (event.type)
+	{
+	case SDL_QUIT:
+	  pn_quit ();
+	  g_assert_not_reached ();
+	case SDL_KEYDOWN:
+	  switch (event.key.keysym.sym)
+	    {
+	    case SDLK_ESCAPE:
+	      pn_quit ();
+	      g_assert_not_reached ();
+	    case SDLK_RETURN:
+	      if (event.key.keysym.mod & (KMOD_ALT | KMOD_META))
+		toggle_fullscreen ();
+	      break;
+	    case SDLK_BACKQUOTE:
+	      take_screenshot ();
+	      break;
+	    default:
+              break;
+	    }
+	  break;
+	case SDL_VIDEORESIZE:
+	  resize_video (event.resize.w, event.resize.h);	  
+	  break;
+	}
+    }
+
+  pn_new_beat = pn_is_new_beat();
+
+  if (pn_rc->actuator)
+    {
+      exec_actuator (pn_rc->actuator);
+      blit_to_screen ();
+    }
+}
+
+/* this MUST be called if a builtin's output is to surface[1]
+   (by the builtin, after it is done) */
+void
+pn_swap_surfaces (void)
+{
+   SDL_GL_SwapBuffers();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/paranormal.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,79 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _PARANORMAL_H
+#define _PARANORMAL_H
+
+#include <glib.h>
+#include <SDL.h>
+#include <SDL_opengl.h>
+
+#include "actuators.h"
+
+struct pn_sound_data
+{
+  gint16 pcm_data[2][512];
+  gint16 freq_data[2][256];
+};
+
+struct pn_image_data
+{
+  int width, height;
+  struct pn_color cmap[256];
+  guchar *surface[2];
+};
+
+/* The executable (ie xmms.c or standalone.c)
+   is responsible for allocating this and filling
+   it with default/saved values */
+struct pn_rc
+{
+  struct pn_actuator *actuator;
+};
+
+/* core funcs */
+void pn_init (void);
+void pn_cleanup (void);
+void pn_render (void);
+void pn_swap_surfaces (void);
+
+/* Implemented elsewhere (ie xmms.c or standalone.c) */
+void pn_set_rc ();
+void pn_fatal_error (const char *fmt, ...);
+void pn_error (const char *fmt, ...);
+void pn_quit (void);
+
+/* Implimented in cfg.c */
+void pn_configure (void);
+
+/* globals used for rendering */
+extern struct pn_rc         *pn_rc;
+extern struct pn_sound_data *pn_sound_data;
+extern struct pn_image_data *pn_image_data;
+
+extern gboolean pn_new_beat;
+
+/* global trig pre-computes */
+extern float sin_val[360];
+extern float cos_val[360];
+
+/* beat detection */
+int pn_is_new_beat(void);
+
+#endif /* _PARANORMAL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/plugin.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,469 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* FIXME: issues with not uniniting variables between
+   enables?  I wasn't too careful about that, but it
+   seems to work fine.  If there are problems perhaps
+   look for a bug there?
+*/
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <memory.h>
+#include <math.h>
+#include <setjmp.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <audacious/i18n.h>
+
+#include <gtk/gtk.h>
+#include <audacious/plugin.h>
+#include <audacious/util.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "presets.h"
+#include "containers.h"
+
+/* Error reporting dlg */
+static GtkWidget *err_dialog;
+
+/* Draw thread stuff */
+/* FIXME: Do I need mutex for pn_done? */
+static SDL_Thread *draw_thread = NULL;
+static SDL_mutex *sound_data_mutex;
+static SDL_mutex *config_mutex;
+
+static gboolean pn_done = FALSE;
+jmp_buf quit_jmp;
+gboolean timeout_set = FALSE;
+guint quit_timeout;
+
+/* Sound stuffs */
+static gboolean new_pcm_data = FALSE;
+static gboolean new_freq_data = FALSE;
+static gint16 tmp_pcm_data[2][512];
+static gint16 tmp_freq_data[2][256];
+
+/* XMMS interface */
+static void pn_xmms_init (void);
+static void pn_xmms_cleanup (void);
+static void pn_xmms_about (void);
+static void pn_xmms_configure (void);
+static void pn_xmms_render_pcm (gint16 data[2][512]);
+static void pn_xmms_render_freq (gint16 data[2][256]);
+
+static VisPlugin pn_vp = 
+{
+  .description = "Paranormal Visualization Studio",
+  .num_pcm_chs_wanted = 2,
+  .num_freq_chs_wanted = 2,
+  .init = pn_xmms_init,
+  .cleanup = pn_xmms_cleanup,
+  .about = pn_xmms_about,
+  .configure = pn_xmms_configure,
+  .render_pcm = pn_xmms_render_pcm,
+  .render_freq = pn_xmms_render_freq
+};
+
+VisPlugin *pn_vplist[] = { &pn_vp, NULL };
+
+DECLARE_PLUGIN(paranormal, NULL, NULL, NULL, NULL, NULL, NULL, pn_vplist,NULL);
+
+static void
+load_pn_rc (void)
+{
+  struct pn_actuator *a, *b;
+
+  if (! pn_rc)
+      pn_rc = g_new0 (struct pn_rc, 1);
+
+  /* load a default preset */
+  pn_rc->actuator = create_actuator ("container_simple");
+  if (! pn_rc->actuator) goto ugh;
+
+  a = create_actuator ("general_clear");
+  if (! a) goto ugh;
+  container_add_actuator (pn_rc->actuator, a);
+
+  a = create_actuator ("wave_horizontal");
+  if (! a) goto ugh;
+  container_add_actuator (pn_rc->actuator, a);
+
+  return;
+
+ ugh:
+  if (pn_rc->actuator)
+    destroy_actuator (pn_rc->actuator);
+  pn_error ("Error loading default preset");
+}
+
+static int
+draw_thread_fn (gpointer data)
+{
+  gfloat fps = 0.0;
+  guint last_time = 0, last_second = 0;
+  guint this_time;
+  pn_init ();
+
+  /* Used when pn_quit is called from this thread */
+  if (setjmp (quit_jmp) != 0)
+    pn_done = TRUE;
+
+  while (! pn_done)
+    {
+      SDL_mutexP (sound_data_mutex);
+      if (new_freq_data)
+	{
+	  memcpy (pn_sound_data->freq_data, tmp_freq_data,
+		  sizeof (gint16) * 2 * 256);
+	  new_freq_data = FALSE;
+	}
+      if (new_pcm_data)
+	{
+	  memcpy (pn_sound_data->pcm_data, tmp_pcm_data,
+		  sizeof (gint16) * 2 * 512);
+	  new_freq_data = FALSE;
+	}
+      SDL_mutexV (sound_data_mutex);
+      SDL_mutexP (config_mutex);
+      pn_render ();
+      SDL_mutexV (config_mutex);
+
+      /* Compute the FPS */
+      this_time = SDL_GetTicks ();
+
+      fps = fps * .95 + (1000. / (gfloat) (this_time - last_time)) * .05;
+      if (this_time > 2000 + last_second)
+        {
+          last_second = this_time;
+          g_print ("FPS: %f\n", fps);
+        }
+      last_time = this_time;
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+      sched_yield();
+#endif
+    }
+
+  /* Just in case a pn_quit () was called in the loop */
+/*    SDL_mutexV (sound_data_mutex); */
+
+  pn_cleanup ();
+
+  return 0;
+}
+
+/* Is there a better way to do this? this = messy
+   It appears that calling disable_plugin () in some
+   thread other than the one that called pn_xmms_init ()
+   causes a seg fault :( */
+static int
+quit_timeout_fn (gpointer data)
+{
+  if (pn_done)
+    {
+      pn_vp.disable_plugin (&pn_vp);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+pn_xmms_init (void)
+{
+  /* If it isn't already loaded, load the run control */
+  if (! pn_rc)
+	  load_pn_rc ();
+
+  sound_data_mutex = SDL_CreateMutex ();
+  config_mutex = SDL_CreateMutex ();
+  if (! sound_data_mutex)
+    pn_fatal_error ("Unable to create a new mutex: %s",
+		    SDL_GetError ());
+
+  pn_done = FALSE;
+  draw_thread = SDL_CreateThread (draw_thread_fn, NULL);
+  if (! draw_thread)
+    pn_fatal_error ("Unable to create a new thread: %s",
+		    SDL_GetError ());
+
+  /* Add a gtk timeout to test for quits */
+  quit_timeout = gtk_timeout_add (1000, quit_timeout_fn, NULL);
+  timeout_set = TRUE;
+}
+
+static void
+pn_xmms_cleanup (void)
+{
+  if (timeout_set)
+    {
+      gtk_timeout_remove (quit_timeout);
+      timeout_set = FALSE;
+    }
+
+  if (draw_thread)
+    {
+      pn_done = TRUE;
+      SDL_WaitThread (draw_thread, NULL);
+      draw_thread = NULL;
+    }
+
+  if (sound_data_mutex)
+    {
+      SDL_DestroyMutex (sound_data_mutex);
+      sound_data_mutex = NULL;
+    }
+
+  if (config_mutex)
+    {
+      SDL_DestroyMutex (config_mutex);
+      config_mutex = NULL;
+    }
+}
+
+static void
+about_close_clicked(GtkWidget *w, GtkWidget **window)
+{
+	gtk_widget_destroy(*window);
+	*window=NULL;
+}
+
+static void
+about_closed(GtkWidget *w, GdkEvent *e, GtkWidget **window)
+{
+	about_close_clicked(w,window);
+}
+
+static void
+pn_xmms_about (void)
+{
+  audacious_info_dialog("About Paranormal Visualization Studio", 
+
+"Paranormal Visualization Studio " VERSION "\n\n\
+Copyright (C) 2006, William Pitcock <nenolod -at- nenolod.net>\n\
+Portions Copyright (C) 2001, Jamie Gennis <jgennis -at- mindspring.com>\n\
+\n\
+This program is free software; you can redistribute it and/or modify\n\
+it under the terms of the GNU General Public License as published by\n\
+the Free Software Foundation; either version 2 of the License, or\n\
+(at your option) any later version.\n\
+\n\
+This program is distributed in the hope that it will be useful,\n\
+but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
+GNU General Public License for more details.\n\
+\n\
+You should have received a copy of the GNU General Public License\n\
+along with this program; if not, write to the Free Software\n\
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307\n\
+USA", _("Ok"), FALSE, NULL, NULL);
+}
+
+static void
+pn_xmms_configure (void)
+{
+  /* We should already have a GDK_THREADS_ENTER
+     but we need to give it config_mutex */
+  if (config_mutex)
+    SDL_mutexP (config_mutex);
+
+  if (! pn_rc)
+	  load_pn_rc ();
+
+  pn_configure ();
+
+  if (config_mutex)
+    SDL_mutexV (config_mutex);
+}
+
+static void
+pn_xmms_render_pcm (gint16 data[2][512])
+{
+  SDL_mutexP (sound_data_mutex);
+  memcpy (tmp_pcm_data, data, sizeof (gint16) * 2 * 512);
+  new_pcm_data = TRUE;
+  SDL_mutexV (sound_data_mutex);
+}
+
+static void
+pn_xmms_render_freq (gint16 data[2][256])
+{
+  SDL_mutexP (sound_data_mutex);
+  memcpy (tmp_freq_data, data, sizeof (gint16) * 2 * 256);
+  new_freq_data = TRUE;
+  SDL_mutexV (sound_data_mutex);
+}
+
+/* **************** paranormal.h stuff **************** */
+
+void
+pn_set_rc (struct pn_rc *new_rc)
+{
+  if (config_mutex)
+    SDL_mutexP (config_mutex);
+
+  if (! pn_rc)
+    load_pn_rc ();
+
+  if (pn_rc->actuator)
+    destroy_actuator (pn_rc->actuator);
+  pn_rc->actuator = new_rc->actuator;
+
+  if (config_mutex)
+    SDL_mutexV (config_mutex);
+}
+
+void
+pn_fatal_error (const char *fmt, ...)
+{
+  char *errstr;
+  va_list ap;
+  GtkWidget *dialog;
+  GtkWidget *close, *label;
+
+  /* Don't wanna try to lock GDK if we already have it */
+  if (draw_thread && SDL_ThreadID () == SDL_GetThreadID (draw_thread))
+    GDK_THREADS_ENTER ();
+
+  /* now report the error... */
+  va_start (ap, fmt);
+  errstr = g_strdup_vprintf (fmt, ap);
+  va_end (ap);
+
+  dialog=gtk_dialog_new();
+  gtk_window_set_title(GTK_WINDOW(dialog), "Error - Paranormal Visualization Studio - " VERSION);
+  gtk_container_border_width (GTK_CONTAINER (dialog), 8);
+
+  label=gtk_label_new(errstr);
+  fprintf (stderr, "%s\n", errstr);
+  g_free (errstr);
+
+  close = gtk_button_new_with_label ("Close");
+  gtk_signal_connect_object (GTK_OBJECT (close), "clicked",
+			     GTK_SIGNAL_FUNC (gtk_widget_destroy),
+			     GTK_OBJECT (dialog));
+
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, FALSE,
+		      FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), close,
+		      FALSE, FALSE, 0);
+  gtk_widget_show (label);
+  gtk_widget_show (close);
+
+  gtk_widget_show (dialog);
+  gtk_widget_grab_focus (dialog);
+
+  if (draw_thread && SDL_ThreadID () == SDL_GetThreadID (draw_thread))
+    GDK_THREADS_LEAVE ();
+
+  pn_quit ();
+}
+
+
+void
+pn_error (const char *fmt, ...)
+{
+  char *errstr;
+  va_list ap;
+  static GtkWidget *text;
+  static GtkTextBuffer *textbuf;
+
+  /* now report the error... */
+  va_start (ap, fmt);
+  errstr = g_strdup_vprintf (fmt, ap);
+  va_end (ap);
+  fprintf (stderr, "Paranormal-CRITICAL **: %s\n", errstr);
+
+  /* This is the easiest way of making sure we don't
+     get stuck trying to lock a mutex that this thread
+     already owns since this fn can be called from either
+     thread */
+  if (draw_thread && SDL_ThreadID () == SDL_GetThreadID (draw_thread))
+    GDK_THREADS_ENTER ();
+
+  if (! err_dialog)
+    {
+      GtkWidget *close;
+
+      err_dialog=gtk_dialog_new();
+      gtk_window_set_title (GTK_WINDOW (err_dialog), "Error - Paranormal Visualization Studio - " VERSION);
+      gtk_window_set_policy (GTK_WINDOW (err_dialog), FALSE, FALSE, FALSE);
+      gtk_widget_set_usize (err_dialog, 400, 200);
+      gtk_container_border_width (GTK_CONTAINER (err_dialog), 8);
+
+      textbuf = gtk_text_buffer_new(NULL);
+      text = gtk_text_view_new_with_buffer (textbuf);
+
+      close = gtk_button_new_with_label ("Close");
+      gtk_signal_connect_object (GTK_OBJECT (close), "clicked",
+				 GTK_SIGNAL_FUNC (gtk_widget_hide),
+				 GTK_OBJECT (err_dialog));
+      gtk_signal_connect_object (GTK_OBJECT (err_dialog), "delete-event",
+				 GTK_SIGNAL_FUNC (gtk_widget_hide),
+				 GTK_OBJECT (err_dialog));
+
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (err_dialog)->vbox), text, FALSE,
+			  FALSE, 0);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (err_dialog)->action_area), close,
+			  FALSE, FALSE, 0);
+      gtk_widget_show (text);
+      gtk_widget_show (close);
+    }
+
+  gtk_text_buffer_set_text(GTK_TEXT_BUFFER(textbuf), errstr, -1);
+  g_free (errstr);
+
+  gtk_widget_show (err_dialog);
+  gtk_widget_grab_focus (err_dialog);
+
+  if (draw_thread && SDL_ThreadID () == SDL_GetThreadID (draw_thread))
+    GDK_THREADS_LEAVE ();
+}
+
+
+/* This is confusing...
+   Don't call this from anywhere but the draw thread or
+   the initialization xmms thread (ie NOT the xmms sound
+   data functions) */
+void
+pn_quit (void)
+{
+  if (draw_thread && SDL_ThreadID () == SDL_GetThreadID (draw_thread))
+    {
+      /* We're in the draw thread so be careful */
+      longjmp (quit_jmp, 1);
+    }
+  else
+    {
+      /* We're not in the draw thread, so don't sweat it...
+	 addendum: looks like we have to bend over backwards (forwards?)
+	 for xmms here too */
+      pn_vp.disable_plugin (&pn_vp);
+      while (1)
+	gtk_main_iteration ();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/pn_utils.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,34 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _PN_UTILS_H
+#define _PN_UTILS_H
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define CAP(i,c) (i > c ? c : i < -(c) ? -(c) : i)
+#define CAPHILO(i,h,l) (i > h ? h : i < l ? l : i)
+#define CAPHI(i,h) (i > h ? h : i)
+#define CAPLO(i,l) (i < l ? l : i)
+
+#define PN_IMG_INDEX(x,y) ((x) + (pn_image_data->width * (y)))
+
+#endif /* _PN_UTILS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,278 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* FIXME: add documentation support to preset files */
+/* FIXME: add multiple-presets-per-file support (maybe) */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "containers.h"
+
+/* cur->name should be the actuator name */
+static void
+parse_actuator (xmlNodePtr cur, struct pn_actuator *a)
+{
+  int i;
+  char *content;
+  struct pn_actuator *child;
+
+  for (cur = cur->xmlChildrenNode; cur; cur = cur->next)
+    {
+      if (xmlIsBlankNode (cur) || cur->type != XML_ELEMENT_NODE)
+	continue;
+
+      /* see if it's an option */
+      for (i=0; a->options && a->options[i].desc; i++)
+	if (! xmlStrcmp (cur->name,
+			 (const xmlChar *) a->options[i].desc->name))
+	  break;
+
+      if (a->options && a->options[i].desc)
+	{
+	  /* it is an option, so let's set it! */
+	  content = (char*)xmlNodeGetContent (cur);
+
+	  /* FIXME: warning? */
+	  if (! content)
+	    continue;
+
+	  /* FIXME: perhaps do a little better job of error checking? */
+	  switch (a->options[i].desc->type)
+	    {
+	    case OPT_TYPE_INT:
+	      a->options[i].val.ival = (int)strtol (content, NULL, 0);
+	      break;
+	    case OPT_TYPE_FLOAT:
+	      a->options[i].val.fval = (float)strtod (content, NULL);
+	      break;
+	    case OPT_TYPE_STRING:
+	      a->options[i].val.sval = g_strdup (content);
+	      break;
+	    case OPT_TYPE_COLOR:
+	      {
+		guint r,g,b;
+		char *s = content+1;
+		r = strtoul (s, &s, 0);
+		if (r > 255 || ! (s = strchr (s, ',')))
+		  goto bad_color;
+		g = strtoul (s+1, &s, 0);
+		if (g > 255 || ! (s = strchr (s, ',')))
+		  goto bad_color;
+		b = strtoul (s+1, NULL, 0);
+		if (b > 255)
+		  goto bad_color;
+
+		a->options[i].val.cval.r = (guchar)r;
+		a->options[i].val.cval.g = (guchar)g;
+		a->options[i].val.cval.b = (guchar)b;
+
+		break;
+	      }
+	    bad_color:
+	      pn_error ("parse error: invalid color value: option \"%s\" ignored.\n"
+			"  correct syntax: (r,g,b) where r, g, and b are the\n"
+			"  red, green, and blue components of the "
+			"color, respectively", cur->name);
+	      break;
+	      
+	    case OPT_TYPE_COLOR_INDEX:
+	      {
+		int c = (int)strtol (content, NULL, 0);
+		if (c < 0 || c > 255)
+		  pn_error ("parse error: invalid color index \"%s\" (%d): option ignored.\n"
+			    "  the value must be between 0 and 255",
+			    cur->name, c);
+		else
+		  a->options[i].val.ival = c;
+		break;
+	      }
+	    case OPT_TYPE_BOOLEAN:
+	      {
+		char *c, *d;
+		for (c=content; isspace (*c); c++);
+		for (d=c; !isspace(*d); d++);
+		*d = '\0';
+		if (g_strcasecmp (c, "true") == 0)
+		  a->options[i].val.bval = TRUE;
+		else if (g_strcasecmp (c, "false") == 0)
+		  a->options[i].val.bval = FALSE;
+		else
+		  pn_error ("parse error: invalid boolean value \"%s\" (%s): option ignored.\n"
+			    "  the value must be either 'true' or 'false'",
+			    cur->name, c);
+	      }
+	    }
+
+	  /* gotta free content */
+	  xmlFree ((xmlChar*)content);
+	}
+      /* See if we have a child actuator */
+      else if (a->desc->flags & ACTUATOR_FLAG_CONTAINER
+	       && (child = create_actuator ((char*)cur->name)))
+	{
+	  container_add_actuator (a, child);
+	  parse_actuator (cur, child);
+	}
+      else
+	/* We have an error */
+	pn_error ("parse error: unknown entity \"%s\": ignored.", cur->name);
+    }
+}
+
+struct pn_actuator *
+load_preset (const char *filename)
+{
+  xmlDocPtr doc;
+  xmlNodePtr cur;
+  struct pn_actuator *a = NULL;
+
+  doc = xmlParseFile (filename);
+  if (! doc)
+    return NULL;
+
+  cur = xmlDocGetRootElement (doc);
+  if (! cur)
+    xmlFreeDoc (doc);
+
+  if (xmlStrcmp (cur->name, (const xmlChar *) "paranormal_preset"))
+    {
+      xmlFreeDoc (doc);
+      return NULL;
+    }
+
+  for (cur = cur->children; cur; cur = cur->next)
+    {
+      if (xmlIsBlankNode (cur) || cur->type != XML_ELEMENT_NODE)
+	continue;
+
+      /* if (...) { ... } else if (is_documentation [see top of file]) ... else */
+      {
+	a = create_actuator ((char*)cur->name);
+
+	/* FIXME: warn? */
+	if (! a)
+	  continue;
+
+	parse_actuator (cur, a);
+	break;
+      }
+    }
+
+  /* Don't need this any longer */
+  xmlFreeDoc (doc);
+
+  return a;
+}
+
+/* FIXME: do the file writing w/ error checking */
+static gboolean
+save_preset_recursive (FILE *file, const struct pn_actuator *actuator,
+		       int recursion_depth)
+{
+  int i;
+  GSList *child;
+
+  /* open this actuator */
+  fprintf (file, "%*s<%s>\n", recursion_depth, "", actuator->desc->name);
+
+  /* options */
+  if (actuator->options)
+    for (i=0; actuator->options[i].desc; i++)
+      {
+	fprintf (file, "%*s <%s> ", recursion_depth, "",
+		 actuator->desc->option_descs[i].name);
+	switch (actuator->desc->option_descs[i].type)
+	  {
+	  case OPT_TYPE_INT:
+	  case OPT_TYPE_COLOR_INDEX:
+	    fprintf (file, "%d", actuator->options[i].val.ival);
+	    break;
+	  case OPT_TYPE_FLOAT:
+	    fprintf (file, "%.5f", actuator->options[i].val.fval);
+	    break;
+	  case OPT_TYPE_STRING:
+	    fprintf (file, "%s", actuator->options[i].val.sval);
+	    break;
+	  case OPT_TYPE_COLOR:
+	    fprintf (file, "%d, %d, %d", actuator->options[i].val.cval.r,
+		     actuator->options[i].val.cval.g,
+		     actuator->options[i].val.cval.b);
+	    break;
+	  case OPT_TYPE_BOOLEAN:
+	    if (actuator->options[i].val.bval)
+	      fprintf (file, "TRUE");
+	    else
+	      fprintf (file, "FALSE");
+	    break;
+	  }
+	fprintf (file, " </%s>\n", actuator->desc->option_descs[i].name);
+      }
+
+  /* children */
+  if (actuator->desc->flags & ACTUATOR_FLAG_CONTAINER)
+    for (child = *(GSList **)actuator->data; child; child = child->next)
+      if (! save_preset_recursive (file, (struct pn_actuator*) child->data,
+				   recursion_depth+1))
+	return FALSE;
+
+  /* close the actuator */
+  fprintf (file, "%*s</%s>\n", recursion_depth, "", actuator->desc->name);
+
+  return TRUE;
+}
+
+gboolean
+save_preset (const char *filename, const struct pn_actuator *actuator)
+{
+  FILE *file;
+
+  file = fopen (filename, "w");
+  if (! file)
+    {
+      pn_error ("fopen: %s", strerror (errno));
+      return FALSE;
+    }
+
+  fprintf (file, "<?xml version=\"1.0\"?>\n\n<paranormal_preset>\n");
+
+  if (actuator)
+    if (! save_preset_recursive (file, actuator, 1))
+      {
+	fclose (file);
+	return FALSE;
+      }
+
+  fprintf (file, "</paranormal_preset>");
+
+  fclose (file);
+
+  return TRUE;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets.h	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,30 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _PRESETS_H
+#define _PRESETS_H
+
+#include <glib.h>
+
+#include "actuators.h"
+
+struct pn_actuator *load_preset (const char *filename);
+gboolean save_preset (const char *filename, const struct pn_actuator *actuator);
+
+#endif /* _PRESETS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/Makefile	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,38 @@
+DATA = nazca_-_smoke_on_the_water.pnv		\
+       nenolod_-_3d_wave.pnv			\
+       nenolod_-_aquamarine_dream.pnv		\
+       nenolod_-_purple_flower.pnv		\
+       nenolod_-_bumblebees.pnv			\
+       nenolod_-_flying_into_pastels.pnv	\
+       nenolod_-_phosphor_flame.pnv		\
+       nenolod_-_psuedo_starfield.pnv		\
+       nenolod_-_quakingscope.pnv		\
+       nenolod_-_beatscope.pnv			\
+       nenolod_-_branchscope.pnv		\
+       nenolod_-_retroscope.pnv			\
+       nenolod_-_technicolour_nightmare.pnv	\
+       nenolod_-_trapped.pnv			\
+       nenolod_-_value_replace_fun.pnv		\
+       nenolod_-_rush.pnv			\
+       nenolod_-_worms.pnv			\
+       nenolod_-_scopefun.pnv			\
+       nenolod_-_smoke.pnv			\
+       nenolod_-_swarm.pnv			\
+       nenolod_-_interlaced.pnv			\
+       nenolod_-_cubism.pnv			\
+       nenolod_-_transform_fun.pnv		\
+       nenolod_-_tunnel_vision.pnv		\
+       nenolod_-_kaliedoscope.pnv		\
+       nenolod_-_simple_yet_pretty.pnv		\
+       nenolod_-_quasar.pnv			\
+       aerdan_-_bloody_vortex.pnv		\
+       aerdan_-_cloudscape.pnv			\
+       aerdan_-_cloudscape2.pnv			\
+       aerdan_-_dancing_snow.pnv		\
+       aerdan_-_portal_to_hell.pnv		\
+       aerdan_-_telestatic.pnv			\
+       ticpu_-_colored_beat-o-scope.pnv	
+
+include ../../../buildsys.mk
+
+PACKAGE = audacious/paranormal/Presets
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_bloody_vortex.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <general_clear>
+   </general_clear>
+   <cmap_gradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <lcolor> 255, 64, 0 </lcolor>
+    <hcolor> 128, 0, 0 </hcolor>
+   </cmap_gradient>
+  </container_once>
+  <general_fade>
+   <amount> 4 </amount>
+  </general_fade>
+  <general_blur>
+  </general_blur>
+  <general_mosaic>
+   <radius> 3 </radius>
+  </general_mosaic>
+  <wave_radial>
+   <base_radius> 39.00000 </base_radius>
+   <value> 255 </value>
+  </wave_radial>
+  <xform_spin>
+   <angle> -2.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.94000 </r_scale>
+  </xform_spin>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_cloudscape.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 220, 225, 225 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> 0 </channels>
+   <value> 251 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.96500 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_cloudscape2.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 220, 225, 225 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 245 </high_index>
+    <color> 180, 180, 180 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> 0 </channels>
+   <value> 250 </value>
+   <lines> FALSE </lines>
+  </wave_horizontal>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.12500 </r_add>
+   <r_scale> 0.96500 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 255 </value>
+   <lines> FALSE </lines>
+  </wave_horizontal>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_dancing_snow.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 146, 191, 225 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.96500 </r_scale>
+  </xform_spin>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+  <wave_radial>
+   <base_radius> 1.00000 </base_radius>
+   <value> 250 </value>
+  </wave_radial>
+  <general_blur>
+  </general_blur>
+  <freq_drops>
+  </freq_drops>
+  <xform_bump_spin>
+   <angle> 0.00000 </angle>
+   <bumps> 10.00000 </bumps>
+   <base_scale> 0.95000 </base_scale>
+   <mod_scale> 0.10000 </mod_scale>
+  </xform_bump_spin>
+  <xform_spin>
+   <angle> -5.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.96500 </r_scale>
+  </xform_spin>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_portal_to_hell.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 128, 85, 0 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+  <general_blur>
+  </general_blur>
+  <xform_ripple>
+   <angle> 0.00000 </angle>
+   <ripples> 10.00000 </ripples>
+   <base_speed> 2.00000 </base_speed>
+   <mod_speed> 1.00000 </mod_speed>
+  </xform_ripple>
+  <wave_radial>
+   <base_radius> 1.50000 </base_radius>
+   <value> 250 </value>
+  </wave_radial>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.96500 </r_scale>
+  </xform_spin>
+  <freq_drops>
+  </freq_drops>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_stonervision.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <wave_smooth>
+    <channels> 0 </channels>
+   </wave_smooth>
+   <cmap_dynamic>
+    <low_index> 5 </low_index>
+    <high_index> 250 </high_index>
+    <script> red = red + 0.05; blue = blue + 0.03; green = green + 0.01; </script>
+   </cmap_dynamic>
+  </container_once>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+  <wave_radial>
+   <base_radius> -1.00000 </base_radius>
+   <value> 253 </value>
+  </wave_radial>
+  <xform_ripple>
+   <angle> 0.00000 </angle>
+   <ripples> 8.00000 </ripples>
+   <base_speed> 2.00000 </base_speed>
+   <mod_speed> 5.00000 </mod_speed>
+  </xform_ripple>
+  <misc_floater>
+   <value> 256 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <misc_floater>
+   <value> 255 </value>
+  </misc_floater>
+  <wave_scope>
+   <init_script> n = 800; t = -0.05; </init_script>
+   <frame_script> t = t + 0.05; </frame_script>
+   <sample_script> d = index + value; r = t + index * 3.141952924 * 4; x = cos(r) * d; y = sin(r) * d; </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/aerdan_-_telestatic.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 220, 225, 225 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> 0 </channels>
+   <value> 251 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.96500 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+  <xform_halfrender>
+   <direction> -1 </direction>
+  </xform_halfrender>
+  <freq_drops>
+  </freq_drops>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nazca_-_smoke_on_the_water.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <general_clear>
+   </general_clear>
+  </container_once>
+  <cmap_gradient>
+   <low_index> 0 </low_index>
+   <high_index> 255 </high_index>
+   <lcolor> 0, 0, 0 </lcolor>
+   <hcolor> 72, 72, 255 </hcolor>
+  </cmap_gradient>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 255 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <wave_horizontal>
+   <channels> 1 </channels>
+   <value> 255 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_ripple>
+   <angle> 0.00000 </angle>
+   <ripples> 7.00000 </ripples>
+   <base_speed> 1.00000 </base_speed>
+   <mod_speed> 1.00000 </mod_speed>
+  </xform_ripple>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_3d_wave.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 191, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_scope>
+   <init_script>  n=7;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p;  </init_script>
+   <frame_script>  ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3);  </frame_script>
+   <sample_script>  x1=value*sin(p2*index);y1=value * index / cos(z1);z1=r*cos(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst);  </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <general_fade>
+   <amount> 10 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_aquamarine_dream.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 161, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_normalize>
+   <height> -1 </height>
+   <hfrac> -1.00000 </hfrac>
+   <vfrac> 0.12500 </vfrac>
+   <channels> 0 </channels>
+  </wave_normalize>
+  <wave_scope>
+   <init_script> n = 800; t = -0.05; </init_script>
+   <frame_script> t = t + 0.05; </frame_script>
+   <sample_script> d = index + value; r = t + index * 3.141952924 * 4; x = cos(r) * d; y = sin(r) * d; </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <general_blur>
+  </general_blur>
+  <xform_movement>
+   <formula>  r = sin(r); d = cos(d)^2;  </formula>
+   <polar> TRUE </polar>
+  </xform_movement>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 8 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_beatscope.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 138 </high_index>
+    <color> 119, 239, 163 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 139 </low_index>
+    <high_index> 255 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+  </wave_horizontal>
+  <general_blur>
+  </general_blur>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <xform_spin>
+    <angle> 0.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 1.04000 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> 0.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.98700 </r_scale>
+   </xform_spin>
+   <container_cycle>
+    <change_interval> 0 </change_interval>
+    <beat> TRUE </beat>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 138 </high_index>
+     <color> 119, 239, 163 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 139 </low_index>
+     <high_index> 255 </high_index>
+     <color> 151, 179, 234 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 138 </high_index>
+     <color> 151, 179, 234 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 139 </low_index>
+     <high_index> 255 </high_index>
+     <color> 119, 239, 163 </color>
+    </cmap_bwgradient>
+   </container_cycle>
+   <xform_spin>
+    <angle> 1.25000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.98700 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> -1.25000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 1.04000 </r_scale>
+   </xform_spin>
+  </container_cycle>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_branchscope.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 138 </high_index>
+    <color> 119, 239, 163 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 139 </low_index>
+    <high_index> 255 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <container_onbeat>
+   <freq_drops>
+   </freq_drops>
+  </container_onbeat>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <container_simple>
+    <wave_horizontal>
+     <channels> -1 </channels>
+    </wave_horizontal>
+    <wave_radial>
+     <base_radius> 0.00000 </base_radius>
+    </wave_radial>
+   </container_simple>
+   <container_simple>
+    <wave_horizontal>
+     <channels> -1 </channels>
+    </wave_horizontal>
+   </container_simple>
+   <container_simple>
+    <wave_radial>
+     <base_radius> 0.00000 </base_radius>
+    </wave_radial>
+   </container_simple>
+  </container_cycle>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <container_simple>
+    <general_blur>
+    </general_blur>
+   </container_simple>
+   <general_noop>
+   </general_noop>
+   <container_simple>
+    <general_mosaic>
+     <radius> 3 </radius>
+    </general_mosaic>
+    <general_blur>
+    </general_blur>
+    <general_fade>
+     <amount> 30 </amount>
+    </general_fade>
+   </container_simple>
+  </container_cycle>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 138 </high_index>
+    <color> 119, 239, 163 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 139 </low_index>
+    <high_index> 255 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+   <general_noop>
+   </general_noop>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 138 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 139 </low_index>
+    <high_index> 255 </high_index>
+    <color> 119, 239, 163 </color>
+   </cmap_bwgradient>
+  </container_cycle>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <xform_spin>
+    <angle> 0.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.98700 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> 0.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 1.04000 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> 1.25000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.98700 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> -1.25000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 1.04000 </r_scale>
+   </xform_spin>
+  </container_cycle>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_bumblebees.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 238, 208, 83 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_normalize>
+   <height> -6 </height>
+   <hfrac> 6.00000 </hfrac>
+   <vfrac> 0.12500 </vfrac>
+   <channels> 0 </channels>
+  </wave_normalize>
+  <wave_radial>
+   <base_radius> 0.00000 </base_radius>
+  </wave_radial>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_cubism.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 0, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 250 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_halfrender>
+   <direction> -1 </direction>
+   <render_twice> FALSE </render_twice>
+  </xform_halfrender>
+  <xform_halfrender>
+   <direction> 1 </direction>
+   <render_twice> FALSE </render_twice>
+  </xform_halfrender>
+  <xform_spin>
+   <angle> -4.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.90000 </r_scale>
+  </xform_spin>
+  <xform_spin>
+   <angle> 1.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> -1.00000 </r_scale>
+  </xform_spin>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <general_invert>
+   </general_invert>
+   <general_noop>
+   </general_noop>
+  </container_cycle>
+  <general_replace>
+   <start> 250 </start>
+   <end> 255 </end>
+   <out> 0 </out>
+  </general_replace>
+  <general_replace>
+   <start> 128 </start>
+   <end> 149 </end>
+   <out> 0 </out>
+  </general_replace>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_flying_into_pastels.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 140 </low_index>
+    <high_index> 255 </high_index>
+    <color> 76, 122, 229 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_normalize>
+   <height> -6 </height>
+   <hfrac> 6.00000 </hfrac>
+   <vfrac> 0.12500 </vfrac>
+   <channels> 0 </channels>
+  </wave_normalize>
+  <wave_radial>
+   <base_radius> 0.00000 </base_radius>
+  </wave_radial>
+  <xform_ripple>
+   <angle> 0.00000 </angle>
+   <ripples> 8.00000 </ripples>
+   <base_speed> 1.00000 </base_speed>
+   <mod_speed> 1.00000 </mod_speed>
+  </xform_ripple>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+  <xform_spin>
+   <angle> -0.50000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.94000 </r_scale>
+  </xform_spin>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_interlaced.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <general_clear>
+   </general_clear>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 151, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <container_simple>
+   <misc_floater>
+    <value> 180 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 180 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 180 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 180 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 180 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 180 </value>
+   </misc_floater>
+  </container_simple>
+  <container_onbeat>
+   <freq_drops>
+   </freq_drops>
+   <general_replace>
+    <start> 250 </start>
+    <end> 255 </end>
+    <out> 150 </out>
+   </general_replace>
+   <xform_halfrender>
+    <direction> 1 </direction>
+    <render_twice> TRUE </render_twice>
+   </xform_halfrender>
+  </container_onbeat>
+  <xform_halfrender>
+   <direction> -1 </direction>
+   <render_twice> TRUE </render_twice>
+  </xform_halfrender>
+  <general_fade>
+   <amount> 3 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_kaliedoscope.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_dynamic>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <script> blue = blue + 0.006999; green = green + 0.007; red = red + 0.004599; </script>
+   </cmap_dynamic>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 255 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_movement>
+   <formula>  d=cos(d)^2;  </formula>
+  </xform_movement>
+  <general_blur>
+  </general_blur>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_phosphor_flame.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 120, 223, 193 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <freq_drops>
+  </freq_drops>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+  <general_blur>
+  </general_blur>
+  <wave_radial>
+   <base_radius> 0.00000 </base_radius>
+  </wave_radial>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 1.04000 </r_scale>
+  </xform_spin>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_psuedo_starfield.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 191, 191, 191 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <freq_drops>
+  </freq_drops>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.97000 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_purple_flower.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 118, 0, 191 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_radial>
+   <base_radius> 0.00000 </base_radius>
+  </wave_radial>
+  <general_blur>
+  </general_blur>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_quakingscope.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 138 </high_index>
+    <color> 119, 239, 163 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 139 </low_index>
+    <high_index> 255 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+  </wave_horizontal>
+  <general_blur>
+  </general_blur>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> FALSE </beat>
+   <xform_spin>
+    <angle> 0.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 1.04000 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> 0.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.98700 </r_scale>
+   </xform_spin>
+  </container_cycle>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_quasar.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 191, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_scope>
+   <init_script>   points=513;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p;   </init_script>
+   <frame_script>   ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3);   </frame_script>
+   <sample_script>   x1=value*sin(p2*index);y1=0;z1=r*cos(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst);   </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <wave_scope>
+   <init_script>   points=513;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p;   </init_script>
+   <frame_script>   ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3);   </frame_script>
+   <sample_script>   y1=value*cos(p2*index);x1=0;z1=r*sin(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst);   </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <wave_scope>
+   <init_script>   points=5;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p;   </init_script>
+   <frame_script>   ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3);   </frame_script>
+   <sample_script>   z1=r*sin(p2*index);x1=0;y1=0*sin(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst);   </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <general_fade>
+   <amount> 10 </amount>
+  </general_fade>
+  <general_blur>
+  </general_blur>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_retroscope.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 119, 239, 163 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <general_fade>
+   <amount> 255 </amount>
+  </general_fade>
+  <wave_horizontal>
+   <channels> -1 </channels>
+  </wave_horizontal>
+  <general_blur>
+  </general_blur>
+  <general_mosaic>
+  </general_mosaic>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_rush.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_gradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <lcolor> 0, 0, 127 </lcolor>
+    <hcolor> 0, 127, 255 </hcolor>
+   </cmap_gradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 255 </value>
+   <lines> FALSE </lines>
+  </wave_horizontal>
+  <wave_vertical>
+   <channels> -1 </channels>
+   <value> 255 </value>
+   <lines> FALSE </lines>
+  </wave_vertical>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> TRUE </beat>
+   <xform_spin>
+    <angle> -4.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.75000 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> 4.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.75000 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> -8.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.75000 </r_scale>
+   </xform_spin>
+   <xform_spin>
+    <angle> 8.00000 </angle>
+    <r_add> 0.00000 </r_add>
+    <r_scale> 0.75000 </r_scale>
+   </xform_spin>
+  </container_cycle>
+  <general_fade>
+   <amount> 3 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_scopefun.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 191, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <general_invert>
+  </general_invert>
+  <wave_scope>
+   <init_script> n=7;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p; </init_script>
+   <frame_script> ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3); </frame_script>
+   <sample_script> x1=value*sin(p2*index);y1=cos(p2*index);z1=r*cos(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst); </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <general_fade>
+   <amount> 10 </amount>
+  </general_fade>
+  <general_invert>
+  </general_invert>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_simple_yet_pretty.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 105, 32, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> 0 </channels>
+   <value> 255 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <wave_vertical>
+   <channels> 0 </channels>
+   <value> 255 </value>
+   <lines> TRUE </lines>
+  </wave_vertical>
+  <xform_movement>
+   <formula> r = sin(r); d = cos(d)^2; </formula>
+   <polar> TRUE </polar>
+  </xform_movement>
+  <general_blur>
+  </general_blur>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_smoke.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 180 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <general_replace>
+   <start> 1 </start>
+   <end> 15 </end>
+   <out> 0 </out>
+  </general_replace>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.94000 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_swarm.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,923 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 127, 255 </color>
+   </cmap_bwgradient>
+   <general_clear>
+   </general_clear>
+  </container_once>
+  <container_simple>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+  </container_simple>
+  <container_simple>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+  </container_simple>
+  <xform_spin>
+   <angle> 1.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.96000 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_technicolour_nightmare.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 100, 62, 191 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 157 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_spin>
+   <angle> 0.03000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 1.04000 </r_scale>
+  </xform_spin>
+  <xform_halfrender>
+   <direction> 1 </direction>
+  </xform_halfrender>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 151 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <container_onbeat>
+   <xform_halfrender>
+    <direction> -1 </direction>
+   </xform_halfrender>
+  </container_onbeat>
+  <container_onbeat>
+   <container_cycle>
+    <change_interval> 0 </change_interval>
+    <beat> FALSE </beat>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 255 </high_index>
+     <color> 69, 75, 191 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 255 </high_index>
+     <color> 120, 191, 191 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 255 </high_index>
+     <color> 100, 62, 191 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 255 </high_index>
+     <color> 100, 191, 62 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 255 </high_index>
+     <color> 62, 191, 100 </color>
+    </cmap_bwgradient>
+    <cmap_bwgradient>
+     <low_index> 0 </low_index>
+     <high_index> 255 </high_index>
+     <color> 239, 123, 227 </color>
+    </cmap_bwgradient>
+   </container_cycle>
+  </container_onbeat>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_transform_fun.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 130, 191 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_scope>
+   <init_script> points=512; dt=0.01; t=0; sc=1; </init_script>
+   <frame_script> t=t+dt;dt=0.9*dt+0.001;  </frame_script>
+   <sample_script> x=cos(2*index+t)*0.9*(value*0.5+0.5); y=sin(index*2+t)*0.9*(value*0.5+0.5); </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <general_blur>
+  </general_blur>
+  <xform_movement>
+   <formula> r=cos(r*3); d=sin(d*1.1) </formula>
+  </xform_movement>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_trapped.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 161, 226 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <xform_movement>
+   <formula> r=(tan(r)^sin(r)) </formula>
+  </xform_movement>
+  <wave_scope>
+   <init_script> points=192; t = -0.05; </init_script>
+   <frame_script> t = t + 0.05; </frame_script>
+   <sample_script> d = index + value; r = t + tan(index) * 3.141952924 * 4; x = (sin(r) * sin(d)) / 1.3; y = cos(r) * cos(d); </sample_script>
+   <lines> TRUE </lines>
+  </wave_scope>
+  <general_fade>
+   <amount> 3 </amount>
+  </general_fade>
+  <general_blur>
+  </general_blur>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_tunnel_vision.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 130, 191 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+   <value> 255 </value>
+   <lines> TRUE </lines>
+  </wave_horizontal>
+  <xform_dynmovement>
+   <init_script> rseek=1.45; dseek=2; </init_script>
+   <frame_script>  </frame_script>
+   <point_script> r=r/rseek; d=d*dseek;  </point_script>
+  </xform_dynmovement>
+  <general_blur>
+  </general_blur>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 2 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_value_replace_fun.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 151, 179, 234 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <wave_horizontal>
+   <channels> -1 </channels>
+  </wave_horizontal>
+  <general_replace>
+   <start> 255 </start>
+   <end> 255 </end>
+   <out> 180 </out>
+  </general_replace>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 0.94000 </r_scale>
+  </xform_spin>
+  <general_blur>
+  </general_blur>
+  <general_fade>
+   <amount> 1 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/nenolod_-_worms.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,920 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_once>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 255 </high_index>
+    <color> 0, 127, 255 </color>
+   </cmap_bwgradient>
+  </container_once>
+  <general_invert>
+  </general_invert>
+  <container_simple>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+  </container_simple>
+  <container_simple>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+   <misc_floater>
+    <value> 255 </value>
+   </misc_floater>
+  </container_simple>
+  <xform_spin>
+   <angle> 0.00000 </angle>
+   <r_add> 0.00000 </r_add>
+   <r_scale> 1.02000 </r_scale>
+  </xform_spin>
+  <general_invert>
+  </general_invert>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/presets/ticpu_-_colored_beat-o-scope.pnv	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+
+<paranormal_preset>
+ <container_simple>
+  <container_onbeat>
+   <container_simple>
+    <general_blur>
+    </general_blur>
+    <general_blur>
+    </general_blur>
+    <general_blur>
+    </general_blur>
+   </container_simple>
+   <xform_spin>
+    <angle> 8.00000 </angle>
+    <r_add> 1.00000 </r_add>
+    <r_scale> 0.60000 </r_scale>
+   </xform_spin>
+  </container_onbeat>
+  <container_cycle>
+   <change_interval> 3 </change_interval>
+   <beat> FALSE </beat>
+   <cmap_bwgradient>
+    <low_index> 26 </low_index>
+    <high_index> 169 </high_index>
+    <color> 0, 191, 255 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 94 </high_index>
+    <color> 83, 127, 150 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 84 </low_index>
+    <high_index> 255 </high_index>
+    <color> 208, 95, 89 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 173 </high_index>
+    <color> 71, 255, 51 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 114 </low_index>
+    <high_index> 255 </high_index>
+    <color> 242, 50, 253 </color>
+   </cmap_bwgradient>
+   <cmap_bwgradient>
+    <low_index> 0 </low_index>
+    <high_index> 157 </high_index>
+    <color> 15, 239, 231 </color>
+   </cmap_bwgradient>
+  </container_cycle>
+  <container_cycle>
+   <change_interval> 0 </change_interval>
+   <beat> FALSE </beat>
+   <general_blur>
+   </general_blur>
+   <general_noop>
+   </general_noop>
+   <general_noop>
+   </general_noop>
+   <general_noop>
+   </general_noop>
+  </container_cycle>
+  <container_cycle>
+   <change_interval> 8 </change_interval>
+   <beat> TRUE </beat>
+   <wave_scope>
+    <init_script>   n=7;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p;   </init_script>
+    <frame_script>   ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3);   </frame_script>
+    <sample_script>   x1=value*sin(p2*index);y1=value * index / cos(z1);z1=r*cos(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst);   </sample_script>
+    <lines> TRUE </lines>
+   </wave_scope>
+   <wave_scope>
+    <init_script>   n=7;r=0.5;mx=0;my=0;mz=0;dst=2;rx=0;ry=0;rz=0;rdx=1;rdy=1;rdz=1;p=3.14159265;p2=2.0*p;p3=180/p;   </init_script>
+    <frame_script>   ;rx=rx+rdx;ry=ry+rdy;rz=rz+rdz;xs=sin(rx/p3);ys=sin(ry/p3);zs=sin(rz/p3);xc=cos(rx/p3);yc=cos(ry/p3);zc=cos(rz/p3);   </frame_script>
+    <sample_script>   x1=value*sin(p2*index);y1=value * index / cos(z1);z1=r*cos(p2*index);y2=y1*xc-z1*xs;z2=y1*xs+z1*xc;x2=z2*ys+x1*yc;z3=z2*yc-x1*ys;x3=x2*zc-y2*zs;y3=y2*zc+x2*zs;x4=mx+x3;y4=my+y3;z4=mz+z3;x=x4/(1+z4/dst);y=y4/(1+z4/dst);   </sample_script>
+    <lines> TRUE </lines>
+   </wave_scope>
+  </container_cycle>
+  <general_fade>
+   <amount> 4 </amount>
+  </general_fade>
+ </container_simple>
+</paranormal_preset>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/wave.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,528 @@
+/*
+ * paranormal-ng: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <config.h>
+
+#include <math.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "pn_utils.h"
+
+#include "drawing.h"
+
+#include "libcalc/calc.h"
+
+/* **************** wave_horizontal **************** */
+struct pn_actuator_option_desc wave_horizontal_opts[] =
+{
+  {"channels", "Which sound channels to use: negative = channel 1, \npositive = channel 2, "
+   "zero = both (two wave-forms.)", OPT_TYPE_INT, {ival: -1} },
+  {"value", "The colour value to use.", OPT_TYPE_COLOR, {cval: { 0, 192, 255 } } },
+  {"width", "The line's width.", OPT_TYPE_INT, {ival: 1} },
+  { NULL }
+};
+
+void
+wave_horizontal_exec_lines (const struct pn_actuator_option *opts,
+		    gpointer data)
+{
+  int channel = ( opts[0].val.ival < 0 ) ? 0 : 1;
+  guchar value = (opts[1].val.ival < 0 || opts[1].val.ival > 255) ? 255 : opts[1].val.ival;
+  GLfloat *x_pos, *y_pos;	/* dynamic tables which store the positions for the line */
+  GLfloat *x2_pos, *y2_pos;	/* dynamic tables which store the positions for the line */
+  gint i, j;
+  float step;
+  GLubyte colour[] = { opts[1].val.cval.r, opts[1].val.cval.g, opts[1].val.cval.b, 255 };
+
+  x_pos = g_new0(GLfloat, 257);
+  y_pos = g_new0(GLfloat, 257);
+  x2_pos = g_new0(GLfloat, 257);
+  y2_pos = g_new0(GLfloat, 257);
+
+  step = pn_image_data->width / 128.;
+
+  /* calculate the line. */
+  for (j = 0, i = -128; j < 256; i++, j++)
+    {
+      if (opts[0].val.ival != 0)
+        {
+           x_pos[j] = (i * step) / pn_image_data->width;
+           y_pos[j] = (GLfloat) CAP (pn_sound_data->pcm_data[channel][j * 2]>>5, 
+			(pn_image_data->height>>1)) / (GLfloat) pn_image_data->height;
+        }
+      else
+        {
+           x_pos[j] = (i * step) / pn_image_data->width;
+           y_pos[j] = ((GLfloat) CAP (pn_sound_data->pcm_data[channel][j * 2]>>5, 
+			(pn_image_data->height>>1)) / (GLfloat) pn_image_data->height) - 0.5f;
+
+           x2_pos[j] = (i * step) / pn_image_data->width;
+           y2_pos[j] = ((GLfloat) CAP (pn_sound_data->pcm_data[channel][j * 2]>>5, 
+			(pn_image_data->height>>1)) / (GLfloat) pn_image_data->height) + 0.5f;
+
+        }
+    }
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+
+  glLineWidth(opts[2].val.ival);
+  glBegin(GL_LINE_STRIP);
+
+  glColor4ubv(colour);
+
+  /* draw the line. */
+  for (i = 1; i < 256; i++)
+    {
+       glVertex2d(x_pos[i - 1], y_pos[i - 1]);
+       glVertex2d(x_pos[i], y_pos[i]);
+    }
+
+  glEnd();
+
+  if ( opts[0].val.ival == 0 )
+    {
+       glBegin(GL_LINE_STRIP);
+
+       for (i = 1; i < 256; i++)
+         {
+           glVertex2d(x2_pos[i - 1] / pn_image_data->width, y2_pos[i - 1] / pn_image_data->height);
+           glVertex2d(x2_pos[i] / pn_image_data->width, y2_pos[i] / pn_image_data->height);
+         }
+
+       glEnd();
+    }
+
+  glPopMatrix();
+
+  g_free(x_pos);
+  g_free(y_pos);
+  g_free(x2_pos);
+  g_free(y2_pos);
+}
+
+static void
+wave_horizontal_exec (const struct pn_actuator_option *opts,
+		    gpointer data)
+{
+  wave_horizontal_exec_lines(opts, data);
+}
+
+struct pn_actuator_desc builtin_wave_horizontal =
+{
+  "wave_horizontal", "Horizontal Waveform",
+  "Draws one or two waveforms horizontally across "
+  "the drawing surface",
+  0, wave_horizontal_opts,
+  NULL, NULL, wave_horizontal_exec
+};
+
+/* **************** wave_vertical **************** */
+struct pn_actuator_option_desc wave_vertical_opts[] =
+{
+  {"channels", "Which sound channels to use: negative = channel 1, \npositive = channel 2, "
+   "zero = both (two wave-forms.)", OPT_TYPE_INT, {ival: -1} },
+  {"value", "The colour value to use.", OPT_TYPE_COLOR, {cval: { 0, 192, 255 } } },
+  {"width", "The line's width.", OPT_TYPE_INT, {ival: 1} },
+  { NULL }
+};
+
+static void
+wave_vertical_exec_lines (const struct pn_actuator_option *opts,
+		    gpointer data)
+{
+  int channel = ( opts[0].val.ival < 0 ) ? 0 : 1;
+  guchar value = (opts[1].val.ival < 0 || opts[1].val.ival > 255) ? 255 : opts[1].val.ival;
+  GLfloat *x_pos, *y_pos;	/* dynamic tables which store the positions for the line */
+  GLfloat *x2_pos, *y2_pos;	/* dynamic tables which store the positions for the line */
+  gint i, j;
+  float step;
+  GLubyte colour[] = { opts[1].val.cval.r, opts[1].val.cval.g, opts[1].val.cval.b, 255 };
+
+  x_pos = g_new0(GLfloat, 129);
+  y_pos = g_new0(GLfloat, 129);
+  x2_pos = g_new0(GLfloat, 129);
+  y2_pos = g_new0(GLfloat, 129);
+
+  step = pn_image_data->height / 64.;
+
+  /* calculate the line. */
+  for (i = -64, j = 0; j < 128; i++, j++)
+    {
+      if (opts[0].val.ival != 0)
+        {
+           x_pos[j] = (GLfloat) CAP (pn_sound_data->pcm_data[channel][j * 2]>>6, 
+			(pn_image_data->height>>1)) / (GLfloat) pn_image_data->width;
+	   y_pos[j] = (i * step) / pn_image_data->height;
+        }
+      else
+        {
+           x_pos[j] = ((GLfloat) CAP (pn_sound_data->pcm_data[channel][j * 2]>>6, 
+			(pn_image_data->height>>1)) / (GLfloat) pn_image_data->width) - 0.5;
+	   y_pos[j] = (i * step) / pn_image_data->height;
+
+           x2_pos[j] = ((GLfloat) CAP (pn_sound_data->pcm_data[channel][j * 2]>>6, 
+			(pn_image_data->height>>1)) / (GLfloat) pn_image_data->width) + 0.5;
+	   y2_pos[j] = (i * step) / pn_image_data->height;
+        }
+    }
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+
+  glLineWidth(opts[2].val.ival);
+  glBegin(GL_LINE_STRIP);
+
+  glColor4ubv(colour);
+
+  /* draw the line. */
+  for (i = 1; i < 128; i++)
+    {
+       glVertex2d(x_pos[i - 1], y_pos[i - 1]);
+       glVertex2d(x_pos[i], y_pos[i]);
+    }
+
+  glEnd();
+
+  if ( opts[0].val.ival == 0 )
+    {
+       glBegin(GL_LINE_STRIP);
+
+       for (i = 1; i < 128; i++)
+         {
+           glVertex2d(x2_pos[i - 1] / pn_image_data->width, y2_pos[i - 1] / pn_image_data->height);
+           glVertex2d(x2_pos[i] / pn_image_data->width, y2_pos[i] / pn_image_data->height);
+         }
+
+       glEnd();
+    }
+
+  glPopMatrix();
+
+  g_free(x_pos);
+  g_free(y_pos);
+  g_free(x2_pos);
+  g_free(y2_pos);
+}
+
+static void
+wave_vertical_exec (const struct pn_actuator_option *opts,
+		    gpointer data)
+{
+  wave_vertical_exec_lines(opts, data);
+}
+
+struct pn_actuator_desc builtin_wave_vertical =
+{
+  "wave_vertical", "Vertical Waveform",
+  "Draws one or two waveforms vertically across "
+  "the drawing surface",
+  0, wave_vertical_opts,
+  NULL, NULL, wave_vertical_exec
+};
+
+/* FIXME: allow for only 1 channel for wave_normalize & wave_smooth */
+/* **************** wave_normalize **************** */
+static struct pn_actuator_option_desc wave_normalize_opts[] =
+{
+  { "height", "If positive, the height, in pixels, to which the waveform will be "
+    "normalized; if negative, hfrac is used", OPT_TYPE_INT, { ival: -1 } },
+  { "hfrac", "If positive, the fraction of the horizontal image size to which the "
+    "waveform will be normalized; if negative, vfrac is used",
+    OPT_TYPE_FLOAT, { fval: -1 } },
+  { "vfrac", "If positive, the fraction of the vertical image size to which the "
+    "waveform will be normalized",
+    OPT_TYPE_FLOAT, { fval: .125 } },
+  { "channels", "Which sound channel(s) to normalize: negative = channel 1,\n"
+    "\tpositive = channel 2, 0 = both channels.",
+    OPT_TYPE_INT, { ival: 0 } },
+  { NULL }
+};
+
+static void
+wave_normalize_exec (const struct pn_actuator_option *opts,
+		     gpointer data)
+{
+  int i, j, max=0;
+  float denom;
+
+  for (j=0; j<2; j++)
+    {
+      if ( !(opts[3].val.ival) || (opts[3].val.ival < 0 && j == 0) ||
+	   (opts[3].val.ival > 0 && j == 1) ) {
+	
+	for (i=0; i<512; i++)
+	  if (abs(pn_sound_data->pcm_data[j][i]) > max)
+	    max = abs(pn_sound_data->pcm_data[j][i]);
+	
+	if (opts[0].val.ival > 0)
+	  denom = max/(opts[0].val.ival<<8);
+	else if (opts[1].val.fval > 0)
+	  denom = max/(opts[1].val.fval * (pn_image_data->width<<8));
+	else
+	  denom = max/(opts[2].val.fval * (pn_image_data->height<<8));
+	
+	if (denom > 0)
+	  for (i=0; i<512; i++)
+	    pn_sound_data->pcm_data[j][i]
+	      /= denom;
+      }
+    }
+}
+
+struct pn_actuator_desc builtin_wave_normalize =
+{
+  "wave_normalize", "Normalize Waveform Data",
+  "Normalizes the waveform data used by the wave_* actuators",
+  0, wave_normalize_opts,
+  NULL, NULL, wave_normalize_exec
+};
+
+/* **************** wave_smooth **************** */
+struct pn_actuator_option_desc wave_smooth_opts[] = 
+{
+  { "channels", "Which sound channel(s) to smooth: negative = channel 1, \n"
+    "\tpositive = channel 2, 0 = both channels.",
+    OPT_TYPE_INT, { ival: 0 } },
+  {0}
+};
+
+static void
+wave_smooth_exec (const struct pn_actuator_option *opts,
+		  gpointer data)
+{
+  int i, j, k;
+  gint16 tmp[512];
+
+  for (j=0; j<2; j++)
+    {
+      if ( !(opts[0].val.ival) || (opts[0].val.ival < 0 && j == 0) ||
+	   (opts[0].val.ival > 0 && j == 1) ) { 
+	
+	for (i=4; i<508; i++)
+	  {
+	    k = (pn_sound_data->pcm_data[j][i]<<3)
+	      + (pn_sound_data->pcm_data[j][i+1]<<2)
+	      + (pn_sound_data->pcm_data[j][i-1]<<2)
+	      + (pn_sound_data->pcm_data[j][i+2]<<2)
+	      + (pn_sound_data->pcm_data[j][i-2]<<2)
+	      + (pn_sound_data->pcm_data[j][i+3]<<1)
+	      + (pn_sound_data->pcm_data[j][i-3]<<1)
+	      + (pn_sound_data->pcm_data[j][i+4]<<1)
+	      + (pn_sound_data->pcm_data[j][i-4]<<1);
+	    tmp[i] = k >> 5;
+	  }
+	memcpy (pn_sound_data->pcm_data[j]+4, tmp, sizeof (gint16) * 504);
+      } 
+    }
+}
+
+struct pn_actuator_desc builtin_wave_smooth =
+{
+  "wave_smooth", "Smooth Waveform Data",
+  "Smooth out the waveform data used by the wave_* actuators",
+  0, wave_smooth_opts,
+  NULL, NULL, wave_smooth_exec
+};
+
+/* **************** wave_radial **************** */
+static struct pn_actuator_option_desc wave_radial_opts[] =
+{
+  { "base_radius", " ", 
+    OPT_TYPE_FLOAT, { fval: 0 } },
+  {"value", "The colour value to use.", OPT_TYPE_COLOR, {cval: { 0, 192, 255 } } },
+  {"width", "The line's width.", OPT_TYPE_INT, {ival: 1} },
+  { NULL }
+};
+
+static void
+wave_radial_exec (const struct pn_actuator_option *opts,
+		  gpointer data)
+{
+  int i, x, y;
+  GLfloat *x_pos, *y_pos;	/* dynamic tables which store the positions for the line */
+  GLubyte colour[] = { opts[1].val.cval.r, opts[1].val.cval.g, opts[1].val.cval.b, 255 };
+
+  x_pos = g_new0(GLfloat, 361);
+  y_pos = g_new0(GLfloat, 361);
+  
+  for(i=0; i<360; i++)
+    {
+      x_pos[i] = (opts[0].val.fval + (pn_sound_data->pcm_data[0][(int)(i*(512.0/360.0))]))
+	* cos_val[i];
+      y_pos[i] = (opts[0].val.fval + (pn_sound_data->pcm_data[0][(int)(i*(512.0/360.0))]))
+	* sin_val[i];
+    }
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+
+  glLineWidth(opts[2].val.ival);
+  glBegin(GL_LINES);
+
+  glColor4ubv(colour);
+
+  /* draw the line. */
+  for (i = 1; i < 360; i++)
+    {
+       glVertex2d(x_pos[i - 1], y_pos[i - 1]);
+       glVertex2d(x_pos[i], y_pos[i]);
+    }
+
+  glEnd();
+
+  glPopMatrix();
+
+  g_free(x_pos);
+  g_free(y_pos);
+};	       
+
+struct pn_actuator_desc builtin_wave_radial =
+{
+  "wave_radial", "Radial Waveform",
+  "Draws a single waveform varying"
+  " radially from the center of the image",
+  0, wave_radial_opts,
+  NULL, NULL, wave_radial_exec
+};
+
+/* **************** wave_scope **************** */
+
+static struct pn_actuator_option_desc wave_scope_opts[] =
+{
+  {"init_script", "Initialization script.", OPT_TYPE_STRING, {sval: "n = 800; t = -0.05;"} },
+  {"frame_script", "Script to run at the beginning of each frame.", OPT_TYPE_STRING, {sval: "t = t + 0.05;"} },
+  {"sample_script", "Script to run for each sample.", OPT_TYPE_STRING, {sval: "d = index + value; r = t + index * 3.141952924 * 4; x = cos(r) * d; y = sin(r) * d;"} },
+  {"lines", "Use lines instead of dots.", OPT_TYPE_BOOLEAN, {bval: TRUE} },
+  { NULL }
+};
+
+struct pn_scope_data
+{
+  expression_t *expr_on_init, *expr_on_frame, *expr_on_sample;
+  symbol_dict_t *dict;
+  gboolean reset;
+};
+
+static void
+wave_scope_init(gpointer *data)
+{
+  *data = g_new0(struct pn_scope_data, 1);
+
+  /* the expressions will need to be compiled, so prepare for that */
+  ((struct pn_scope_data *)*data)->reset = TRUE;
+}
+
+static void
+wave_scope_cleanup(gpointer op_data)
+{
+  struct pn_scope_data *data = (struct pn_scope_data *) op_data;
+
+  g_return_if_fail(data != NULL);
+
+  if (data->expr_on_init)
+    expr_free(data->expr_on_init);
+
+  if (data->expr_on_frame)
+    expr_free(data->expr_on_frame);
+
+  if (data->expr_on_sample)
+    expr_free(data->expr_on_sample);
+
+  if (data->dict)
+    dict_free(data->dict);
+
+  if (data)
+    g_free(data);
+}
+
+static void
+wave_scope_exec(const struct pn_actuator_option *opts,
+		gpointer op_data)
+{
+  struct pn_scope_data *data = (struct pn_scope_data *) op_data;
+  gint i;
+  gdouble *xf, *yf, *index, *value, *points;
+
+  if (data->reset)
+    {
+       if (data->dict)
+         dict_free(data->dict);
+
+       data->dict = dict_new();
+
+       if (opts[0].val.sval != NULL)
+         data->expr_on_init = expr_compile_string(opts[0].val.sval, data->dict);
+
+       if (opts[1].val.sval != NULL)
+         data->expr_on_frame = expr_compile_string(opts[1].val.sval, 
+		data->dict);
+
+       if (opts[2].val.sval != NULL)
+         data->expr_on_sample = expr_compile_string(opts[2].val.sval, 
+		data->dict);
+
+       if (data->expr_on_init != NULL)
+         expr_execute(data->expr_on_init, data->dict);
+
+       data->reset = FALSE;
+    }
+
+  xf = dict_variable(data->dict, "x");
+  yf = dict_variable(data->dict, "y");
+  index = dict_variable(data->dict, "index");
+  value = dict_variable(data->dict, "value");
+  points = dict_variable(data->dict, "points");
+
+  if (data->expr_on_frame != NULL)
+    expr_execute(data->expr_on_frame, data->dict);
+
+  if (*points > 513 || *points == 0)
+      *points = 513;
+
+  if (data->expr_on_sample != NULL)
+    {
+       glBegin(GL_LINE_STRIP);
+
+       for (i = 0; i < *points; i++)
+          {
+             *value = 1.0 * pn_sound_data->pcm_data[0][i & 511] / 32768.0;
+             *index = i / (*points - 1);
+
+             expr_execute(data->expr_on_sample, data->dict);
+
+             glVertex2d(*xf, *yf);
+          }
+
+       glEnd();
+       glPopMatrix();
+    }
+}
+
+struct pn_actuator_desc builtin_wave_scope =
+{
+  "wave_scope", "Scope",
+  "A programmable scope.",
+  0, wave_scope_opts,
+  wave_scope_init, wave_scope_cleanup, wave_scope_exec
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/paranormal-ng/xform.c	Mon Oct 15 06:20:13 2007 -0500
@@ -0,0 +1,781 @@
+/*
+ * paranormal: iterated pipeline-driven visualization plugin
+ * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org>
+ * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* FIXME: allow for only using an xform on part of the img? */
+/* FIXME: perhaps combine these into a single vector field
+   so that only 1 apply_xform needs to be done for as many
+   of these as someone wants to use */
+
+#include <config.h>
+
+#include <math.h>
+
+#include <glib.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+#include "pn_utils.h"
+
+#include "libcalc/calc.h"
+
+struct xform_vector
+{
+  gint32 offset; /* the offset of the top left pixel */
+  guint16 w; /* 4:4:4:4 NE, NW, SE, SW pixel weights
+		  The total should be 16 */
+
+  /* if offset < 0 then w is the color index to
+     which the pixel will be set */
+};
+
+static void
+xfvec (float x, float y, struct xform_vector *v)
+{
+  float xd, yd;
+  int weight[4];
+
+  if (x >= pn_image_data->width-1 || y >= pn_image_data->height-1
+      || x < 0 || y < 0)
+    {
+      v->offset = -1;
+      v->w = 0;
+      return;
+    }
+
+  v->offset = PN_IMG_INDEX (floor(x), floor(y));
+
+  xd = x - floor (x);
+  yd = y - floor (y);
+
+  weight[3] = xd * yd * 16;
+  weight[2] = (1-xd) * yd * 16;
+  weight[1] = xd * (1-yd) * 16;
+  weight[0] = 16 - weight[3] - weight[2] - weight[1]; /* just in case */
+
+  v->w = (weight[0]<<12) | (weight[1]<<8) | (weight[2]<<4) | weight[3];
+}
+
+static void
+apply_xform (struct xform_vector *vfield)
+{
+  int i;
+  struct xform_vector *v;
+  register guchar *srcptr;
+  register guchar *destptr;
+  register int color;
+
+  if (vfield == NULL)
+      return;
+
+  for (i=0, v=vfield, destptr=pn_image_data->surface[1];
+       i<pn_image_data->width*pn_image_data->height;
+       i++, v++, destptr++)
+    {
+      /* off the screen */
+      if (v->offset < 0)
+	{
+	  *destptr = (guchar)v->w;
+	  continue;
+	}
+
+      srcptr = pn_image_data->surface[0] + v->offset;
+
+      /* exactly on the pixel */
+      if (v->w == 0)
+	  *destptr = *srcptr;
+      
+      /* gotta blend the points */
+      else
+	{
+	  color =  *srcptr * (v->w>>12);
+	  color += *++srcptr * ((v->w>>8) & 0x0f);
+	  color += *(srcptr+=pn_image_data->width) * (v->w & 0x0f);
+	  color += *(--srcptr) * ((v->w>>4) & 0x0f);
+	  color >>= 4;
+	  *destptr = (guchar)color;
+	}
+    }
+}
+
+/* **************** xform_spin **************** */
+/* FIXME: Describe these better, how they are backwards */
+/* FIXME: better name? */
+struct pn_actuator_option_desc xform_spin_opts[] =
+{
+  { "angle", "The angle of rotation", OPT_TYPE_FLOAT, { fval: -8.0 } },
+  { "r_add", "The number of pixels by which the r coordinate will be "
+    "increased (before scaling)", OPT_TYPE_FLOAT, { fval: 0.0 } },
+  { "r_scale", "The amount by which the r coordinate of each pixel will "
+    "be scaled", OPT_TYPE_FLOAT, { fval: 1.0 } },
+  { NULL }
+};
+
+struct xform_spin_data
+{
+  int width, height;
+  struct xform_vector *vfield;
+};
+
+static void
+xform_spin_init (gpointer *data)
+{
+  *data = g_new0 (struct xform_spin_data, 1);
+}
+
+static void
+xform_spin_cleanup (gpointer data)
+{
+  struct xform_spin_data *d = (struct xform_spin_data *) data;
+
+  
+  if (d)
+    {
+      if (d->vfield)
+	g_free (d->vfield);
+      g_free (d);
+    }
+}
+
+static void
+xform_spin_exec (const struct pn_actuator_option *opts,
+		 gpointer data)
+{
+  struct xform_spin_data *d = (struct xform_spin_data*)data;
+  float i, j;
+
+  if (d->width != pn_image_data->width
+      || d->height != pn_image_data->height)
+    {
+      d->width = pn_image_data->width;
+      d->height = pn_image_data->height;
+
+      if (d->vfield)
+	g_free (d->vfield);
+
+      d->vfield = g_malloc0 (sizeof(struct xform_vector)
+			    * d->width * d->height);
+
+      for (j=-(pn_image_data->height>>1)+1; j<=pn_image_data->height>>1; j++)
+	for (i=-(pn_image_data->width>>1); i<pn_image_data->width>>1; i++)
+	  {
+	    float r, t = 0;
+	    float x, y;
+
+	    r = sqrt (i*i + j*j);
+	    if (r)
+	      t = asin (j/r);
+	    if (i < 0)
+	      t = M_PI - t;
+
+	    t += opts[0].val.fval * M_PI/180.0; 
+	    r += opts[1].val.fval;
+	    r *= opts[2].val.fval;
+
+	    x = (r * cos (t)) + (pn_image_data->width>>1);
+	    y = (pn_image_data->height>>1) - (r * sin (t));
+
+	    xfvec (x, y, &d->vfield
+		   [PN_IMG_INDEX ((pn_image_data->width>>1)+(int)rint(i),
+				  ((pn_image_data->height>>1)-(int)rint(j)))]);
+	  }
+    }
+
+  apply_xform (d->vfield);
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_xform_spin =
+{
+  "xform_spin", "Spin Transform", 
+  "Rotates and radially scales the image",
+  0, xform_spin_opts,
+  xform_spin_init, xform_spin_cleanup, xform_spin_exec
+};
+
+/* **************** xform_ripple **************** */
+struct pn_actuator_option_desc xform_ripple_opts[] =
+{
+  { "angle", "The angle of rotation", OPT_TYPE_FLOAT, { fval: 0 } },
+  { "ripples", "The number of ripples that fit on the screen "
+    "(horizontally)", OPT_TYPE_FLOAT, { fval: 8 } },
+  { "base_speed", "The minimum number of pixels to move each pixel",
+    OPT_TYPE_FLOAT, { fval: 1 } },
+  { "mod_speed", "The maximum number of pixels by which base_speed"
+    " will be modified", OPT_TYPE_FLOAT, { fval: 1 } },
+  { NULL }
+};
+
+struct xform_ripple_data
+{
+  int width, height;
+  struct xform_vector *vfield;
+};
+
+static void
+xform_ripple_init (gpointer *data)
+{
+  *data = g_new0 (struct xform_ripple_data, 1);
+}
+
+static void
+xform_ripple_cleanup (gpointer data)
+{
+  struct xform_ripple_data *d = (struct xform_ripple_data*) data;
+
+  if (d)
+    {
+      if (d->vfield)
+	g_free (d->vfield);
+      g_free (d);
+    }
+}
+
+static void
+xform_ripple_exec (const struct pn_actuator_option *opts,
+		 gpointer data)
+{
+  struct xform_ripple_data *d = (struct xform_ripple_data*)data;
+  float i, j;
+
+  if (d->width != pn_image_data->width
+      || d->height != pn_image_data->height)
+    {
+      d->width = pn_image_data->width;
+      d->height = pn_image_data->height;
+
+      if (d->vfield)
+	g_free (d->vfield);
+
+      d->vfield = g_malloc (sizeof(struct xform_vector)
+			    * d->width * d->height);
+
+      for (j=-(pn_image_data->height>>1)+1; j<=pn_image_data->height>>1; j++)
+	for (i=-(pn_image_data->width>>1); i<pn_image_data->width>>1; i++)
+	  {
+	    float r, t = 0;
+	    float x, y;
+
+	    r = sqrt (i*i + j*j);
+	    if (r)
+	      t = asin (j/r);
+	    if (i < 0)
+	      t = M_PI - t;
+
+	    t += opts[0].val.fval * M_PI/180.0; 
+
+	    if (r > 4)//(pn_image_data->width/(2*opts[1].val.fval)))
+	      r -=  opts[2].val.fval + (opts[3].val.fval/2) *
+		(1 + sin ((r/(pn_image_data->width/(2*opts[1].val.fval)))*M_PI));
+/*  	    else if (r > 4) */
+/*  	      r *= r/(pn_image_data->width/opts[1].val.fval); */
+	    else /* don't let it explode */
+	      r = 1000000;
+
+
+	    x = (r * cos (t)) + (pn_image_data->width>>1);
+	    y = (pn_image_data->height>>1) - (r * sin (t));
+
+	    xfvec (x, y, &d->vfield
+		   [PN_IMG_INDEX ((pn_image_data->width>>1)+(int)rint(i),
+				  ((pn_image_data->height>>1)-(int)rint(j)))]);
+	  }
+    }
+
+  apply_xform (d->vfield);
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_xform_ripple =
+{
+  "xform_ripple", "Ripple Transform", "Creates an ripple effect",
+  0, xform_ripple_opts,
+  xform_ripple_init, xform_ripple_cleanup, xform_ripple_exec
+};
+
+/* **************** xform_bump_spin **************** */
+struct pn_actuator_option_desc xform_bump_spin_opts[] =
+{
+  { "angle", "The angle of rotation", OPT_TYPE_FLOAT, { fval: 0 } },
+  { "bumps", "The number of bumps that on the image",
+    OPT_TYPE_FLOAT, { fval: 8 } },
+  { "base_scale", "The base radial scale",
+    OPT_TYPE_FLOAT, { fval: 0.95 } },
+  { "mod_scale", "The maximum amount that should be "
+    "added to the base_scale to create the 'bump' effect",
+    OPT_TYPE_FLOAT, { fval: .1 } },
+  { NULL }
+};
+
+struct xform_bump_spin_data
+{
+  int width, height;
+  struct xform_vector *vfield;
+};
+
+static void
+xform_bump_spin_init (gpointer *data)
+{
+  *data = g_new0 (struct xform_bump_spin_data, 1);
+}
+
+static void
+xform_bump_spin_cleanup (gpointer data)
+{
+  struct xform_bump_spin_data *d = (struct xform_bump_spin_data*) data;
+
+  if (d)
+    {
+      if (d->vfield)
+	g_free (d->vfield);
+      g_free (d);
+    }
+}
+
+static void
+xform_bump_spin_exec (const struct pn_actuator_option *opts,
+		 gpointer data)
+{
+  struct xform_bump_spin_data *d = (struct xform_bump_spin_data*)data;
+  float i, j;
+
+  if (d->width != pn_image_data->width
+      || d->height != pn_image_data->height)
+    {
+      d->width = pn_image_data->width;
+      d->height = pn_image_data->height;
+
+      if (d->vfield)
+	g_free (d->vfield);
+
+      d->vfield = g_malloc (sizeof(struct xform_vector)
+			    * d->width * d->height);
+
+      for (j=-(pn_image_data->height>>1)+1; j<=pn_image_data->height>>1; j++)
+	for (i=-(pn_image_data->width>>1); i<pn_image_data->width>>1; i++)
+	  {
+	    float r, t = 0;
+	    float x, y;
+
+	    r = sqrt (i*i + j*j);
+	    if (r)
+	      t = asin (j/r);
+	    if (i < 0)
+	      t = M_PI - t;
+
+	    t += opts[0].val.fval * M_PI/180.0;
+
+	    r *=  opts[2].val.fval + opts[3].val.fval
+	      * (1 + sin (t*opts[1].val.fval));
+
+	    x = (r * cos (t)) + (pn_image_data->width>>1);
+	    y = (pn_image_data->height>>1) - (r * sin (t));
+
+	    xfvec (x, y, &d->vfield
+		   [PN_IMG_INDEX ((pn_image_data->width>>1)+(int)rint(i),
+				  ((pn_image_data->height>>1)-(int)rint(j)))]);
+	  }
+    }
+
+  apply_xform (d->vfield);
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_xform_bump_spin =
+{
+  "xform_bump_spin", "Bump Transform", 
+  "Rotate the image at a varying speed to create "
+  "the illusion of bumps",
+  0, xform_bump_spin_opts,
+  xform_bump_spin_init, xform_bump_spin_cleanup, xform_bump_spin_exec
+};
+
+/* **************** xform_halfrender **************** */
+struct pn_actuator_option_desc xform_halfrender_opts[] =
+{
+  { "direction", "Negative is horizontal, positive is vertical.", 
+    OPT_TYPE_INT, { ival: 1 } },
+  { "render_twice", "Render the second image.",
+    OPT_TYPE_BOOLEAN, { bval: TRUE } },
+  { NULL }
+};
+
+static void
+xform_halfrender_exec (const struct pn_actuator_option *opts,
+		 gpointer data)
+{
+  gint x, y;
+
+  if (opts[0].val.ival < 0)
+    {
+       for (y = 0; y < pn_image_data->height; y += 2)
+         {
+            for (x = 0; x < pn_image_data->width; x++)
+              {
+                 pn_image_data->surface[1][PN_IMG_INDEX(x, y / 2)] =
+                   pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
+	         if (opts[1].val.bval)
+                   {
+                     pn_image_data->surface[1][PN_IMG_INDEX(x, (y / 2) + (pn_image_data->height / 2))] =
+                       pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
+                   }
+              }
+         }
+    }
+  else
+    {
+       for (y = 0; y < pn_image_data->height; y++)
+         {
+            for (x = 0; x < pn_image_data->width; x += 2)
+              {
+                 pn_image_data->surface[1][PN_IMG_INDEX(x / 2, y)] =
+                   pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
+                 if (opts[1].val.bval)
+                   {
+                     pn_image_data->surface[1][PN_IMG_INDEX((x / 2) + (pn_image_data->width / 2), y)] =
+                       pn_image_data->surface[0][PN_IMG_INDEX(x, y)];
+                   }
+              }
+         }
+    }
+
+    pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_xform_halfrender =
+{
+  "xform_halfrender", "Halfrender Transform",
+  "Divides the surface in half and renders it twice.",
+  0, xform_halfrender_opts,
+  NULL, NULL, xform_halfrender_exec
+};
+
+/* **************** xform_movement **************** */
+struct pn_actuator_option_desc xform_movement_opts[] =
+{
+  { "formula", "The formula to evaluate.",
+    OPT_TYPE_STRING, { sval: "r = r * cos(r); d = sin(d);" } },
+  { "polar", "Whether the coordinates are polar or not.",
+    OPT_TYPE_BOOLEAN, { bval: TRUE } },
+  { NULL }
+};
+
+typedef struct {
+  int width, height;                 /* Previous width and height. */
+  struct xform_vector *vfield;
+} PnMovementData;
+
+static void
+xform_movement_init (gpointer *data)
+{
+    *data = g_new0(PnMovementData, 1);
+}
+
+static void
+xform_movement_cleanup (gpointer data)
+{
+    PnMovementData *d = (PnMovementData *) data;
+
+    if (d)
+      {
+         if (d->vfield)
+ 	     g_free (d->vfield);
+         g_free (d);
+      }
+}
+
+inline void
+xform_trans_polar (struct xform_vector *vfield, gint x, gint y,
+	expression_t *expr, symbol_dict_t *dict)
+{
+  gdouble *rf, *df;
+  gdouble xf, yf;
+  gint xn, yn;
+
+  rf = dict_variable(dict, "r");
+  df = dict_variable(dict, "d");
+
+  /* Points (xf, yf) must be in a (-1..1) square. */
+  xf = 2.0 * x / (pn_image_data->width - 1) - 1.0;
+  yf = 2.0 * y / (pn_image_data->height - 1) - 1.0;
+
+  /* Now, convert to polar coordinates r and d. */
+  *rf = hypot(xf, yf);
+  *df = atan2(yf, xf);
+
+  /* Run the script. */
+  expr_execute(expr, dict);
+
+  /* Back to (-1..1) square. */
+  xf = (*rf) * cos ((*df));
+  yf = (*rf) * sin ((*df));
+
+  /* Convert back to physical coordinates. */
+  xn = (int)(((xf + 1.0) * (pn_image_data->width - 1) / 2) + 0.5);
+  yn = (int)(((yf + 1.0) * (pn_image_data->height - 1) / 2) + 0.5);
+
+  if (xn < 0 || xn >= pn_image_data->width || yn < 0 || yn >= pn_image_data->height)
+    {
+      xn = x; yn = y;
+    }
+
+  xfvec (xn, yn, &vfield[PN_IMG_INDEX (x, y)]);
+}
+
+inline void
+xform_trans_literal (struct xform_vector *vfield, gint x, gint y,
+	expression_t *expr, symbol_dict_t *dict)
+{
+  gdouble rf, df;
+  gdouble *xf, *yf;
+  gint xn, yn;
+
+  xf = dict_variable(dict, "x");
+  yf = dict_variable(dict, "y");
+
+  /* Points (xf, yf) must be in a (-1..1) square. */
+  *xf = 2.0 * x / (pn_image_data->width - 1) - 1.0;
+  *yf = 2.0 * y / (pn_image_data->height - 1) - 1.0;
+
+  /* Run the script. */
+  expr_execute(expr, dict);
+
+  /* Convert back to physical coordinates. */
+  xn = (int)(((*xf + 1.0) * (pn_image_data->width - 1) / 2) + 0.5);
+  yn = (int)(((*yf + 1.0) * (pn_image_data->height - 1) / 2) + 0.5);
+
+  if (xn < 0 || xn >= pn_image_data->width || yn < 0 || yn >= pn_image_data->height)
+    {
+      xn = x; yn = y;
+    }
+
+  xfvec (xn, yn, &vfield[PN_IMG_INDEX (x, y)]);
+}
+
+static void
+xform_movement_exec (const struct pn_actuator_option *opts,
+		 gpointer odata)
+{
+  PnMovementData *d = (PnMovementData *) odata;
+  void (*transform_func)(struct xform_vector *, gint, gint, expression_t *, symbol_dict_t *) = 
+        opts[1].val.bval == TRUE ? xform_trans_polar : xform_trans_literal;
+
+  if (d->width != pn_image_data->width
+      || d->height != pn_image_data->height)
+    {
+      gint i, j;
+      gdouble *rf, *df;
+      gdouble xf, yf;
+      gint xn, yn;
+      expression_t *expr;
+      symbol_dict_t *dict;
+
+      d->width = pn_image_data->width;
+      d->height = pn_image_data->height;
+
+      if (d->vfield)
+        {
+  	  g_free (d->vfield);
+          d->vfield = NULL;
+        }
+
+      if (opts[0].val.sval == NULL)
+        return;
+
+      dict = dict_new();
+      expr = expr_compile_string(opts[0].val.sval, dict);
+      if (!expr)
+        {
+           dict_free(dict);
+           return;
+        }
+
+      rf = dict_variable(dict, "r");
+      df = dict_variable(dict, "d");
+
+      d->vfield = g_malloc (sizeof(struct xform_vector)
+			    * d->width * d->height);
+
+      for (j = 0; j < pn_image_data->height; j++)
+	for (i = 0; i < pn_image_data->width; i++)
+	  {
+            transform_func(d->vfield, i, j, expr, dict);
+	  }
+    }
+
+  apply_xform (d->vfield);
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_xform_movement =
+{
+  "xform_movement", "Movement Transform",
+  "A customizable blitter.",
+  0, xform_movement_opts,
+  xform_movement_init, xform_movement_cleanup, xform_movement_exec
+};
+
+/* **************** xform_dynmovement **************** */
+/* FIXME: really slow */
+struct pn_actuator_option_desc xform_dynmovement_opts[] =
+{
+  { "init_script", "The formula to evaluate on init.",
+    OPT_TYPE_STRING, { sval: "" } },
+  { "beat_script", "The formula to evaluate on each beat.",
+    OPT_TYPE_STRING, { sval: "" } },
+  { "frame_script", "The formula to evaluate on each frame.",
+    OPT_TYPE_STRING, { sval: "" } },
+  { "point_script", "The formula to evaluate.",
+    OPT_TYPE_STRING, { sval: "d = 0.15;" } },
+  { "polar", "Whether or not the coordinates to use are polar.",
+    OPT_TYPE_BOOLEAN, { bval: TRUE } },
+  { NULL }
+};
+
+typedef struct {
+  int width, height;                 /* Previous width and height. */
+  expression_t *expr_init;
+  expression_t *expr_frame;
+  expression_t *expr_beat;
+  expression_t *expr_point;
+  symbol_dict_t *dict;
+  struct xform_vector *vfield;
+} PnDynMovementData;
+
+static void
+xform_dynmovement_init (gpointer *data)
+{
+    *data = g_new0(PnDynMovementData, 1);
+}
+
+static void
+xform_dynmovement_cleanup (gpointer data)
+{
+    PnDynMovementData *d = (PnDynMovementData *) data;
+
+    if (d)
+      {
+         if (d->expr_init)
+             expr_free (d->expr_init);
+         if (d->expr_beat)
+             expr_free (d->expr_beat);
+         if (d->expr_frame)
+             expr_free (d->expr_frame);
+         if (d->expr_point)
+             expr_free (d->expr_point);
+         if (d->dict)
+             dict_free (d->dict);
+         if (d->vfield)
+ 	     g_free (d->vfield);
+         g_free (d);
+      }
+}
+
+static void
+xform_dynmovement_exec (const struct pn_actuator_option *opts,
+		 gpointer odata)
+{
+  PnDynMovementData *d = (PnDynMovementData *) odata;
+  gint i, j;
+  gdouble *rf, *df;
+  gdouble xf, yf;
+  gint xn, yn;
+  void (*transform_func)(struct xform_vector *, gint, gint, expression_t *, symbol_dict_t *) = 
+        opts[4].val.bval == TRUE ? xform_trans_polar : xform_trans_literal;
+  gboolean make_table = FALSE;
+
+  if (d->width != pn_image_data->width
+      || d->height != pn_image_data->height)
+    {
+      d->width = pn_image_data->width;
+      d->height = pn_image_data->height;
+
+      if (d->vfield)
+        {
+  	  g_free (d->vfield);
+          d->vfield = NULL;
+        }
+
+      if (opts[3].val.sval == NULL)
+          return;
+
+      if (!d->dict)
+          d->dict = dict_new();
+      else
+        {
+          dict_free(d->dict);
+          d->dict = dict_new();
+        }
+
+      if (d->expr_init)
+        {
+          expr_free(d->expr_init);
+          d->expr_init = NULL;
+        }
+
+      /* initialize */
+      d->expr_init = expr_compile_string(opts[0].val.sval, d->dict);
+
+      if (d->expr_init != NULL)
+        {
+           expr_execute(d->expr_init, d->dict);
+        }
+
+      d->expr_beat = expr_compile_string(opts[1].val.sval, d->dict);
+      d->expr_frame = expr_compile_string(opts[2].val.sval, d->dict);
+      d->expr_point = expr_compile_string(opts[3].val.sval, d->dict);
+
+      d->vfield = g_malloc (sizeof(struct xform_vector)
+			    * d->width * d->height);
+
+      make_table = TRUE;
+   }
+
+   rf = dict_variable(d->dict, "r");
+   df = dict_variable(d->dict, "d");
+
+   if (*opts[2].val.sval != '\0' || pn_new_beat)
+       make_table = TRUE;
+
+   /* run the on-frame script. */
+   if (make_table == TRUE)
+     {
+       if (d->expr_beat != NULL)
+         expr_execute(d->expr_beat, d->dict);
+
+       if (d->expr_frame != NULL)
+         expr_execute(d->expr_frame, d->dict);
+
+       for (j = 0; j < pn_image_data->height; j++)
+         for (i = 0; i < pn_image_data->width; i++)
+           {
+             transform_func(d->vfield, i, j, d->expr_point, d->dict);
+           }
+     }
+
+  apply_xform (d->vfield);
+  pn_swap_surfaces ();
+}
+
+struct pn_actuator_desc builtin_xform_dynmovement =
+{
+  "xform_dynmovement", "Dynamic Movement Transform",
+  "A customizable blitter.",
+  0, xform_dynmovement_opts,
+  xform_dynmovement_init, xform_dynmovement_cleanup, xform_dynmovement_exec
+};