aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/past.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/hammer/past.c')
-rw-r--r--cyclone/hammer/past.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/cyclone/hammer/past.c b/cyclone/hammer/past.c
new file mode 100644
index 0000000..eb29c8e
--- /dev/null
+++ b/cyclone/hammer/past.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2002-2003 krzYszcz and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* CHECKED:
+ bang for a float at > (refman error: >=)
+ bang for a list if all >= (refman page says the same)
+ bang for a list if any is >, even if the rest (but not previous) is <
+ well...
+*/
+
+#include "m_pd.h"
+#include "common/loud.h"
+#include "common/grow.h"
+
+#define PAST_MAXSIZE 8 /* CHECKED */
+
+typedef struct past
+{
+ t_object x_ob;
+ int x_low;
+ int x_size; /* as allocated */
+ int x_nthresh; /* as used */
+ t_atom *x_thresh;
+ t_atom x_thrini[PAST_MAXSIZE];
+} t_past;
+
+static t_class *past_class;
+
+static int past_compare(t_past *x, t_float f, t_atom *ap)
+{
+ if (ap->a_type == A_FLOAT)
+ {
+ if (f > ap->a_w.w_float)
+ return (1);
+ else if (f == ap->a_w.w_float)
+ return (0);
+ else
+ return (-1);
+ }
+ else /* CHECKED */
+ {
+ if (f > 0.)
+ return (1);
+ else if (f == 0.)
+ return (0);
+ else
+ return (-1);
+ }
+}
+
+static void past_float(t_past *x, t_float f)
+{
+ if (x->x_nthresh == 1)
+ {
+ if (past_compare(x, f, x->x_thresh) > 0) /* CHECKED: equal is low */
+ {
+ if (x->x_low)
+ {
+ x->x_low = 0;
+ outlet_bang(((t_object *)x)->ob_outlet);
+ }
+ }
+ else x->x_low = 1;
+ }
+ else if (past_compare(x, f, x->x_thresh) < 0) x->x_low = 1;
+}
+
+/* CHECKME: x_low handling */
+static void past_list(t_past *x, t_symbol *s, int ac, t_atom *av)
+{
+ if (ac && ac <= x->x_nthresh)
+ {
+ int result;
+ t_atom *vp = x->x_thresh;
+ if (av->a_type == A_FLOAT
+ && (result = past_compare(x, av->a_w.w_float, vp)) >= 0)
+ {
+ if (!result)
+ {
+ for (ac--, av++, vp++; ac; ac--, av++, vp++)
+ {
+ if (av->a_type != A_FLOAT
+ || (result =
+ past_compare(x, av->a_w.w_float, vp++)) < 0)
+ {
+ x->x_low = 1;
+ return;
+ }
+ if (result) break;
+ }
+ }
+ if (x->x_low)
+ {
+ x->x_low = 0;
+ outlet_bang(((t_object *)x)->ob_outlet);
+ }
+ }
+ else x->x_low = 1;
+ }
+}
+
+static void past_clear(t_past *x)
+{
+ x->x_low = 1;
+}
+
+static void past_set(t_past *x, t_symbol *s, int ac, t_atom *av)
+{
+ if (ac)
+ {
+ t_atom *vp = x->x_thresh;
+ if (ac > x->x_size)
+ {
+ loud_incompatible_max(past_class, PAST_MAXSIZE, "guard points");
+ x->x_thresh = grow_nodata(&ac, &x->x_size, x->x_thresh,
+ PAST_MAXSIZE, x->x_thrini,
+ sizeof(*x->x_thresh));
+ }
+ x->x_nthresh = ac;
+ while (ac--) *vp++ = *av++;
+ /* CHECKED: x_low is not set here */
+ }
+}
+
+static void past_free(t_past *x)
+{
+ if (x->x_thresh != x->x_thrini)
+ freebytes(x->x_thresh, x->x_size * sizeof(*x->x_thresh));
+}
+
+static void *past_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_past *x = (t_past *)pd_new(past_class);
+ x->x_low = 1;
+ x->x_nthresh = 0;
+ x->x_size = PAST_MAXSIZE;
+ x->x_thresh = x->x_thrini;
+ outlet_new((t_object *)x, &s_bang);
+ past_set(x, 0, ac, av);
+ return (x);
+}
+
+void past_setup(void)
+{
+ past_class = class_new(gensym("past"),
+ (t_newmethod)past_new,
+ (t_method)past_free,
+ sizeof(t_past), 0, A_GIMME, 0);
+ class_addfloat(past_class, past_float);
+ class_addlist(past_class, past_list);
+ class_addmethod(past_class, (t_method)past_clear, gensym("clear"), 0);
+ class_addmethod(past_class, (t_method)past_set, gensym("set"), A_GIMME, 0);
+}