aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2009-10-30 18:03:58 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2009-10-30 18:03:58 +0000
commit82068e5edf2a0ede8ba19a480d749dff73374614 (patch)
tree93944e5d6ba560f49f52949e49f9264d4a7fd0b6
parentf7f1917354ee605f2c355e8fb42f644af58e9d62 (diff)
fixed some crasher bugs
svn path=/trunk/externals/hardware/wiimote/; revision=12701
-rw-r--r--wiimote.c164
1 files 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);
}
-