/*
* wiiuse
*
* Written By:
* Michael Laforest < para >
* Email: < thepara (--AT--) g m a i l [--DOT--] com >
*
* Copyright 2006-2007
*
* This file is part of wiiuse.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* $Header$
*
*/
/**
* @file
* @brief C function interface to os_mac.
*/
#ifdef __APPLE__
#import "os_mac.h"
#import "../io.h"
#import "../events.h"
#import "../os.h"
#import
#import
#import
#import
#import
#pragma mark -
#pragma mark find
// See os_mac_find.m
#pragma mark -
#pragma mark connect, disconnect
/**
* @brief Connect to a wiimote with a known address.
*
* @param wm Pointer to a wiimote_t structure.
*
* @see wiimote_os_connect()
* @see wiimote_os_find()
*
* @return 1 on success, 0 on failure
*/
static short wiiuse_os_connect_single(struct wiimote_t* wm) {
// Skip if already connected or device not found
if(!wm) {
WIIUSE_ERROR("No Wiimote given.");
return 0;
} else if(wm && (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_DEV_FOUND) || wm->objc_wm == NULL)) {
WIIUSE_ERROR("Tried to connect Wiimote without an address.");
return 0;
} else if(WIIMOTE_IS_CONNECTED(wm)) {
WIIUSE_WARNING("Wiimote [id %i] is already connected.", wm->unid);
return 1;
}
WIIUSE_DEBUG("Connecting to Wiimote [id %i].", wm->unid);
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
short result = 0;
// connect
WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm;
if([objc_wm connect] == kIOReturnSuccess) {
WIIUSE_INFO("Connected to Wiimote [id %i].", wm->unid);
// save the connect structure to retrieve data later on
wm->objc_wm = (void*)objc_wm;
// save the connection status
WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
// Do the handshake
wiiuse_handshake(wm, NULL, 0);
wiiuse_set_report_type(wm);
result = 1;
}
[pool drain];
return result;
}
int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) {
int connected = 0;
int i;
for (i = 0; i < wiimotes; ++i) {
if(wm[i] == NULL) {
WIIUSE_ERROR("Trying to connect to non-initialized Wiimote.");
break;
}
if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND) || !wm[i]->objc_wm) {
// If the device is not found, skip it
continue;
}
if (wiiuse_os_connect_single(wm[i]))
++connected;
}
return connected;
}
void wiiuse_os_disconnect(struct wiimote_t* wm) {
if (!wm || !WIIMOTE_IS_CONNECTED(wm) || !wm->objc_wm)
return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[((WiiuseWiimote*)wm->objc_wm) disconnect];
[pool drain];
}
#pragma mark -
#pragma mark poll, read, write
int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) {
int i;
byte read_buffer[MAX_PAYLOAD];
int evnt = 0;
if (!wm) return 0;
for (i = 0; i < wiimotes; ++i) {
wm[i]->event = WIIUSE_NONE;
/* clear out the buffer */
memset(read_buffer, 0, sizeof(read_buffer));
/* read */
if (wiiuse_os_read(wm[i], read_buffer, sizeof(read_buffer))) {
/* propagate the event */
propagate_event(wm[i], read_buffer[0], read_buffer+1);
} else {
/* send out any waiting writes */
wiiuse_send_next_pending_write_request(wm[i]);
idle_cycle(wm[i]);
}
evnt += (wm[i]->event != WIIUSE_NONE);
}
return evnt;
}
int wiiuse_os_read(struct wiimote_t* wm, byte* buf, int len) {
if(!wm || !wm->objc_wm) return 0;
if(!WIIMOTE_IS_CONNECTED(wm)) {
WIIUSE_ERROR("Attempting to read from unconnected Wiimote");
return 0;
}
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm;
int result = [objc_wm readBuffer: buf length: len];
[pool drain];
return result;
}
int wiiuse_os_write(struct wiimote_t* wm, byte report_type, byte* buf, int len) {
if(!wm || !wm->objc_wm) return 0;
if(!WIIMOTE_IS_CONNECTED(wm)) {
WIIUSE_ERROR("Attempting to write to unconnected Wiimote");
return 0;
}
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm;
int result = [objc_wm writeReport: report_type buffer: buf length: (NSUInteger)len];
[pool drain];
return result;
}
#pragma mark -
#pragma mark platform fields
void wiiuse_init_platform_fields(struct wiimote_t* wm) {
wm->objc_wm = NULL;
}
void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) {
if(!wm) return;
WiiuseWiimote* objc_wm = (WiiuseWiimote*) wm->objc_wm;
// disconnect
// Note: this should already have happened, because this function
// is called once the device is disconnected. This is just paranoia.
[objc_wm disconnect];
// release WiiuseWiimote object
[objc_wm release];
wm->objc_wm = NULL;
}
#endif // __APPLE__