aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--help-ifeel.pd34
-rw-r--r--ifeel.c142
3 files changed, 124 insertions, 54 deletions
diff --git a/Makefile b/Makefile
index aa064a3..800d171 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ LINUXCFLAGS = -DUNIX -DPD -O2 -funroll-loops -fomit-frame-pointer \
LINUXINCLUDE = -I/usr/local/lib/pd/include -I../../pd/src
.c.pd_linux:
- cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
+ gcc-3.2 $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c
ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm
strip --strip-unneeded $*.pd_linux
rm $*.o
diff --git a/help-ifeel.pd b/help-ifeel.pd
new file mode 100644
index 0000000..7001c79
--- /dev/null
+++ b/help-ifeel.pd
@@ -0,0 +1,34 @@
+#N canvas 736 320 450 300 10;
+#X obj 105 228 ifeel /dev/input/ifeel0;
+#X obj 160 82 hsl 128 20 0 255 0 0 empty empty interval_(0-255) 6 8
+32 8 -225271 -1 -1 12700 0;
+#X obj 212 130 hsl 128 20 0 255 0 0 empty empty count_(0-255) 6 8 32
+8 -261681 -1 -1 0 0;
+#X obj 264 178 hsl 128 20 0 1 0 0 empty empty level_(0-1) 6 8 32 8
+-261689 -1 -1 12700 0;
+#X obj 61 157 bng 25 250 50 0 empty empty empty 0 -6 32 8 -24198 -1
+-1;
+#X obj 105 157 bng 25 250 50 0 empty empty empty 0 -6 32 8 -258699
+-1 -1;
+#X msg 105 187 stop;
+#X msg 61 187 start;
+#X obj 261 201 nbx 5 14 -1e+37 1e+37 0 0 pack_bang_env empty empty
+0 -6 33 10 -233017 -1 -1 1 256;
+#X obj 209 153 nbx 3 14 -1e+37 1e+37 0 0 pack_bang_env empty empty
+0 -6 33 10 -233017 -1 -1 0 256;
+#X obj 157 105 nbx 3 14 -1e+37 1e+37 0 0 pack_bang_env empty empty
+0 -6 33 10 -233017 -1 -1 255 256;
+#X obj 120 9 cnv 15 20 20 empty empty ifeel 4 12 33 14 -228992 -66577
+0;
+#X text 190 15 control the pulse in an iFeel mouse;
+#X obj 4 13 force-feedback;
+#X connect 1 0 10 0;
+#X connect 2 0 9 0;
+#X connect 3 0 8 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 3;
+#X connect 9 0 0 2;
+#X connect 10 0 0 1;
diff --git a/ifeel.c b/ifeel.c
index e6a6aa9..2b13576 100644
--- a/ifeel.c
+++ b/ifeel.c
@@ -18,6 +18,13 @@
* based on ifeel_send.c from the linux iFeel driver:
* http://sourceforge.net/projects/tactile
*
+ * there is a difference in the naming schemes of the ifeel driver and this
+ * object. The ifeel driver uses strength, delay, and count. This object
+ * uses level, interval, and count.
+ *
+ * strength/level - the strength of the pulse (I am searching for a better word)
+ * delay/interval - the interval in between each pulse
+ * count - the total number of pulses to do
*/
#include "m_pd.h"
@@ -30,10 +37,15 @@
#include <fcntl.h>
#include <errno.h>
#include <string.h>
+#include <time.h>
#include "ifeel.h"
+#define DEBUG(x)
+/*#define DEBUG(x) x */
+
+
#define IFEEL_DEVICE "/dev/input/ifeel0"
static t_class *ifeel_class;
@@ -47,76 +59,96 @@ typedef struct _ifeel {
/******************************************************************************
-general ff methods
+support functions
******************************************************************************/
-void ifeel_start(t_ifeel *x)
-{
- post("ifeel_start");
-
+void ifeel_playcommand(t_ifeel *x) {
+/* const struct timespec *requested_time; */
+/* struct timespec *remaining; */
+
if (ioctl(x->x_fd, USB_IFEEL_BUZZ_IOCTL, &x->x_ifeel_command) < 0) {
- printf("ERROR %s\n", strerror(errno));
- }
+ post("x->x_fd: %d",x->x_fd);
+ post("level: %d interval: %d count: %d",x->x_ifeel_command.strength,x->x_ifeel_command.delay,x->x_ifeel_command.count);
+ post("ERROR %s", strerror(errno));
+ close(x->x_fd);
+ }
+
+ DEBUG(
+ post("level: %d interval: %d count: %d",x->x_ifeel_command.strength,x->x_ifeel_command.delay,x->x_ifeel_command.count);
+ post("");)
}
-void ifeel_stop(t_ifeel *x)
-{
- post("ifeel_stop");
+
+/******************************************************************************
+input/control functions
+******************************************************************************/
+void ifeel_start(t_ifeel *x) {
+ DEBUG(post("ifeel_start");)
+
+ /*
+ * since ifeel_stop sets everything to zero, we need to
+ * read the inlets again to get current values
+ */
+
+ ifeel_playcommand(x);
+}
+
+void ifeel_stop(t_ifeel *x) {
+ DEBUG(post("ifeel_stop");)
+ /*
+ * there is no 'stop' ioctl, so set everything to zero
+ * to achieve the same effect
+ */
x->x_ifeel_command.strength = 0;
x->x_ifeel_command.delay = 0;
x->x_ifeel_command.count = 0;
- if (ioctl(x->x_fd, USB_IFEEL_BUZZ_IOCTL, &x->x_ifeel_command) < 0) {
- printf("ERROR %s\n", strerror(errno));
- }
+
+ ifeel_playcommand(x);
}
-void ifeel_level(t_ifeel *x, t_floatarg level)
-{
- post("ifeel_level");
+void ifeel_level(t_ifeel *x, t_floatarg level) {
+ DEBUG(post("ifeel_level");)
- /* make sure its in the proper range */
+ /*
+ * make sure its in the proper range
+ * this object takes floats 0-1
+ * the ifeel driver takes ints 0-255
+ */
level = level * 255;
level = (level > 255 ? 255 : level);
level = (level < 0 ? 0 : level);
x->x_ifeel_command.strength = (unsigned int)level;
-
- if (ioctl(x->x_fd, USB_IFEEL_BUZZ_IOCTL, &x->x_ifeel_command) < 0) {
- printf("ERROR %s\n", strerror(errno));
- }
-
}
-void ifeel_interval(t_ifeel *x, t_floatarg interval)
-{
- post("ifeel_interval");
+void ifeel_interval(t_ifeel *x, t_floatarg interval) {
+ DEBUG(post("ifeel_interval");)
interval = (interval < 0 ? 0 : interval);
x->x_ifeel_command.delay = (unsigned int)interval;
-
- if (ioctl(x->x_fd, USB_IFEEL_BUZZ_IOCTL, &x->x_ifeel_command) < 0) {
- printf("ERROR %s\n", strerror(errno));
- }
}
-void ifeel_count(t_ifeel *x, t_floatarg count )
-{
- post("ifeel_count");
+void ifeel_count(t_ifeel *x, t_floatarg count ) {
+ DEBUG(post("ifeel_count");)
- count = (count < 0 ? 0 : count);
+ count = (count < 0 ? 0 : count);
x->x_ifeel_command.count = (unsigned int)count;
+}
- if (ioctl(x->x_fd, USB_IFEEL_BUZZ_IOCTL, &x->x_ifeel_command) < 0) {
- printf("ERROR %s\n", strerror(errno));
- }
+static int ifeel_open(t_ifeel *x) {
+ return 1;
}
+/******************************************************************************
+ init/free functions
+******************************************************************************/
+
void ifeel_free(t_ifeel *x)
{
- post("ifeel_free");
+ DEBUG(post("ifeel_free");)
/* stop effect */
ifeel_stop(x);
@@ -125,12 +157,19 @@ void ifeel_free(t_ifeel *x)
close(x->x_fd);
}
-void *ifeel_new(t_symbol *device, t_floatarg level, t_floatarg interval, t_floatarg count)
-{
- post("ifeel_new");
-
+void *ifeel_new(t_symbol *device, t_floatarg level, t_floatarg interval, t_floatarg count) {
+ DEBUG(post("ifeel_new");)
+
t_ifeel *x = (t_ifeel *)pd_new(ifeel_class);
+ post("iFeel mouse, by Hans-Christoph Steiner <hans@eds.org>");
+ post("");
+ post ("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING");
+ post ("This object is under development! The interface could change at anytime!");
+ post ("As I write cross-platform versions, the interface might have to change.");
+ post ("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING");
+ post("");
+
/*
* init to zero so I can use the ifeel_* methods to set the
* struct with the argument values
@@ -142,7 +181,7 @@ void *ifeel_new(t_symbol *device, t_floatarg level, t_floatarg interval, t_float
inlet_new(&x->x_obj,
&x->x_obj.ob_pd,
gensym("float"),
- gensym("direction"));
+ gensym("interval"));
inlet_new(&x->x_obj,
&x->x_obj.ob_pd,
gensym("float"),
@@ -156,15 +195,16 @@ void *ifeel_new(t_symbol *device, t_floatarg level, t_floatarg interval, t_float
post("Using %s",device->s_name);
/* x->x_fd = open(IFEEL_DEVICE, O_RDWR); */
- /* x->x_fd = open((char *) device->s_name, O_RDWR); */
if ((x->x_fd = open((char *) device->s_name, O_RDWR | O_NONBLOCK, 0)) <= 0) {
printf("ERROR %s\n", strerror(errno));
+ return 0;
}
-
- ifeel_level(x,level);
- ifeel_interval(x,interval);
- ifeel_count(x,count);
+
+/* ifeel_level(x,level); */
+/* ifeel_interval(x,interval); */
+/* ifeel_count(x,count); */
}
+
else {
post("ifeel: You need to set an ifeel device (i.e /dev/input/ifeel0)");
}
@@ -172,13 +212,9 @@ void *ifeel_new(t_symbol *device, t_floatarg level, t_floatarg interval, t_float
return (void*)x;
}
-/******************************************************************************
- initialisation functions
-******************************************************************************/
-
void ifeel_setup(void)
{
- post("ifeel_setup");
+ DEBUG(post("ifeel_setup");)
ifeel_class = class_new(gensym("ifeel"),
(t_newmethod)ifeel_new,
@@ -193,7 +229,7 @@ void ifeel_setup(void)
class_addbang(ifeel_class,ifeel_start);
- class_addmethod(ifeel_class, (t_method)ifeel_stop,gensym("start"),0);
+ class_addmethod(ifeel_class, (t_method)ifeel_start,gensym("start"),0);
class_addmethod(ifeel_class, (t_method)ifeel_stop,gensym("stop"),0);
class_addmethod(ifeel_class, (t_method)ifeel_level, gensym("level"), A_DEFFLOAT,0);