From 82068e5edf2a0ede8ba19a480d749dff73374614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Fri, 30 Oct 2009 18:03:58 +0000 Subject: fixed some crasher bugs svn path=/trunk/externals/hardware/wiimote/; revision=12701 --- wiimote.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 127 insertions(+), 37 deletions(-) diff --git a/wiimote.c b/wiimote.c index 6044dfa..9317acd 100644 --- a/wiimote.c +++ b/wiimote.c @@ -56,6 +56,7 @@ typedef struct _wiimote // outlets: t_outlet *outlet_data; + t_outlet *outlet_status; struct timespec*basetime; double baselogicaltime; @@ -217,9 +218,14 @@ static void addWiimsg(union cwiid_mesg mesg, double timestamp) +// ============================================================== +/* forward declarations */ +static void wiimote_doDisconnect(t_wiimote *x); + // ============================================================== + static void wiimote_debug(t_wiimote *x) { post("\n======================"); @@ -241,6 +247,15 @@ static void wiimote_debug(t_wiimote *x) } // ============================================================== +static void wiimote_out_status(t_wiimote *x, int state) +{ + t_atom ap[1]; + + SETFLOAT(ap+0, state); + + outlet_anything(x->outlet_status, gensym("open"), 1, ap); +} + static void wiimote_cwiid_battery(t_wiimote *x, int battery) { @@ -454,7 +469,23 @@ static void wiimote_cwiid_motionplus(t_wiimote *x, struct cwiid_motionplus_mesg } #endif - +static void wiimote_cwiid_error(t_wiimote *x, struct cwiid_error_mesg *mesg) { + switch(mesg->error) { + case CWIID_ERROR_NONE: + pd_error(x, "no error"); + break; + case CWIID_ERROR_DISCONNECT: + pd_error(x, "disconnect error"); + wiimote_doDisconnect(x); + break; + case CWIID_ERROR_COMM: + pd_error(x, "comm error"); + wiimote_doDisconnect(x); + break; + default: + pd_error(x, "unknown error %d", mesg->error); + } +} static void wiimote_cwiid_message(t_wiimote *x, union cwiid_mesg*mesg) { switch (mesg->type) { @@ -502,7 +533,7 @@ static void wiimote_cwiid_message(t_wiimote *x, union cwiid_mesg*mesg) { post("Unknown extension attached"); break; default: - post("ext mesg %d unknown", mesg->status_mesg.ext_type); + post("ext mesg %d/%d unknown", mesg->type, mesg->status_mesg.ext_type); break; } break; @@ -536,6 +567,8 @@ static void wiimote_cwiid_message(t_wiimote *x, union cwiid_mesg*mesg) { wiimote_cwiid_balance(x, &mesg->balance_mesg); break; #endif + case CWIID_MESG_ERROR: + wiimote_cwiid_error(x, &mesg->error_mesg); default: post("mesg %d unknown", (mesg->type)); break; @@ -636,6 +669,8 @@ static void wiimote_dequeue(void*nada) t_wiimoteMsgList*wl=g_wiimoteMsgList; t_wiimoteMsgList*next=NULL; + nada=NULL; /* ignore */ + if(NULL==wl) { /* no messages to dequeue */ return; @@ -659,7 +694,7 @@ static void wiimote_dequeue(void*nada) static void wiimote_queue(t_wiimote*x, union cwiid_mesg*mesg, double timestamp) { /* add mesg to the queue with a Pd timestamp */ - t_wiimoteMsgList*wl=g_wiimoteMsgList; + // t_wiimoteMsgList*wl=g_wiimoteMsgList; /* insert the current message into the list */ t_wiimoteMsgList*newentry=(t_wiimoteMsgList*)getbytes(sizeof(t_wiimoteMsgList)); @@ -676,6 +711,32 @@ static void wiimote_queue(t_wiimote*x, union cwiid_mesg*mesg, double timestamp) } #endif + + +static void cwiid_error_callback(cwiid_wiimote_t *wiimote, const char*err, va_list ap) { + t_wiimote *x=NULL; + if(g_wiimoteList==NULL||wiimote==NULL) { + post("no wii's known"); + return; + } + x=getWiimoteObject(cwiid_get_id(wiimote)); + + if(NULL==x) { + if(err) { + error("wiimote: %s", err); + } else { + error("wiimote: unknown error"); + } + } else { + if(err) { + pd_error(x, "wiimote: %s", err); + } else { + pd_error(x, "wiimote: unknown error"); + } + } + +} + // The CWiid library invokes a callback function whenever events are // generated by the wiimote. This function is specified when connecting // to the wiimote (in the cwiid_open function). @@ -734,7 +795,7 @@ static void wiimote_resetReportMode(t_wiimote *x) if (x->connected) { verbose(1, "changing report mode for Wii%02d to %d", x->wiimoteID, x->reportMode); if (cwiid_command(x->wiimote, CWIID_CMD_RPT_MODE, x->reportMode)) { - post("wiimote error: problem setting report mode."); + pd_error(x, "wiimote: could not set report mode."); } } } @@ -776,14 +837,16 @@ static void wiimote_report(t_wiimote*x, t_symbol*s, int onoff) } if(CWIID_RPT_MOTIONPLUS==flag) { - int err=0; - if(onoff) { - err=cwiid_enable(x->wiimote, CWIID_FLAG_MOTIONPLUS); - } else { - err=cwiid_disable(x->wiimote, CWIID_FLAG_MOTIONPLUS); - } - if(err) { - pd_error(x, "turning %s motionplus returned %d", (flag?"on":"off"), err); + if(x->connected) { + int err=0; + if(onoff) { + err=cwiid_enable(x->wiimote, CWIID_FLAG_MOTIONPLUS); + } else { + err=cwiid_disable(x->wiimote, CWIID_FLAG_MOTIONPLUS); + } + if(err) { + pd_error(x, "turning %s motionplus returned %d", (flag?"on":"off"), err); + } } } @@ -821,7 +884,9 @@ static void wiimote_setRumble(t_wiimote *x, t_floatarg f) { if (x->connected) { - if (cwiid_command(x->wiimote, CWIID_CMD_RUMBLE, f)) post("wiimote error: problem setting rumble."); + if (cwiid_command(x->wiimote, CWIID_CMD_RUMBLE, f)) { + pd_error(x, "wiimote: could not set rumble"); + } } } @@ -834,7 +899,9 @@ static void wiimote_setLED(t_wiimote *x, t_floatarg f) // CWIID_LED3_ON 0x08 if (x->connected) { - if (cwiid_command(x->wiimote, CWIID_CMD_LED, f)) post("wiimote error: problem setting LED."); + if (cwiid_command(x->wiimote, CWIID_CMD_LED, f)) { + pd_error(x, "wiimote: could not set LED."); + } } } @@ -842,13 +909,11 @@ static void wiimote_setLED(t_wiimote *x, t_floatarg f) // ============================================================== - // The following function attempts to connect to a wiimote at a // specific address, provided as an argument. eg, 00:19:1D:70:CE:72 // This address can be discovered by running the following command // in a console: // hcitool scan | grep Nintendo - static void wiimote_doConnect(t_wiimote *x, t_symbol *addr, t_symbol *dongaddr) { bdaddr_t bdaddr; @@ -857,42 +922,48 @@ static void wiimote_doConnect(t_wiimote *x, t_symbol *addr, t_symbol *dongaddr) bdaddr_t dong_bdaddr; bdaddr_t* dong_bdaddr_ptr=&dong_bdaddr; + if(x->connected) { + wiimote_doDisconnect(x); + } + // determine address: if (NULL==addr || addr==gensym("")) { - post("Searching automatically..."); - bdaddr = *BDADDR_ANY; + verbose(1, "searching for wii..."); + bdaddr = *BDADDR_ANY; } else { - str2ba(addr->s_name, &bdaddr); - post("Connecting to given address..."); - post("Press buttons 1 and 2 simultaneously."); - } + str2ba(addr->s_name, &bdaddr); + verbose(1, "Connecting to Wii '%s'", addr->s_name); + } + post("Press buttons 1 and 2 simultaneously."); // determine dongleaddress: if (NULL==dongaddr || dongaddr==gensym("")) { - post("Binding automatically..."); - dong_bdaddr_ptr = NULL; + verbose(1, "using default dongle"); + dong_bdaddr_ptr = NULL; } else { - str2ba(dongaddr->s_name, &dong_bdaddr); + verbose(1, "using dongle '%s'", dongaddr->s_name); + str2ba(dongaddr->s_name, &dong_bdaddr); } // connect: #ifdef CWIID_OPEN_WITH_DONGLE - verbose(1,"wiimote: opening with dongle '%s'", dongaddr->s_name); - x->wiimote = cwiid_open(&bdaddr, dong_bdaddr_ptr, flags); + verbose(1,"wiimote: opening multidongle"); + x->wiimote = cwiid_open(&bdaddr, dong_bdaddr_ptr, flags); #else -# warning multi-dongle support missing... - x->wiimote = cwiid_open(&bdaddr, flags); + verbose(1,"wiimote: opening"); + x->wiimote = cwiid_open(&bdaddr, flags); #endif if(NULL==x->wiimote) { - post("wiimote error: unable to connect"); + pd_error(x, "wiimote: unable to connect"); return; } if(!addWiimoteObject(x, cwiid_get_id(x->wiimote))) { cwiid_close(x->wiimote); x->wiimote=NULL; + wiimote_out_status(x, x->connected); return; } @@ -913,6 +984,7 @@ static void wiimote_doConnect(t_wiimote *x, t_symbol *addr, t_symbol *dongaddr) } x->connected = 1; + wiimote_out_status(x, x->connected); x->reportMode |= CWIID_RPT_STATUS; x->reportMode |= CWIID_RPT_BTN; @@ -938,7 +1010,7 @@ static void wiimote_discover(t_wiimote *x) wiimote_doConnect(x, NULL, NULL); if (!(x->connected)) { - post("Error: could not find any wiimotes. Please ensure that bluetooth is enabled, and that the 'hcitool scan' command lists your Nintendo device."); + pd_error(x, "could not find any wiimotes. Please ensure that bluetooth is enabled, and that the 'hcitool scan' command lists your Nintendo device."); } } @@ -948,18 +1020,26 @@ static void wiimote_doDisconnect(t_wiimote *x) if (x->connected) { if (cwiid_close(x->wiimote)) { - post("wiimote error: problems when disconnecting."); + pd_error(x, "wiimote: unable to close connection."); } else { - post("disconnect successfull, resetting values"); - removeWiimoteObject(x); - x->connected = 0; + post("disconnect successfull, resetting values"); + removeWiimoteObject(x); + x->connected = 0; } + } else { + post("device is not connected"); } - else post("device is not connected"); + + wiimote_out_status(x, x->connected); } +static void wiimote_bang(t_wiimote *x) +{ + wiimote_out_status(x, x->connected); +} + // ============================================================== // ============================================================== @@ -969,6 +1049,7 @@ static void *wiimote_new(t_symbol*s, int argc, t_atom *argv) // create outlets: x->outlet_data = outlet_new(&x->x_obj, NULL); + x->outlet_status = outlet_new(&x->x_obj, NULL); // initialize toggles: x->connected = 0; @@ -1000,12 +1081,20 @@ static void wiimote_free(t_wiimote* x) if(x->basetime) { freebytes(x->basetime, sizeof(struct timespec)); } + + if(x->outlet_data)outlet_free(x->outlet_data); x->outlet_data=NULL; + if(x->outlet_status)outlet_free(x->outlet_status); x->outlet_status=NULL; } void wiimote_setup(void) { g_clock = clock_new(NULL, (t_method)wiimote_dequeue); + if (cwiid_set_err(&cwiid_error_callback)) { + error("wiimote: unable to set error callback"); + } + + wiimote_class = class_new(gensym("wiimote"), (t_newmethod)wiimote_new, (t_method)wiimote_free, sizeof(t_wiimote), CLASS_DEFAULT, A_GIMME, 0); class_addmethod(wiimote_class, (t_method) wiimote_debug, gensym("debug"), 0); @@ -1019,6 +1108,8 @@ void wiimote_setup(void) /* query data */ + class_addbang(wiimote_class, (t_method) wiimote_bang); + class_addmethod(wiimote_class, (t_method) wiimote_report, gensym("report"), A_SYMBOL, A_FLOAT, 0); class_addmethod(wiimote_class, (t_method) wiimote_setReportMode, gensym("setReportMode"), A_FLOAT, 0); @@ -1034,4 +1125,3 @@ void wiimote_setup(void) class_addmethod(wiimote_class, (t_method) wiimote_setRumble, gensym("setRumble"), A_FLOAT, 0); class_addmethod(wiimote_class, (t_method) wiimote_setLED, gensym("setLED"), A_FLOAT, 0); } - -- cgit v1.2.1