aboutsummaryrefslogtreecommitdiff
path: root/wiiremote.c
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2009-10-03 17:37:35 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2009-10-03 17:37:35 +0000
commit816c8543c7409e52740ded50c0d00fe28925ae03 (patch)
treeea7b0522c20c03dec90199c29ec402ede72a5150 /wiiremote.c
parentbc16f1510f7900ba451ef71b2688bcd275c40e92 (diff)
renaming; trying to make wiimotion+ work
svn path=/trunk/externals/hardware/wiimote/; revision=12516
Diffstat (limited to 'wiiremote.c')
-rw-r--r--wiiremote.c196
1 files changed, 112 insertions, 84 deletions
diff --git a/wiiremote.c b/wiiremote.c
index 343a445..4b8955b 100644
--- a/wiiremote.c
+++ b/wiiremote.c
@@ -43,11 +43,8 @@ struct acc {
unsigned char z;
};
-/* Wiiremote Callback */
-cwiid_mesg_callback_t cwiid_callback;
-
// class and struct declarations for wiiremote pd external:
-static t_class *cwiid_class;
+static t_class *wiiremote_class;
typedef struct _wiiremote
{
t_object x_obj; // standard pd object (must be first in struct)
@@ -56,8 +53,9 @@ typedef struct _wiiremote
t_float connected;
int wiiremoteID;
-
- t_float toggle_acc, toggle_ir, toggle_nc;
+
+
+ int reportMode;
struct acc acc_zero, acc_one; // acceleration
struct acc nc_acc_zero, nc_acc_one; // nunchuck acceleration
@@ -67,8 +65,6 @@ typedef struct _wiiremote
} t_wiiremote;
-
-
// For now, we make one global t_wiiremote pointer that we can refer to
// in the cwiid_callback. This means we can support maximum of ONE
// wiiremote. ARGH. We'll have to figure out how to have access to the
@@ -83,7 +79,7 @@ typedef struct _wiiremoteList {
t_wiiremoteList*g_wiiremoteList=NULL;
-int addWiiremoteObject(t_wiiremote*x, int id) {
+static int addWiiremoteObject(t_wiiremote*x, int id) {
t_wiiremoteList*wl=g_wiiremoteList;
t_wiiremoteList*newentry=NULL;
if(NULL!=wl) {
@@ -114,7 +110,7 @@ int addWiiremoteObject(t_wiiremote*x, int id) {
return 1;
}
-t_wiiremote*getWiiremoteObject(const int id) {
+static t_wiiremote*getWiiremoteObject(const int id) {
t_wiiremoteList*wl=g_wiiremoteList;
if(NULL==wl)
return NULL;
@@ -128,7 +124,7 @@ t_wiiremote*getWiiremoteObject(const int id) {
return NULL;
}
-void removeWiiremoteObject(const t_wiiremote*x) {
+static void removeWiiremoteObject(const t_wiiremote*x) {
t_wiiremoteList*wl=g_wiiremoteList;
t_wiiremoteList*last=NULL;
if(NULL==wl)
@@ -156,14 +152,14 @@ void removeWiiremoteObject(const t_wiiremote*x) {
// ==============================================================
-void cwiid_debug(t_wiiremote *x)
+static void wiiremote_debug(t_wiiremote *x)
{
post("\n======================");
if (x->connected) post("Wiiremote (id: %d) is connected.", x->wiiremoteID);
else post("Wiiremote (id: %d) is NOT connected.", x->wiiremoteID);
- post("acceleration: %s", (x->toggle_acc)?"ON":"OFF");
- post("IR: %s", (x->toggle_ir)?"ON":"OFF");
- post("nunchuck: %s", (x->toggle_nc)?"ON":"OFF");
+ post("acceleration: %s", (x->reportMode & CWIID_RPT_ACC)?"ON":"OFF");
+ post("IR: %s", (x->reportMode & CWIID_RPT_IR)?"ON":"OFF");
+ post("extensions: %s", (x->reportMode & CWIID_RPT_EXT)?"ON":"OFF");
post("");
post("Accelerometer calibration: zero=(%d,%d,%d) one=(%d,%d,%d)",x->acc_zero.x,x->acc_zero.y,x->acc_zero.z,x->acc_one.x,x->acc_one.y,x->acc_one.z);
post("Nunchuck calibration: zero=(%d,%d,%d) one=(%d,%d,%d)",x->nc_acc_zero.x,x->nc_acc_zero.y,x->nc_acc_zero.z,x->nc_acc_one.x,x->nc_acc_one.y,x->nc_acc_one.z);
@@ -174,7 +170,7 @@ void cwiid_debug(t_wiiremote *x)
// ==============================================================
// Button handler:
-void cwiid_btn(t_wiiremote *x, struct cwiid_btn_mesg *mesg)
+static void wiiremote_cwiid_btn(t_wiiremote *x, struct cwiid_btn_mesg *mesg)
{
t_atom ap[2];
SETFLOAT(ap+0, (mesg->buttons & 0xFF00)>>8);
@@ -183,14 +179,10 @@ void cwiid_btn(t_wiiremote *x, struct cwiid_btn_mesg *mesg)
}
-void cwiid_acc(t_wiiremote *x, struct cwiid_acc_mesg *mesg)
+static void wiiremote_cwiid_acc(t_wiiremote *x, struct cwiid_acc_mesg *mesg)
{
double a_x, a_y, a_z;
t_atom ap[3];
-
- if(!x->toggle_acc)
- return;
-
a_x = ((double)mesg->acc[CWIID_X] - x->acc_zero.x) / (x->acc_one.x - x->acc_zero.x);
a_y = ((double)mesg->acc[CWIID_Y] - x->acc_zero.y) / (x->acc_one.y - x->acc_zero.y);
@@ -213,11 +205,9 @@ void cwiid_acc(t_wiiremote *x, struct cwiid_acc_mesg *mesg)
}
-void cwiid_ir(t_wiiremote *x, struct cwiid_ir_mesg *mesg)
+static void wiiremote_cwiid_ir(t_wiiremote *x, struct cwiid_ir_mesg *mesg)
{
unsigned int i;
- if(!x->toggle_ir)
- return;
//post("IR (valid,x,y,size) #%d: %d %d %d %d", i, data->ir_data.ir_src[i].valid, data->ir_data.ir_src[i].x, data->ir_data.ir_src[i].y, data->ir_data.ir_src[i].size);
for (i=0; i<CWIID_IR_SRC_COUNT; i++){
@@ -232,7 +222,7 @@ void cwiid_ir(t_wiiremote *x, struct cwiid_ir_mesg *mesg)
}
}
-void cwiid_nunchuk(t_wiiremote *x, struct cwiid_nunchuk_mesg *mesg)
+static void wiiremote_cwiid_nunchuk(t_wiiremote *x, struct cwiid_nunchuk_mesg *mesg)
{
t_atom ap[4];
double a_x, a_y, a_z;
@@ -272,6 +262,17 @@ void cwiid_nunchuk(t_wiiremote *x, struct cwiid_nunchuk_mesg *mesg)
outlet_anything(x->outlet_data, gensym("nunchuck"), 3, ap);
}
+static void wiiremote_cwiid_motionplus(t_wiiremote *x, struct cwiid_motionplus_mesg *mesg)
+{
+ t_atom ap[3];
+ SETFLOAT(ap+0, mesg->angle_rate[CWIID_PHI]);
+ SETFLOAT(ap+1, mesg->angle_rate[CWIID_THETA]);
+ SETFLOAT(ap+2, mesg->angle_rate[CWIID_PSI]);
+
+ outlet_anything(x->outlet_data, gensym("motionplus"), 3, ap);
+}
+
+
// The CWiid library invokes a callback function whenever events are
// generated by the wiiremote. This function is specified when connecting
// to the wiiremote (in the cwiid_open function).
@@ -286,7 +287,7 @@ void cwiid_nunchuk(t_wiiremote *x, struct cwiid_nunchuk_mesg *mesg)
/*void cwiid_callback(cwiid_wiiremote_t *wiimt, int mesg_count, union cwiid_mesg *mesg[], struct timespec *timestamp)
*/
-void cwiid_callback(cwiid_wiimote_t *wiiremote, int mesg_count,
+static void cwiid_callback(cwiid_wiimote_t *wiiremote, int mesg_count,
union cwiid_mesg mesg_array[], struct timespec *timestamp)
{
unsigned char buf[7];
@@ -310,7 +311,7 @@ void cwiid_callback(cwiid_wiimote_t *wiiremote, int mesg_count,
post("Battery: %d%", (int) (100.0 * mesg_array[i].status_mesg.battery / CWIID_BATTERY_MAX));
switch (mesg_array[i].status_mesg.ext_type) {
case CWIID_EXT_NONE:
- post("No nunchuck attached");
+ post("No extension attached");
break;
case CWIID_EXT_NUNCHUK:
post("Nunchuck extension attached");
@@ -333,24 +334,40 @@ void cwiid_callback(cwiid_wiimote_t *wiiremote, int mesg_count,
case CWIID_EXT_UNKNOWN:
post("Unknown extension attached");
break;
+ default:
+ post("ext mesg %d unknown", (mesg_array[i].type));
+ break;
}
break;
case CWIID_MESG_BTN:
- cwiid_btn(x, &mesg_array[i].btn_mesg);
+ wiiremote_cwiid_btn(x, &mesg_array[i].btn_mesg);
break;
case CWIID_MESG_ACC:
- cwiid_acc(x, &mesg_array[i].acc_mesg);
+ wiiremote_cwiid_acc(x, &mesg_array[i].acc_mesg);
break;
case CWIID_MESG_IR:
- cwiid_ir(x, &mesg_array[i].ir_mesg);
+ wiiremote_cwiid_ir(x, &mesg_array[i].ir_mesg);
break;
case CWIID_MESG_NUNCHUK:
- cwiid_nunchuk(x, &mesg_array[i].nunchuk_mesg);
+ wiiremote_cwiid_nunchuk(x, &mesg_array[i].nunchuk_mesg);
break;
+#ifdef CWIID_FLAG_CLASSIC
case CWIID_MESG_CLASSIC:
// todo
break;
+#endif
+#ifdef CWIID_FLAG_MOTIONPLUS
+ case CWIID_MESG_MOTIONPLUS:
+ wiiremote_cwiid_motionplus(x, &mesg_array[i].motionplus_mesg);
+ break;
+#endif
+#ifdef CWIID_MESG_BALANCE
+ case CWIID_MESG_BALANCE:
+ wiiremote_cwiid_balance(x, &mesg_array[i].balance_mesg);
+ break;
+#endif
default:
+ post("mesg %d unknown", (mesg_array[i].type));
break;
}
}
@@ -358,46 +375,53 @@ void cwiid_callback(cwiid_wiimote_t *wiiremote, int mesg_count,
// ==============================================================
+static void wiiremote_resetReportMode(t_wiiremote *x)
+{
+ if (x->connected) {
+ verbose(1, "changing report mode for Wii%02d to %d", x->wiiremoteID, x->reportMode);
+ if (cwiid_command(x->wiiremote, CWIID_CMD_RPT_MODE, x->reportMode)) {
+ post("wiiremote error: problem setting report mode.");
+ }
+ }
+}
-void cwiid_setReportMode(t_wiiremote *x, t_floatarg r)
+static void wiiremote_setReportMode(t_wiiremote *x, t_floatarg r)
{
- unsigned char rpt_mode;
-
- if (r >= 0) rpt_mode = (unsigned char) r;
- else {
- rpt_mode = CWIID_RPT_STATUS | CWIID_RPT_BTN;
- if (x->toggle_ir) rpt_mode |= CWIID_RPT_IR;
- if (x->toggle_acc) rpt_mode |= CWIID_RPT_ACC;
- if (x->toggle_nc) rpt_mode |= CWIID_RPT_EXT;
+ if (r >= 0) {
+ x->reportMode = (int) r;
+ wiiremote_resetReportMode(x);
+ } else {
+ return;
}
- if (x->connected)
- {
- verbose(1, "changing report mode for Wii%02d to %d", x->wiiremoteID, rpt_mode);
- if (cwiid_command(x->wiiremote, CWIID_CMD_RPT_MODE, rpt_mode)) {
- post("wiiremote error: problem setting report mode.");
- }
+}
+
+
+static void wiiremote_report(t_wiiremote*x, int flag, int onoff)
+{
+ if(onoff) {
+ x->reportMode |= flag;
+ } else {
+ x->reportMode &= ~flag;
}
+ wiiremote_resetReportMode(x);
}
-void cwiid_reportAcceleration(t_wiiremote *x, t_floatarg f)
+static void wiiremote_reportAcceleration(t_wiiremote *x, t_floatarg f)
{
- x->toggle_acc = f;
- cwiid_setReportMode(x, -1);
+ wiiremote_report(x, CWIID_RPT_ACC, f);
}
-void cwiid_reportIR(t_wiiremote *x, t_floatarg f)
+static void wiiremote_reportIR(t_wiiremote *x, t_floatarg f)
{
- x->toggle_ir = f;
- cwiid_setReportMode(x, -1);
+ wiiremote_report(x, CWIID_RPT_IR, f);
}
-void cwiid_reportNunchuck(t_wiiremote *x, t_floatarg f)
+static void wiiremote_reportNunchuck(t_wiiremote *x, t_floatarg f)
{
- x->toggle_nc = f;
- cwiid_setReportMode(x, -1);
+ wiiremote_report(x, CWIID_RPT_EXT, f);
}
-void cwiid_setRumble(t_wiiremote *x, t_floatarg f)
+static void wiiremote_setRumble(t_wiiremote *x, t_floatarg f)
{
if (x->connected)
{
@@ -405,7 +429,7 @@ void cwiid_setRumble(t_wiiremote *x, t_floatarg f)
}
}
-void cwiid_setLED(t_wiiremote *x, t_floatarg f)
+static void wiiremote_setLED(t_wiiremote *x, t_floatarg f)
{
// some possible values:
// CWIID_LED0_ON 0x01
@@ -429,11 +453,12 @@ void cwiid_setLED(t_wiiremote *x, t_floatarg f)
// in a console:
// hcitool scan | grep Nintendo
-void cwiid_doConnect(t_wiiremote *x, t_symbol *addr, t_symbol *dongaddr)
+static void wiiremote_doConnect(t_wiiremote *x, t_symbol *addr, t_symbol *dongaddr)
{
unsigned char buf[7];
int i;
bdaddr_t bdaddr;
+ unsigned int flags = CWIID_FLAG_MESG_IFC;
bdaddr_t dong_bdaddr;
bdaddr_t* dong_bdaddr_ptr=&dong_bdaddr;
@@ -458,13 +483,17 @@ void cwiid_doConnect(t_wiiremote *x, t_symbol *addr, t_symbol *dongaddr)
str2ba(dongaddr->s_name, &dong_bdaddr);
}
// connect:
+
+#ifdef CWIID_FLAG_MOTIONPLUS
+ flags |= CWIID_FLAG_MOTIONPLUS;
+#endif
#if 0
- x->wiiremote = cwiid_open(&bdaddr, dong_bdaddr_ptr, CWIID_FLAG_MESG_IFC);
+ x->wiiremote = cwiid_open(&bdaddr, dong_bdaddr_ptr, flags);
#else
#warning multi-dongle support...
- x->wiiremote = cwiid_open(&bdaddr, CWIID_FLAG_MESG_IFC);
+ x->wiiremote = cwiid_open(&bdaddr, flags);
#endif
if(NULL==x->wiiremote) {
@@ -494,7 +523,10 @@ void cwiid_doConnect(t_wiiremote *x, t_symbol *addr, t_symbol *dongaddr)
}
x->connected = 1;
- cwiid_setReportMode(x,-1);
+
+ x->reportMode |= CWIID_RPT_STATUS;
+ x->reportMode |= CWIID_RPT_BTN;
+ wiiremote_resetReportMode(x);
if (cwiid_set_mesg_callback(x->wiiremote, &cwiid_callback)) {
pd_error(x, "Unable to set message callback");
@@ -507,18 +539,18 @@ void cwiid_doConnect(t_wiiremote *x, t_symbol *addr, t_symbol *dongaddr)
// cover, or by pressing buttons 1 and 2 simultaneously.
// TODO: Without pressing the buttons, I get a segmentation error. So far, I don't know why.
-void cwiid_discover(t_wiiremote *x)
+static void wiiremote_discover(t_wiiremote *x)
{
post("Put the wiiremote into discover mode by pressing buttons 1 and 2 simultaneously.");
- cwiid_doConnect(x, NULL, gensym("NULL"));
+ wiiremote_doConnect(x, NULL, gensym("NULL"));
if (!(x->connected))
{
post("Error: could not find any wiiremotes. Please ensure that bluetooth is enabled, and that the 'hcitool scan' command lists your Nintendo device.");
}
}
-void cwiid_doDisconnect(t_wiiremote *x)
+static void wiiremote_doDisconnect(t_wiiremote *x)
{
if (x->connected)
@@ -540,19 +572,15 @@ void cwiid_doDisconnect(t_wiiremote *x)
// ==============================================================
// ==============================================================
-static void *cwiid_new(t_symbol* s, int argc, t_atom *argv)
+static void *wiiremote_new(t_symbol* s, int argc, t_atom *argv)
{
bdaddr_t bdaddr; // wiiremote bdaddr
- t_wiiremote *x = (t_wiiremote *)pd_new(cwiid_class);
+ t_wiiremote *x = (t_wiiremote *)pd_new(wiiremote_class);
// create outlets:
x->outlet_data = outlet_new(&x->x_obj, NULL);
// initialize toggles:
- x->toggle_acc = 0;
- x->toggle_ir = 0;
- x->toggle_nc = 0;
-
x->connected = 0;
x->wiiremoteID = -1;
@@ -563,7 +591,7 @@ static void *cwiid_new(t_symbol* s, int argc, t_atom *argv)
post("conecting to provided address...");
if (argv->a_type == A_SYMBOL)
{
- cwiid_doConnect(x, NULL, atom_getsymbol(argv));
+ wiiremote_doConnect(x, NULL, atom_getsymbol(argv));
} else {
error("[wiiremote] expects either no argument, or a bluetooth address as an argument. eg, 00:19:1D:70:CE:72");
return NULL;
@@ -573,26 +601,26 @@ static void *cwiid_new(t_symbol* s, int argc, t_atom *argv)
}
-static void cwiid_free(t_wiiremote* x)
+static void wiiremote_free(t_wiiremote* x)
{
- cwiid_doDisconnect(x);
+ wiiremote_doDisconnect(x);
}
void wiiremote_setup(void)
{
int i;
- cwiid_class = class_new(gensym("wiiremote"), (t_newmethod)cwiid_new, (t_method)cwiid_free, sizeof(t_wiiremote), CLASS_DEFAULT, A_GIMME, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_debug, gensym("debug"), 0);
- class_addmethod(cwiid_class, (t_method) cwiid_doConnect, gensym("connect"), A_SYMBOL, A_SYMBOL, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_doDisconnect, gensym("disconnect"), 0);
- class_addmethod(cwiid_class, (t_method) cwiid_discover, gensym("discover"), 0);
- class_addmethod(cwiid_class, (t_method) cwiid_setReportMode, gensym("setReportMode"), A_DEFFLOAT, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_reportAcceleration, gensym("reportAcceleration"), A_DEFFLOAT, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_reportNunchuck, gensym("reportNunchuck"), A_DEFFLOAT, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_reportIR, gensym("reportIR"), A_DEFFLOAT, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_setRumble, gensym("setRumble"), A_DEFFLOAT, 0);
- class_addmethod(cwiid_class, (t_method) cwiid_setLED, gensym("setLED"), A_DEFFLOAT, 0);
+ wiiremote_class = class_new(gensym("wiiremote"), (t_newmethod)wiiremote_new, (t_method)wiiremote_free, sizeof(t_wiiremote), CLASS_DEFAULT, A_GIMME, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_debug, gensym("debug"), 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_doConnect, gensym("connect"), A_SYMBOL, A_SYMBOL, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_doDisconnect, gensym("disconnect"), 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_discover, gensym("discover"), 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_setReportMode, gensym("setReportMode"), A_DEFFLOAT, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_reportAcceleration, gensym("reportAcceleration"), A_DEFFLOAT, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_reportNunchuck, gensym("reportNunchuck"), A_DEFFLOAT, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_reportIR, gensym("reportIR"), A_DEFFLOAT, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_setRumble, gensym("setRumble"), A_DEFFLOAT, 0);
+ class_addmethod(wiiremote_class, (t_method) wiiremote_setLED, gensym("setLED"), A_DEFFLOAT, 0);
}