aboutsummaryrefslogtreecommitdiff
path: root/rawjoystick.c
diff options
context:
space:
mode:
Diffstat (limited to 'rawjoystick.c')
-rw-r--r--rawjoystick.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/rawjoystick.c b/rawjoystick.c
new file mode 100644
index 0000000..73dce1e
--- /dev/null
+++ b/rawjoystick.c
@@ -0,0 +1,185 @@
+/*
+'pd_joystick' (An external library for Miller Puckette's 'PD' software
+adding PC and/or USB joystick control capabilities)
+
+Copyright (C) 2001 Joseph A. Sarlo
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+jsarlo@peabody.jhu.edu
+*/
+
+#include "m_pd.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#ifdef USB
+#define JOYSTICK_DEVICE "/dev/input/js0"
+#else
+#define JOYSTICK_DEVICE "dev/js0"
+#endif
+
+// scaling factor for output
+#define DEF_SCALE 1
+// delay/refresh time in milliseconds
+#define DEF_DELTIME 5
+// this object handles a maximum of 10 axes
+#define MAX_AXIS_OUTS 10
+// input event types
+#define JS_EVENT_BUTTON 0x01
+#define JS_EVENT_AXIS 0x02
+#define JS_EVENT_INIT 0x80
+
+// ise ioctl() to get number of axes and buttons from device
+#define JSIOCGAXES _IOR('j', 0x11, unsigned char)
+#define JSIOCGBUTTONS _IOR('j', 0x12, unsigned char)
+
+struct js_event
+{
+ unsigned int time;
+ signed short value;
+ unsigned char type;
+ unsigned char number;
+};
+
+typedef struct _joystick
+{
+ t_object t_ob;
+ struct js_event x_joy_e;
+ int x_joy_fd;
+ float x_scale;
+ float x_translation;
+ t_outlet *x_axis_out[10];
+ t_outlet *x_button_num_out;
+ t_outlet *x_button_val_out;
+ t_clock *x_clock;
+ double x_deltime;
+ unsigned char x_joy_buttons;
+ unsigned char x_joy_axes;
+}t_joystick;
+
+t_class *joystick_class;
+
+void *joystick_new(t_float deltime, t_float scale, t_float translation);
+void joystick_setup(void);
+void joystick_read(t_joystick *x);
+void joystick_change_deltime(t_joystick *x, t_float deltime);
+void joystick_free(t_joystick *x);
+
+void *joystick_new(t_float deltime, t_float scale, t_float translation)
+{
+ int i, num_axes;
+
+ t_joystick *x = (t_joystick *)pd_new(joystick_class);
+
+ // open the joystick device read-only, non-exclusive
+ x->x_joy_fd = open (JOYSTICK_DEVICE, O_RDONLY | O_NONBLOCK);
+
+ // read js_events from the JOYSTICK_DEVICE stream
+ while (read (x->x_joy_fd, &(x->x_joy_e), sizeof(struct js_event)) > -1);
+
+ // if deltime is set in the object's creation arguments
+ // use that value, otherwise use the default
+ if (deltime == 0)
+ x->x_deltime = DEF_DELTIME;
+ else
+ x->x_deltime = (int)deltime;
+
+ // if scale is set in the object's creation arguments
+ // use that value, otherwise use the default
+ if (scale == 0)
+ x->x_scale = DEF_SCALE;
+ else
+ x->x_scale = scale;
+
+ // get translation from object arguments
+ x->x_translation = translation;
+ x->x_joy_axes = 0;
+ x->x_joy_buttons = 0;
+
+ // get number of axes and buttons from device
+ ioctl (x->x_joy_fd, JSIOCGAXES, &(x->x_joy_axes));
+ ioctl (x->x_joy_fd, JSIOCGBUTTONS, &(x->x_joy_buttons));
+
+ // this object handles a maximum of MAX_AXIS_OUTS axes
+ // if there are more, limit to MAX_AXIS_OUTS
+ if (x->x_joy_axes > MAX_AXIS_OUTS)
+ num_axes = MAX_AXIS_OUTS;
+ else
+ num_axes = x->x_joy_axes;
+
+ // create outlets for each axis
+ for (i = 0; i < num_axes; i++)
+ x->x_axis_out[i] = outlet_new(&x->t_ob, &s_float);
+
+ // create outlets for buttons
+ x->x_button_num_out = outlet_new(&x->t_ob, &s_float);
+ x->x_button_val_out = outlet_new(&x->t_ob, &s_float);
+
+
+ x->x_clock = clock_new (x, (t_method)joystick_read);
+
+ clock_delay (x->x_clock, x->x_deltime);
+
+ post ("configuring joystick:");
+ post (" found %d axes", x->x_joy_axes);
+ post (" found %d buttons", x->x_joy_buttons);
+ return (void *)x;
+}
+
+void joystick_setup(void)
+{
+ post ("joystick object loaded (J. Sarlo)");
+ joystick_class = class_new(gensym("joystick"),(t_newmethod)joystick_new,
+ (t_method)joystick_free, sizeof(t_joystick), 0, A_DEFFLOAT, A_DEFFLOAT,
+ A_DEFFLOAT, 0);
+ class_addfloat(joystick_class, joystick_change_deltime);
+}
+
+void joystick_read(t_joystick *x)
+{
+ int rt;
+ while (read (x->x_joy_fd, &(x->x_joy_e), sizeof(struct js_event)) > -1)
+ {
+ if (x->x_joy_e.type == JS_EVENT_AXIS)
+ {
+ outlet_float (x->x_axis_out[x->x_joy_e.number],
+ ((int)x->x_joy_e.value + x->x_translation) / x->x_scale);
+ }
+ else if (x->x_joy_e.type == JS_EVENT_BUTTON)
+ {
+ outlet_float (x->x_button_val_out, x->x_joy_e.value);
+ outlet_float (x->x_button_num_out, x->x_joy_e.number);
+ }
+ }
+ clock_delay (x->x_clock, x->x_deltime);
+}
+
+void joystick_change_deltime(t_joystick *x, t_float deltime)
+{
+ if (deltime < 0)
+ deltime = 0;
+ x->x_deltime = deltime;
+}
+
+void joystick_free(t_joystick *x)
+{
+ close (x->x_joy_fd);
+ clock_free (x->x_clock);
+}