From 19cc31e3fd6942030173981be17ed88ef860ef88 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 28 Dec 2006 22:57:22 +0000 Subject: ported b3 from Masayuki Akamatsu, looks complete now svn path=/trunk/externals/io/; revision=7091 --- wiiremote/Makefile | 7 ++- wiiremote/README.txt | 6 ++ wiiremote/aka.wiiremote.c | 148 +++++++++++++++++++++------------------------- wiiremote/wiiremote.c | 78 ++++++++++++++---------- wiiremote/wiiremote.h | 3 +- 5 files changed, 128 insertions(+), 114 deletions(-) create mode 100644 wiiremote/README.txt (limited to 'wiiremote') diff --git a/wiiremote/Makefile b/wiiremote/Makefile index 78d1860..e222c9b 100644 --- a/wiiremote/Makefile +++ b/wiiremote/Makefile @@ -15,14 +15,15 @@ test_locations: # for emacs etags: - etags ../../../pd/src/*.h *.[ch] linux/input.h + etags ../../../pd/src/*.h *.[ch] make etags_`uname -s` etags_Darwin: - etags -a HID\ Utilities\ Source/*.[ch] \ + etags -a \ /System/Library/Frameworks/ForceFeedback.framework/Headers/*.h \ + /System/Library/Frameworks/CoreFoundation.framework/Headers/*.h \ /System/Library/Frameworks/Carbon.framework/Headers/*.h \ - /System/Library/Frameworks/IOKit.framework/Headers/hid*/*.[ch] + /System/Library/Frameworks/IOBluetooth.framework/Headers/*.[ch] etags_Linux: etags -a /usr/include/*.h linux/input.h /usr/include/sys/*.h diff --git a/wiiremote/README.txt b/wiiremote/README.txt new file mode 100644 index 0000000..bdaf778 --- /dev/null +++ b/wiiremote/README.txt @@ -0,0 +1,6 @@ + +This is a port of the Max class aka.wiiremote by Masayuki Akamatsu. Its +available here: + +http://www.iamas.ac.jp/~aka/max/#aka_wiiremote + diff --git a/wiiremote/aka.wiiremote.c b/wiiremote/aka.wiiremote.c index 89e6248..3c09341 100644 --- a/wiiremote/aka.wiiremote.c +++ b/wiiremote/aka.wiiremote.c @@ -1,7 +1,8 @@ // aka.wiiremote.c // Copyright by Masayuki Akamatsu -// port to Pd by Hans-Christoph Steiner - +// 1.0B1 : 2006.12.12 +// 1.0B2 : 2006.12.15 +// 1.0B3 : 2006.12.20 #ifdef PD #include "m_pd.h" @@ -9,13 +10,15 @@ static t_class *wiiremote_class; #else /* Max */ #include "ext.h" -#endif +#endif /* PD */ + #include "wiiremote.h" +#include + #define kInterval 100 #define kMaxTrial 100 - typedef struct _akawiiremote { #ifdef PD @@ -29,7 +32,7 @@ typedef struct _akawiiremote void *clock; long interval; long trial; - + void *statusOut; void *buttonsOut; void *irOut; @@ -59,7 +62,32 @@ void akawiiremote_free(t_akawiiremote *x); #ifdef PD void wiiremote_setup() +#else /* Max */ +void main() +#endif /* PD */ { + NumVersion outSoftwareVersion; + BluetoothHCIVersionInfo outHardwareVersion; + + if (IOBluetoothGetVersion(&outSoftwareVersion, &outHardwareVersion)==kIOReturnSuccess) + { + if (outSoftwareVersion.majorRev < 1 || outSoftwareVersion.minorAndBugRev < 0x63) + { + error("requires Blutooth version 1.6.3 or later."); + return; + } + } + else + { + error("can't get Bluetooth version."); + return; + } + + post("aka.wiiremote 1.0B3-UB by Masayuki Akamatsu"); + +#ifdef PD + post("\tPd port by Hans-Christoph Steiner"); + wiiremote_class = class_new(gensym("wiiremote"), (t_newmethod)akawiiremote_new, (t_method)akawiiremote_free, @@ -80,15 +108,7 @@ void wiiremote_setup() class_addmethod(wiiremote_class,(t_method)akawiiremote_getledstatus,gensym("getledstatus"),0); class_addmethod(wiiremote_class,(t_method)akawiiremote_assist,gensym("assist"),A_CANT,0); - - post("aka.wiiremote 1.0B2-UB by Masayuki Akamatsu"); - post("\tPd port by Hans-Christoph Steiner"); - - akawiiremote_count = 0; -} #else /* Max */ -void main() -{ setup((t_messlist **)&akawiiremote_class, (method)akawiiremote_new, (method)akawiiremote_free, (short)sizeof(t_akawiiremote), 0L, A_GIMME, 0); addbang((method)akawiiremote_bang); @@ -104,46 +124,25 @@ void main() addmess((method)akawiiremote_getledstatus,"getledstatus",0); addmess((method)akawiiremote_assist,"assist",A_CANT,0); - - post("aka.wiiremote 1.0B2-UB by Masayuki Akamatsu"); +#endif /* PD */ akawiiremote_count = 0; } -#endif /* PD */ + //-------------------------------------------------------------------------------------------- void akawiiremote_bang(t_akawiiremote *x) { t_atom list[4]; - - if (x->wiiremote->device == nil) - { - post("warning: your WiiRemote is not connected"); + + if (x->wiiremote->device == nil) return; // do nothing - } - + #ifdef PD outlet_float(x->buttonsOut, (t_float) x->wiiremote->buttonData); - - if (x->wiiremote->isIRSensorEnabled) - { - SETFLOAT(list, x->wiiremote->posX); - SETFLOAT(list + 1, x->wiiremote->posY); - SETFLOAT(list + 2, x->wiiremote->angle); - SETFLOAT (list + 3, x->wiiremote->tracking); - outlet_list(x->irOut, &s_list, 4, list); - } - - if (x->wiiremote->isMotionSensorEnabled) - { - SETFLOAT(list, x->wiiremote->accX); - SETFLOAT(list + 1, x->wiiremote->accY); - SETFLOAT(list + 2, x->wiiremote->accZ); - SETFLOAT(list + 3, x->wiiremote->orientation); - outlet_list(x->accOut, &s_list, 4, list); - } #else /* Max */ outlet_int(x->buttonsOut, x->wiiremote->buttonData); +#endif /* PD */ if (x->wiiremote->isIRSensorEnabled) { @@ -151,7 +150,7 @@ void akawiiremote_bang(t_akawiiremote *x) SETFLOAT(list + 1, x->wiiremote->posY); SETFLOAT(list + 2, x->wiiremote->angle); SETLONG (list + 3, x->wiiremote->tracking); - outlet_list(x->irOut, 0L, 4, &list); + outlet_list(x->irOut, 0L, 4, list); } if (x->wiiremote->isMotionSensorEnabled) @@ -160,35 +159,35 @@ void akawiiremote_bang(t_akawiiremote *x) SETLONG(list + 1, x->wiiremote->accY); SETLONG(list + 2, x->wiiremote->accZ); SETLONG(list + 3, x->wiiremote->orientation); - outlet_list(x->accOut, 0L, 4, &list); + outlet_list(x->accOut, 0L, 4, list); } -#endif /* PD */ - wiiremote_getstatus(); + //wiiremote_getstatus(); // stopped in B3 } void akawiiremote_connect(t_akawiiremote *x) { - if (x->wiiremote->device == nil) // if not connected - { - if (x->wiiremote->inquiry == nil) // if not seatching - { - Boolean result; + t_atom status; + Boolean result; - result = wiiremote_search(); // start searching the device - x->trial = 0; - clock_delay(x->clock, 0); // start clock to check the device found - } + if (wiiremote_isconnected()) + { + SETLONG(&status, -1); + outlet_anything(x->statusOut, gensym("connect"), 1, &status); } - else // if already connected + else { - t_atom status; - - SETLONG(&status, 1); - outlet_anything(x->statusOut, gensym("connect"), 1, &status); + result = wiiremote_search(); // start searching the device + x->trial = 0; + clock_unset(x->clock); // stop clock + clock_delay(x->clock, 0); // start clock to check the device found } } +void akawiiremote_foundFunc(t_akawiiremote *x) +{ +} + void akawiiremote_disconnect(t_akawiiremote *x) { Boolean result; @@ -241,19 +240,11 @@ void akawiiremote_getledstatus(t_akawiiremote *x) { t_atom list[4]; -#ifdef PD - SETFLOAT(list, x->wiiremote->isLED1Illuminated); - SETFLOAT(list + 1, x->wiiremote->isLED2Illuminated); - SETFLOAT(list + 2, x->wiiremote->isLED3Illuminated); - SETFLOAT(list + 3, x->wiiremote->isLED4Illuminated); - outlet_anything(x->statusOut, gensym("ledstatus"), 4, list); -#else /* Max */ SETLONG(list, x->wiiremote->isLED1Illuminated); SETLONG(list + 1, x->wiiremote->isLED2Illuminated); SETLONG(list + 2, x->wiiremote->isLED3Illuminated); SETLONG(list + 3, x->wiiremote->isLED4Illuminated); - outlet_anything(x->statusOut, gensym("ledstatus"), 4, &list); -#endif + outlet_anything(x->statusOut, gensym("ledstatus"), 4, list); } //-------------------------------------------------------------------------------------------- @@ -263,16 +254,17 @@ void akawiiremote_clock(t_akawiiremote *x) Boolean result; t_atom status; - if (x->wiiremote->device != nil) // if the device is found... + if (wiiremote_isconnected()) // if the device is connected... { clock_unset(x->clock); // stop clock wiiremote_stopsearch(); - result = wiiremote_connect(); // connect to it - SETLONG(&status, result); + //result = wiiremote_connect(); // remove in B3 + wiiremote_getstatus(); // add in B3 + SETLONG(&status, 1); outlet_anything(x->statusOut, gensym("connect"), 1, &status); } - else // if the device is not found... + else // if the device is not connected... { x->trial++; //SETLONG(&status, x->trial); @@ -334,13 +326,13 @@ void *akawiiremote_new(t_symbol *s, short ac, t_atom *av) x->accOut = outlet_new(&x->x_obj, &s_list); #else /* Max */ t_akawiiremote *x; - + x = (t_akawiiremote *)newobject(akawiiremote_class); x->wiiremote = wiiremote_init(); x->clock = clock_new(x, (method)akawiiremote_clock); - + x->statusOut = outlet_new(x, 0); x->buttonsOut = intout(x); x->irOut = listout(x); @@ -348,7 +340,6 @@ void *akawiiremote_new(t_symbol *s, short ac, t_atom *av) #endif /* PD */ x->trial = 0; x->interval = kInterval; - akawiiremote_count++; return x; @@ -359,13 +350,12 @@ void akawiiremote_free(t_akawiiremote *x) akawiiremote_count--; if (akawiiremote_count == 0) wiiremote_disconnect(); - + + clock_unset(x->clock); #ifdef PD - if (x->clock) - clock_unset(x->clock); clock_free(x->clock); #else /* Max */ - freeobject(x->clock); -#endif + freeobject((t_object *)x->clock); +#endif /* PD */ } diff --git a/wiiremote/wiiremote.c b/wiiremote/wiiremote.c index 35acd03..b379f5e 100644 --- a/wiiremote/wiiremote.c +++ b/wiiremote/wiiremote.c @@ -3,7 +3,6 @@ // Based on "DarwiinRemote" by Hiroaki Kimura #include "wiiremote.h" - #include // this type is used a lot (data array): @@ -53,37 +52,47 @@ void checkDevice(IOBluetoothDeviceRef device) CFStringRef myString; myString = IOBluetoothDeviceGetName(device); - if (CFStringCompare(myString, CFSTR("Nintendo RVL-CNT-01"), 0) == kCFCompareEqualTo) + if (myString != nil) { - gWiiRemote.device = IOBluetoothObjectRetain(device); + if (CFStringCompare(myString, CFSTR("Nintendo RVL-CNT-01"), 0) == kCFCompareEqualTo) + { + gWiiRemote.device = IOBluetoothObjectRetain(device); + if ( !wiiremote_connect()) // add in B3 + wiiremote_disconnect(); // add in B3 + } } } -IOBluetoothDeviceInquiryDeviceFoundCallback myFoundFunc(void *refCon, IOBluetoothDeviceInquiryRef inquiry, IOBluetoothDeviceRef device) +void myFoundFunc(void *refCon, IOBluetoothDeviceInquiryRef inquiry, IOBluetoothDeviceRef device) { checkDevice(device); } -IOBluetoothDeviceInquiryDeviceNameUpdatedCallback myUpdatedFunc(void *refCon, IOBluetoothDeviceInquiryRef inquiry, IOBluetoothDeviceRef device, uint32_t devicesRemaining) +void myUpdatedFunc(void *refCon, IOBluetoothDeviceInquiryRef inquiry, IOBluetoothDeviceRef device, uint32_t devicesRemaining) { checkDevice(device); } -IOBluetoothDeviceInquiryCompleteCallback myCompleteFunc(void *refCon, IOBluetoothDeviceInquiryRef inquiry, IOReturn error, Boolean aborted) +void myCompleteFunc(void *refCon, IOBluetoothDeviceInquiryRef inquiry, IOReturn error, Boolean aborted) { - IOReturn result; - if (aborted) return; // called by stop ;) if (error != kIOReturnSuccess) { wiiremote_stopsearch(); - return; } } //-------------------------------------------------------------------------------------------- +Boolean wiiremote_isconnected(void) +{ + Boolean result; + + result = gWiiRemote.device != nil && IOBluetoothDeviceIsConnected(gWiiRemote.device); + return result; +} + Boolean wiiremote_search(void) { IOReturn ret; @@ -131,7 +140,7 @@ Boolean wiiremote_stopsearch(void) //-------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------- - IOBluetoothL2CAPChannelIncomingDataListener myDataListener(IOBluetoothL2CAPChannelRef channel, void *data, UInt16 length, void *refCon) + void myDataListener(IOBluetoothL2CAPChannelRef channel, void *data, UInt16 length, void *refCon) { unsigned char *dp = (unsigned char*)data; @@ -248,35 +257,33 @@ Boolean wiiremote_stopsearch(void) gWiiRemote.posY = oy; } -IOBluetoothL2CAPChannelIncomingEventListener myEventListener(IOBluetoothL2CAPChannelRef channel, void *refCon, IOBluetoothL2CAPChannelEvent *event) +void myEventListener(IOBluetoothL2CAPChannelRef channel, void *refCon, IOBluetoothL2CAPChannelEvent *event) { - switch (event->eventType) + if (event->eventType == kIOBluetoothL2CAPChannelEventTypeData) { - case kIOBluetoothL2CAPChannelEventTypeData: - // In thise case: - // event->u.newData.dataPtr is a pointer to the block of data received. - // event->u.newData.dataSize is the size of the block of data. - myDataListener(channel, event->u.data.dataPtr, event->u.data.dataSize, refCon); - break; - - case kIOBluetoothL2CAPChannelEventTypeClosed: - // In this case: - // event->u.terminatedChannel is the channel that was terminated. It can be converted in an IOBluetoothL2CAPChannel - // object with [IOBluetoothL2CAPChannel withL2CAPChannelRef:]. (see below). - break; + // In thise case: + // event->u.newData.dataPtr is a pointer to the block of data received. + // event->u.newData.dataSize is the size of the block of data. + myDataListener(channel, event->u.data.dataPtr, event->u.data.dataSize, refCon); + } + else + if (event->eventType == kIOBluetoothL2CAPChannelEventTypeClosed) + { + // In this case: + // event->u.terminatedChannel is the channel that was terminated. It can be converted in an IOBluetoothL2CAPChannel + // object with [IOBluetoothL2CAPChannel withL2CAPChannelRef:]. (see below). } } -IOBluetoothUserNotificationCallback myDisconnectedFunc(void * refCon, IOBluetoothUserNotificationRef inRef, IOBluetoothObjectRef objectRef) +void myDisconnectedFunc(void * refCon, IOBluetoothUserNotificationRef inRef, IOBluetoothObjectRef objectRef) { - wiiremote_disconnect(); + //wiiremote_disconnect(); } //-------------------------------------------------------------------------------------------- Boolean wiiremote_connect(void) { - IOReturn result; short i; if (gWiiRemote.device == nil) @@ -289,7 +296,8 @@ Boolean wiiremote_connect(void) break; usleep(10000); // wait 10ms } - if (i==kTrial) return false; + if (i==kTrial) + return false; gWiiRemote.disconnectNotification = IOBluetoothDeviceRegisterForDisconnectNotification(gWiiRemote.device, myDisconnectedFunc, 0); @@ -300,7 +308,8 @@ Boolean wiiremote_connect(void) break; usleep(10000); // wait 10ms } - if (i==kTrial) return false; + if (i==kTrial) + return false; // open L2CAPChannel : BluetoothL2CAPPSM = 17 for (i=0; i