# HG changeset patch # User William Pitcock # Date 1192447213 18000 # Node ID 1fa3c8cd366a03e4084aef3aa08398137215d306 # Parent e5b639ab62b0729da1388dd95545bf266eac44f0 paranormal-ng: a GL visualiser. lots to do, most stuff won't work, but hey, this will do cool stuff too soon diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/.depend diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/Makefile --- /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 diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/TODO --- /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 amount of instructions.. step increases or decreases + on beat + +- container_repeat + executes the child instructions amount of times.. step + increases or decreases on beat + + diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/actuators.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include + +#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); +} + diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/actuators.h --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 +#include + +/* 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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/beatdetect.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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; +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/builtins.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#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 +}; diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/cfg.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include +#include +#include + +#include + +#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; idesc->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); +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/cmaps.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include + +#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 to " + "", + 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 +}; diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/containers.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include + +#include + +#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) +}; diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/containers.h --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/drawing.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#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); + } + } +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/drawing.h --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#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 diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/freq.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include +#include + +#include + +#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; jfreq_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 +}; diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/general.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#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; jheight; j++) + for (i=0; iwidth; 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; jheight; j++) + for (i=0; iwidth; 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; jheight; j += radius) + for (i=0; iwidth; 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 +}; + diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/.depend diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/.deps --- /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 diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/calc.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 + * + * 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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/dict.c --- /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 + * + * 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 +#include + +#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; +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/dict.h --- /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 + * + * 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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/execute.c --- /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 + * + * 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 +#include + +#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; + } + } +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/execute.h --- /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 + * + * 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 + +#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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/function.c --- /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 + * + * 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 +#include +#include + +#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)); +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/function.h --- /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 + * + * 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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/parser.c --- /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 +#include +#include +#include +#include +#include + +#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 /* 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 /* 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 /* 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; +} + + diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/parser.h --- /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 + * + * 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 +#include +#include +#include + +#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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/parser.yacc --- /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 + * + * 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 +#include +#include +#include +#include +#include + +#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 NAME +%token 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; +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/storage.c --- /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 + * + * 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 +#include + +#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)); +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/libcalc/storage.h --- /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 + * + * 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 + +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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/misc.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include +#include + +#include + +#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 +}; + diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/paranormal.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include +#include +#include +#include + +#include + +#include +#include + +#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(); +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/paranormal.h --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 +#include +#include + +#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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/plugin.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#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 \n\ +Portions Copyright (C) 2001, Jamie Gennis \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 (); + } +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/pn_utils.h --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include + +#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, " \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\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, "\n\n\n"); + + if (actuator) + if (! save_preset_recursive (file, actuator, 1)) + { + fclose (file); + return FALSE; + } + + fprintf (file, ""); + + fclose (file); + + return TRUE; + +} diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets.h --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#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 */ diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/.depend diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/.depend-done diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/Makefile --- /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 diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_bloody_vortex.pnv --- /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 @@ + + + + + + + + + 0 + 255 + 255, 64, 0 + 128, 0, 0 + + + + 4 + + + + + 3 + + + 39.00000 + 255 + + + -2.00000 + 0.00000 + 0.94000 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_cloudscape.pnv --- /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 @@ + + + + + + + 0 + 255 + 220, 225, 225 + + + + 0 + 251 + TRUE + + + 0.00000 + 0.00000 + 0.96500 + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_cloudscape2.pnv --- /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 @@ + + + + + + + 0 + 255 + 220, 225, 225 + + + 0 + 245 + 180, 180, 180 + + + + 0 + 250 + FALSE + + + 0.00000 + 0.12500 + 0.96500 + + + + + 1 + + + -1 + 255 + FALSE + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_dancing_snow.pnv --- /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 @@ + + + + + + + 0 + 255 + 146, 191, 225 + + + + 0.00000 + 0.00000 + 0.96500 + + + 1 + + + 1.00000 + 250 + + + + + + + 0.00000 + 10.00000 + 0.95000 + 0.10000 + + + -5.00000 + 0.00000 + 0.96500 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_portal_to_hell.pnv --- /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 @@ + + + + + + + 0 + 255 + 128, 85, 0 + + + + 1 + + + + + 0.00000 + 10.00000 + 2.00000 + 1.00000 + + + 1.50000 + 250 + + + 0.00000 + 0.00000 + 0.96500 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_stonervision.pnv --- /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 @@ + + + + + + + 0 + + + 5 + 250 + + + + + + + 1 + + + -1.00000 + 253 + + + 0.00000 + 8.00000 + 2.00000 + 5.00000 + + + 256 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + n = 800; t = -0.05; + t = t + 0.05; + d = index + value; r = t + index * 3.141952924 * 4; x = cos(r) * d; y = sin(r) * d; + TRUE + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/aerdan_-_telestatic.pnv --- /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 @@ + + + + + + + 0 + 255 + 220, 225, 225 + + + + 0 + 251 + TRUE + + + 0.00000 + 0.00000 + 0.96500 + + + + + -1 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nazca_-_smoke_on_the_water.pnv --- /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 @@ + + + + + + + + + + 0 + 255 + 0, 0, 0 + 72, 72, 255 + + + -1 + 255 + TRUE + + + 1 + 255 + TRUE + + + 0.00000 + 7.00000 + 1.00000 + 1.00000 + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_3d_wave.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 191, 255 + + + + 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; + ;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); + 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); + TRUE + + + 10 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_aquamarine_dream.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 161, 255 + + + + -1 + -1.00000 + 0.12500 + 0 + + + n = 800; t = -0.05; + t = t + 0.05; + d = index + value; r = t + index * 3.141952924 * 4; x = cos(r) * d; y = sin(r) * d; + TRUE + + + + + r = sin(r); d = cos(d)^2; + TRUE + + + + + 8 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_beatscope.pnv --- /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 @@ + + + + + + + 0 + 138 + 119, 239, 163 + + + 139 + 255 + 151, 179, 234 + + + + -1 + + + + + 0 + TRUE + + 0.00000 + 0.00000 + 1.04000 + + + 0.00000 + 0.00000 + 0.98700 + + + 0 + TRUE + + 0 + 138 + 119, 239, 163 + + + 139 + 255 + 151, 179, 234 + + + 0 + 138 + 151, 179, 234 + + + 139 + 255 + 119, 239, 163 + + + + 1.25000 + 0.00000 + 0.98700 + + + -1.25000 + 0.00000 + 1.04000 + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_branchscope.pnv --- /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 @@ + + + + + + + 0 + 138 + 119, 239, 163 + + + 139 + 255 + 151, 179, 234 + + + + + + + + 0 + TRUE + + + -1 + + + 0.00000 + + + + + -1 + + + + + 0.00000 + + + + + 0 + TRUE + + + + + + + + + 3 + + + + + 30 + + + + + 0 + TRUE + + 0 + 138 + 119, 239, 163 + + + 139 + 255 + 151, 179, 234 + + + + + 0 + 138 + 151, 179, 234 + + + 139 + 255 + 119, 239, 163 + + + + 0 + TRUE + + 0.00000 + 0.00000 + 0.98700 + + + 0.00000 + 0.00000 + 1.04000 + + + 1.25000 + 0.00000 + 0.98700 + + + -1.25000 + 0.00000 + 1.04000 + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_bumblebees.pnv --- /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 @@ + + + + + + + 0 + 255 + 238, 208, 83 + + + + -6 + 6.00000 + 0.12500 + 0 + + + 0.00000 + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_cubism.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 0, 255 + + + + -1 + 250 + TRUE + + + -1 + FALSE + + + 1 + FALSE + + + -4.00000 + 0.00000 + 0.90000 + + + 1.00000 + 0.00000 + -1.00000 + + + 0 + TRUE + + + + + + + 250 + 255 + 0 + + + 128 + 149 + 0 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_flying_into_pastels.pnv --- /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 @@ + + + + + + + 140 + 255 + 76, 122, 229 + + + + -6 + 6.00000 + 0.12500 + 0 + + + 0.00000 + + + 0.00000 + 8.00000 + 1.00000 + 1.00000 + + + + + 1 + + + -0.50000 + 0.00000 + 0.94000 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_interlaced.pnv --- /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 @@ + + + + + + + + + 0 + 255 + 0, 151, 255 + + + + + 180 + + + 180 + + + 180 + + + 180 + + + 180 + + + 180 + + + + + + + 250 + 255 + 150 + + + 1 + TRUE + + + + -1 + TRUE + + + 3 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_kaliedoscope.pnv --- /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 @@ + + + + + + + 0 + 255 + + + + + -1 + 255 + TRUE + + + d=cos(d)^2; + + + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_phosphor_flame.pnv --- /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 @@ + + + + + + + 0 + 255 + 120, 223, 193 + + + + + + 1 + + + + + 0.00000 + + + 0.00000 + 0.00000 + 1.04000 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_psuedo_starfield.pnv --- /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 @@ + + + + + + + 0 + 255 + 191, 191, 191 + + + + + + 0.00000 + 0.00000 + 0.97000 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_purple_flower.pnv --- /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 @@ + + + + + + + 0 + 255 + 118, 0, 191 + + + + 0.00000 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_quakingscope.pnv --- /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 @@ + + + + + + + 0 + 138 + 119, 239, 163 + + + 139 + 255 + 151, 179, 234 + + + + -1 + + + + + 0 + FALSE + + 0.00000 + 0.00000 + 1.04000 + + + 0.00000 + 0.00000 + 0.98700 + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_quasar.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 191, 255 + + + + 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; + ;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); + 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); + TRUE + + + 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; + ;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); + 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); + TRUE + + + 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; + ;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); + 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); + TRUE + + + 10 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_retroscope.pnv --- /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 @@ + + + + + + + 0 + 255 + 119, 239, 163 + + + + 255 + + + -1 + + + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_rush.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 0, 127 + 0, 127, 255 + + + + -1 + 255 + FALSE + + + -1 + 255 + FALSE + + + 0 + TRUE + + -4.00000 + 0.00000 + 0.75000 + + + 4.00000 + 0.00000 + 0.75000 + + + -8.00000 + 0.00000 + 0.75000 + + + 8.00000 + 0.00000 + 0.75000 + + + + 3 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_scopefun.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 191, 255 + + + + + + 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; + ;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); + 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); + TRUE + + + 10 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_simple_yet_pretty.pnv --- /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 @@ + + + + + + + 0 + 255 + 105, 32, 255 + + + + 0 + 255 + TRUE + + + 0 + 255 + TRUE + + + r = sin(r); d = cos(d)^2; + TRUE + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_smoke.pnv --- /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 @@ + + + + + + + 0 + 255 + 151, 179, 234 + + + + -1 + 180 + TRUE + + + 1 + 15 + 0 + + + 0.00000 + 0.00000 + 0.94000 + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_swarm.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 127, 255 + + + + + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + + 1.00000 + 0.00000 + 0.96000 + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_technicolour_nightmare.pnv --- /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 @@ + + + + + + + 0 + 255 + 100, 62, 191 + + + + -1 + 157 + TRUE + + + 0.03000 + 0.00000 + 1.04000 + + + 1 + + + -1 + 151 + TRUE + + + + -1 + + + + + 0 + FALSE + + 0 + 255 + 69, 75, 191 + + + 0 + 255 + 120, 191, 191 + + + 0 + 255 + 100, 62, 191 + + + 0 + 255 + 100, 191, 62 + + + 0 + 255 + 62, 191, 100 + + + 0 + 255 + 239, 123, 227 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_transform_fun.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 130, 191 + + + + points=512; dt=0.01; t=0; sc=1; + t=t+dt;dt=0.9*dt+0.001; + x=cos(2*index+t)*0.9*(value*0.5+0.5); y=sin(index*2+t)*0.9*(value*0.5+0.5); + TRUE + + + + + r=cos(r*3); d=sin(d*1.1) + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_trapped.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 161, 226 + + + + r=(tan(r)^sin(r)) + + + points=192; t = -0.05; + t = t + 0.05; + d = index + value; r = t + tan(index) * 3.141952924 * 4; x = (sin(r) * sin(d)) / 1.3; y = cos(r) * cos(d); + TRUE + + + 3 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_tunnel_vision.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 130, 191 + + + + -1 + 255 + TRUE + + + rseek=1.45; dseek=2; + + r=r/rseek; d=d*dseek; + + + + + + + 2 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_value_replace_fun.pnv --- /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 @@ + + + + + + + 0 + 255 + 151, 179, 234 + + + + -1 + + + 255 + 255 + 180 + + + 0.00000 + 0.00000 + 0.94000 + + + + + 1 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/nenolod_-_worms.pnv --- /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 @@ + + + + + + + 0 + 255 + 0, 127, 255 + + + + + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + 255 + + + + 0.00000 + 0.00000 + 1.02000 + + + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/presets/ticpu_-_colored_beat-o-scope.pnv --- /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 @@ + + + + + + + + + + + + + + + 8.00000 + 1.00000 + 0.60000 + + + + 3 + FALSE + + 26 + 169 + 0, 191, 255 + + + 0 + 94 + 83, 127, 150 + + + 84 + 255 + 208, 95, 89 + + + 0 + 173 + 71, 255, 51 + + + 114 + 255 + 242, 50, 253 + + + 0 + 157 + 15, 239, 231 + + + + 0 + FALSE + + + + + + + + + + + 8 + TRUE + + 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; + ;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); + 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); + TRUE + + + 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; + ;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); + 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); + TRUE + + + + 4 + + + \ No newline at end of file diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/wave.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include + +#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 +}; diff -r e5b639ab62b0 -r 1fa3c8cd366a src/paranormal-ng/xform.c --- /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 + * Portions copyright (c) 2001 Jamie Gennis + * + * 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 + +#include + +#include + +#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]; + iwidth*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); iwidth>>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); iwidth>>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); iwidth>>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 +};