aboutsummaryrefslogtreecommitdiff
path: root/gem_counter.c
diff options
context:
space:
mode:
Diffstat (limited to 'gem_counter.c')
-rw-r--r--gem_counter.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/gem_counter.c b/gem_counter.c
new file mode 100644
index 0000000..da4434f
--- /dev/null
+++ b/gem_counter.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 1997-1999 Mark Danks.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
+ */
+
+#include "m_pd.h"
+
+/* -------------------------- gem_counter ------------------------------ */
+
+/* instance structure */
+static t_class *gem_counter_class;
+
+typedef struct _gem_counter
+{
+ t_object x_obj; /* obligatory object header */
+ int c_current; /* current number */
+ int c_high; /* highest number */
+ int c_low; /* lowest number */
+ int c_updown; /* 0 = going up, 1 = going down */
+ int c_dir; /* gem_counter dir. 1=up, 2=down, 3=up/down */
+ t_outlet *t_out1; /* the outlet */
+ t_outlet *t_out2; /* the outlet */
+} t_gem_counter;
+
+void gem_counter_bang(t_gem_counter *x)
+{
+ int sendBang = 0;
+ switch(x->c_dir)
+ {
+ // count up
+ case 1:
+ x->c_current++;
+ if (x->c_current > x->c_high)
+ x->c_current = x->c_low;
+ else if (x->c_current < x->c_low)
+ x->c_current = x->c_low;
+ else if (x->c_current == x->c_high)
+ sendBang = 1;
+ break;
+ // count down
+ case 2:
+ x->c_current--;
+ if (x->c_current < x->c_low)
+ x->c_current = x->c_high;
+ else if (x->c_current > x->c_high)
+ x->c_current = x->c_high;
+ else if (x->c_current == x->c_low)
+ sendBang = 1;
+ break;
+ // count up and down
+ case 3:
+ // going up
+ if (x->c_updown == 0)
+ {
+ x->c_current++;
+ if (x->c_current > x->c_high)
+ {
+ x->c_current = x->c_high - 1;
+ x->c_updown = 1;
+ }
+ else if (x->c_current < x->c_low)
+ x->c_current = x->c_low;
+ else if (x->c_current == x->c_high)
+ sendBang = 1;
+ }
+ // going down
+ else if (x->c_updown == 1)
+ {
+ x->c_current--;
+ if (x->c_current < x->c_low)
+ {
+ x->c_current = x->c_low + 1;
+ x->c_updown = 0;
+ }
+ else if (x->c_current > x->c_high)
+ x->c_current = x->c_high;
+ else if (x->c_current == x->c_low)
+ sendBang = 1;
+ }
+ else
+ {
+ error("up/down wrong");
+ return;
+ }
+ break;
+ default:
+ error("dir wrong");
+ return;
+ }
+ outlet_float(x->t_out1, (float)x->c_current);
+ if (sendBang)
+ outlet_bang(x->t_out2);
+}
+
+void gem_counter_dir(t_gem_counter *x, t_floatarg n)
+{
+ if (n == 1 || n == 2 || n == 3) x->c_dir = (int)n;
+ else error("bad dir");
+}
+
+void gem_counter_high(t_gem_counter *x, t_floatarg n)
+{
+ x->c_high = (int)n;
+}
+
+void gem_counter_low(t_gem_counter *x, t_floatarg n)
+{
+ x->c_low = (int)n;
+}
+
+void gem_counter_reset(t_gem_counter *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (!argc)
+ {
+ switch(x->c_dir)
+ {
+ case 1:
+ x->c_current = x->c_low;
+ break;
+ case 2:
+ x->c_current = x->c_high;
+ break;
+ case 3:
+ if (x->c_updown == 0) x->c_current = x->c_low;
+ else if (x->c_updown == 1) x->c_current = x->c_high;
+ break;
+ default:
+ return;
+ }
+ }
+ else
+ {
+ switch(argv[0].a_type)
+ {
+ case A_FLOAT :
+ x->c_current = (int)argv[0].a_w.w_float;
+ break;
+ default :
+ error ("gem_counter: reset not float");
+ break;
+ }
+ }
+ outlet_float(x->t_out1, (float)x->c_current);
+}
+
+void gem_counter_clear(t_gem_counter *x, t_symbol *s, int argc, t_atom *argv)
+{
+ if (!argc)
+ {
+ switch(x->c_dir)
+ {
+ case 1:
+ x->c_current = x->c_low - 1;
+ break;
+ case 2:
+ x->c_current = x->c_high + 1;
+ break;
+ case 3:
+ if (x->c_updown == 0) x->c_current = x->c_low - 1;
+ else if (x->c_updown == 1) x->c_current = x->c_high + 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch(argv[0].a_type)
+ {
+ case A_FLOAT :
+ x->c_current = (int)argv[0].a_w.w_float - 1;
+ break;
+ default :
+ error ("gem_counter: reset not float");
+ break;
+ }
+ }
+}
+
+void *gem_counter_new(t_floatarg f, t_floatarg g, t_floatarg h) /* init vals in struc */
+{
+ t_gem_counter *x = (t_gem_counter *)pd_new(gem_counter_class);
+ x->t_out1 = outlet_new(&x->x_obj, 0);
+ x->t_out2 = outlet_new(&x->x_obj, 0);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl1"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl2"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("fl3"));
+ x->c_current = 0;
+ x->c_updown = 0;
+ if (h)
+ {
+ gem_counter_low(x, f);
+ gem_counter_high(x, g);
+ gem_counter_dir(x, h);
+ }
+ else if (g)
+ {
+ x->c_dir = 1;
+ gem_counter_low(x, f);
+ gem_counter_high(x, g);
+ }
+ else if (f)
+ {
+ x->c_dir = x->c_low = 1;
+ gem_counter_high(x, f);
+ }
+ else
+ {
+ x->c_dir = x->c_low = 1;
+ x->c_high = 10;
+ }
+ return (x);
+}
+
+void gem_counter_setup(void)
+{
+ gem_counter_class = class_new(gensym("gem_counter"), (t_newmethod)gem_counter_new, 0,
+ sizeof(t_gem_counter), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addbang(gem_counter_class, (t_method)gem_counter_bang);
+ class_addmethod(gem_counter_class, (t_method)gem_counter_dir, gensym("fl1"), A_FLOAT, 0);
+ class_addmethod(gem_counter_class, (t_method)gem_counter_low, gensym("fl2"), A_FLOAT, 0);
+ class_addmethod(gem_counter_class, (t_method)gem_counter_high, gensym("fl3"), A_FLOAT, 0);
+ class_addmethod(gem_counter_class, (t_method)gem_counter_reset, gensym("reset"), A_GIMME, 0);
+ class_addmethod(gem_counter_class, (t_method)gem_counter_clear, gensym("clear"), A_GIMME, 0);
+
+ class_sethelpsymbol(gem_counter_class, gensym("help-gem_counter"));
+}