implemented wiiuse_os_read for mac
This commit is contained in:
139
src/os_mac.m
139
src/os_mac.m
@@ -134,25 +134,46 @@ void wiiuse_os_disconnect(struct wiimote_t* wm) {
|
|||||||
#pragma mark poll, read, write
|
#pragma mark poll, read, write
|
||||||
|
|
||||||
int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) {
|
int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) {
|
||||||
int i;
|
int i, evnt = 0;
|
||||||
|
|
||||||
if (!wm) return 0;
|
if (!wm) return 0;
|
||||||
|
|
||||||
for (i = 0; i < wiimotes; ++i) {
|
for (i = 0; i < wiimotes; ++i) {
|
||||||
wm[i]->event = WIIUSE_NONE;
|
wm[i]->event = WIIUSE_NONE;
|
||||||
|
|
||||||
|
if (wiiuse_os_read(wm[i])) {
|
||||||
|
/* propagate the event, messages should be read as in linux, starting from the second element */
|
||||||
|
propagate_event(wm[i], wm[i]->event_buf[1], wm[i]->event_buf+2);
|
||||||
|
evnt += (wm[i]->event != WIIUSE_NONE);
|
||||||
|
|
||||||
|
/* clear out the event buffer */
|
||||||
|
memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf));
|
||||||
|
} else {
|
||||||
idle_cycle(wm[i]);
|
idle_cycle(wm[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return evnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wiiuse_os_read(struct wiimote_t* wm) {
|
int wiiuse_os_read(struct wiimote_t* wm) {
|
||||||
|
if(!wm || !wm->objc_wm || !WIIMOTE_IS_CONNECTED(wm)) {
|
||||||
|
WIIUSE_ERROR("Attempting to read from NULL or unconnected Wiimote");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm;
|
||||||
|
int result = [objc_wm read];
|
||||||
|
|
||||||
|
[pool drain];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len) {
|
int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len) {
|
||||||
if(!wm) {
|
if(!wm || !wm->objc_wm || !WIIMOTE_IS_CONNECTED(wm)) {
|
||||||
WIIUSE_ERROR("Attempting to write to NULL Wiimote");
|
WIIUSE_ERROR("Attempting to write to NULL or unconnected Wiimote");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,10 +218,15 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
wm = wm_;
|
wm = wm_;
|
||||||
|
|
||||||
device = device_;
|
device = device_;
|
||||||
controlChannel = nil;
|
controlChannel = nil;
|
||||||
interruptChannel = nil;
|
interruptChannel = nil;
|
||||||
|
|
||||||
disconnectNotification = nil;
|
disconnectNotification = nil;
|
||||||
|
|
||||||
|
receivedData = [[NSMutableArray alloc] initWithCapacity: 2];
|
||||||
|
receivedDataLock = [[NSLock alloc] init];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -214,7 +240,8 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
|
|||||||
|
|
||||||
[disconnectNotification unregister];
|
[disconnectNotification unregister];
|
||||||
[disconnectNotification release];
|
[disconnectNotification release];
|
||||||
disconnectNotification = nil;
|
|
||||||
|
[receivedData release];
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
@@ -286,6 +313,71 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
|
|||||||
|
|
||||||
#pragma mark read, write
|
#pragma mark read, write
|
||||||
|
|
||||||
|
- (int) checkForAvailableData {
|
||||||
|
unsigned int length = 0;
|
||||||
|
|
||||||
|
[receivedDataLock lock];
|
||||||
|
if([receivedData count]) {
|
||||||
|
// pop first item from queue
|
||||||
|
NSData* firstData = [receivedData objectAtIndex:0];
|
||||||
|
[receivedData removeObjectAtIndex:0];
|
||||||
|
|
||||||
|
byte* data = (byte*) [firstData bytes];
|
||||||
|
length = [firstData length];
|
||||||
|
|
||||||
|
// forward event data to C struct
|
||||||
|
memcpy(wm->event_buf, data, sizeof(wm->event_buf));
|
||||||
|
|
||||||
|
// clear local buffer
|
||||||
|
[firstData release];
|
||||||
|
}
|
||||||
|
[receivedDataLock unlock];
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) waitForInclomingData: (NSTimeInterval) duration {
|
||||||
|
NSDate* timeoutDate = [NSDate dateWithTimeIntervalSinceNow: duration];
|
||||||
|
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
|
||||||
|
while (true) {
|
||||||
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // This is used for fast release of NSDate, otherwise it leaks
|
||||||
|
|
||||||
|
if(![theRL runMode:NSDefaultRunLoopMode beforeDate:timeoutDate]) {
|
||||||
|
WIIUSE_ERROR("Could not start run loop while waiting for read [id %i].", wm->unid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[receivedDataLock lock];
|
||||||
|
NSUInteger count = [receivedData count];
|
||||||
|
[receivedDataLock unlock];
|
||||||
|
if(count) {
|
||||||
|
// received some data, stop waiting
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if([timeoutDate isLessThanOrEqualTo:[NSDate date]]) {
|
||||||
|
// timeout
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[pool drain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) read {
|
||||||
|
// is there already some data to read?
|
||||||
|
int result = [self checkForAvailableData];
|
||||||
|
if(!result) {
|
||||||
|
// wait a short amount of time, until data becomes available
|
||||||
|
[self waitForInclomingData:1];
|
||||||
|
|
||||||
|
// check again
|
||||||
|
result = [self checkForAvailableData];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
- (int) writeBuffer: (byte*) buffer length: (NSUInteger) length {
|
- (int) writeBuffer: (byte*) buffer length: (NSUInteger) length {
|
||||||
if(controlChannel == nil) {
|
if(controlChannel == nil) {
|
||||||
WIIUSE_ERROR("Attempted to write to nil control channel [id %i].", wm->unid);
|
WIIUSE_ERROR("Attempted to write to nil control channel [id %i].", wm->unid);
|
||||||
@@ -313,6 +405,43 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
|
|||||||
return (error == kIOReturnSuccess) ? length : 0;
|
return (error == kIOReturnSuccess) ? length : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark IOBluetoothL2CAPChannelDelegate
|
||||||
|
|
||||||
|
- (void) l2capChannelData:(IOBluetoothL2CAPChannel*)channel data:(void*)data_ length:(NSUInteger)length {
|
||||||
|
|
||||||
|
byte* data = (byte*) data_;
|
||||||
|
|
||||||
|
// This is done in case the output channel woke up this handler
|
||||||
|
if(!data || ([channel PSM] == WM_OUTPUT_CHANNEL)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// log the received data
|
||||||
|
#ifdef WITH_WIIUSE_DEBUG
|
||||||
|
{
|
||||||
|
printf("[DEBUG] (id %i) RECV: (%x) ", wm->unid, data[0]);
|
||||||
|
int x;
|
||||||
|
for (x = 1; x < length; ++x)
|
||||||
|
printf("%.2x ", data[x]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is called if we are receiving data before completing
|
||||||
|
* the handshaking, hence before calling wiiuse_poll
|
||||||
|
*/
|
||||||
|
if(WIIMOTE_IS_SET(wm, WIIMOTE_STATE_HANDSHAKE)) {
|
||||||
|
propagate_event(wm, data[1], data+2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the data into the buffer
|
||||||
|
[receivedDataLock lock];
|
||||||
|
[receivedData addObject: [[NSData alloc] initWithBytes:data length:length]];
|
||||||
|
[receivedDataLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|||||||
@@ -42,15 +42,6 @@
|
|||||||
#import "../wiiuse_internal.h"
|
#import "../wiiuse_internal.h"
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
|
|
||||||
#define WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE 1
|
|
||||||
#else
|
|
||||||
#define WIIUSE_MAC_OS_X_VERSION_10_7_OR_ABOVE 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@interface WiiuseWiimote : NSObject<IOBluetoothL2CAPChannelDelegate> {
|
@interface WiiuseWiimote : NSObject<IOBluetoothL2CAPChannelDelegate> {
|
||||||
wiimote* wm; // reference to the C wiimote struct
|
wiimote* wm; // reference to the C wiimote struct
|
||||||
|
|
||||||
@@ -59,6 +50,9 @@
|
|||||||
IOBluetoothL2CAPChannel* interruptChannel;
|
IOBluetoothL2CAPChannel* interruptChannel;
|
||||||
|
|
||||||
IOBluetoothUserNotification* disconnectNotification;
|
IOBluetoothUserNotification* disconnectNotification;
|
||||||
|
|
||||||
|
NSMutableArray* receivedData; // a queue os NSData*
|
||||||
|
NSLock* receivedDataLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithPtr: (wiimote*) wm device: (IOBluetoothDevice*) device;
|
- (id) initWithPtr: (wiimote*) wm device: (IOBluetoothDevice*) device;
|
||||||
@@ -66,6 +60,7 @@
|
|||||||
- (IOReturn) connect;
|
- (IOReturn) connect;
|
||||||
- (void) disconnect;
|
- (void) disconnect;
|
||||||
|
|
||||||
|
- (int) read;
|
||||||
- (int) writeBuffer: (byte*) buffer length: (NSUInteger) length;
|
- (int) writeBuffer: (byte*) buffer length: (NSUInteger) length;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user