diff --git a/src/events.c b/src/events.c index 6378351..70d3404 100644 --- a/src/events.c +++ b/src/events.c @@ -44,20 +44,13 @@ #include "nunchuk.h" /* for nunchuk_disconnected, etc */ #include "wiiboard.h" /* for wii_board_disconnected, etc */ #include "motion_plus.h" /* for motion_plus_disconnected, etc */ -#include "io.h" /* for wiiuse_os_read, etc */ -#ifndef WIIUSE_WIN32 - #include /* for timeval */ - #include /* for select, fd_set */ - #include /* for read */ -#endif +#include "os.h" /* for wiiuse_os_poll */ -#include /* for errno */ #include /* for printf, perror */ #include /* for free, malloc */ #include /* for memcpy, memset */ -static void idle_cycle(struct wiimote_t* wm); static void clear_dirty_reads(struct wiimote_t* wm); static void event_data_read(struct wiimote_t* wm, byte* msg); static void event_data_write(struct wiimote_t *wm, byte *msg); @@ -80,130 +73,7 @@ static int state_changed(struct wiimote_t* wm); * the event variable will be set. */ int wiiuse_poll(struct wiimote_t** wm, int wiimotes) { - int evnt = 0; - - #ifdef WIIUSE_BLUEZ - /* - * *nix - */ - struct timeval tv; - fd_set fds; - int r; - int i; - int highest_fd = -1; - - if (!wm) return 0; - - /* block select() for 1/2000th of a second */ - tv.tv_sec = 0; - tv.tv_usec = 500; - - FD_ZERO(&fds); - - for (i = 0; i < wiimotes; ++i) { - /* only poll it if it is connected */ - if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) { - FD_SET(wm[i]->in_sock, &fds); - - /* find the highest fd of the connected wiimotes */ - if (wm[i]->in_sock > highest_fd) - highest_fd = wm[i]->in_sock; - } - - wm[i]->event = WIIUSE_NONE; - } - - if (highest_fd == -1) - /* nothing to poll */ - return 0; - - if (select(highest_fd + 1, &fds, NULL, NULL, &tv) == -1) { - WIIUSE_ERROR("Unable to select() the wiimote interrupt socket(s)."); - perror("Error Details"); - return 0; - } - - /* check each socket for an event */ - for (i = 0; i < wiimotes; ++i) { - /* if this wiimote is not connected, skip it */ - if (!WIIMOTE_IS_CONNECTED(wm[i])) - continue; - - if (FD_ISSET(wm[i]->in_sock, &fds)) { - /* clear out the event buffer */ - memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf)); - - /* clear out any old read requests */ - clear_dirty_reads(wm[i]); - - /* read the pending message into the buffer */ - r = read(wm[i]->in_sock, wm[i]->event_buf, sizeof(wm[i]->event_buf)); - if (r == -1) { - /* error reading data */ - WIIUSE_ERROR("Receiving wiimote data (id %i).", wm[i]->unid); - perror("Error Details"); - - if (errno == ENOTCONN) { - /* this can happen if the bluetooth dongle is disconnected */ - WIIUSE_ERROR("Bluetooth appears to be disconnected. Wiimote unid %i will be disconnected.", wm[i]->unid); - wiiuse_disconnect(wm[i]); - wiiuse_disconnected(wm[i]); - wm[i]->event = WIIUSE_UNEXPECTED_DISCONNECT; - } - - continue; - } - if (!r) { - /* remote disconnect */ - wiiuse_disconnected(wm[i]); - evnt = 1; - continue; - } - - /* propagate the event */ - propagate_event(wm[i], wm[i]->event_buf[1], wm[i]->event_buf+2); - evnt += (wm[i]->event != WIIUSE_NONE); - } else { - idle_cycle(wm[i]); - } - } - #elif defined(WIIUSE_WIN32) - /* - * Windows - */ - int i; - - if (!wm) return 0; - - for (i = 0; i < wiimotes; ++i) { - wm[i]->event = WIIUSE_NONE; - - if (wiiuse_os_read(wm[i])) { - /* propagate the event */ - propagate_event(wm[i], wm[i]->event_buf[0], wm[i]->event_buf+1); - 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]); - } - } - #elif defined(WIIUSE_MAC) - /* - * Mac - */ - int i; - - if (!wm) return 0; - - for (i = 0; i < wiimotes; ++i) { - wm[i]->event = WIIUSE_NONE; - idle_cycle(wm[i]); - } - #endif - - return evnt; + return wiiuse_os_poll(wm, wiimotes); } int wiiuse_update(struct wiimote_t** wiimotes, int nwiimotes, wiiuse_update_cb callback) { @@ -244,7 +114,7 @@ int wiiuse_update(struct wiimote_t** wiimotes, int nwiimotes, wiiuse_update_cb c * * @param wm Pointer to a wiimote_t structure. */ -static void idle_cycle(struct wiimote_t* wm) { +void idle_cycle(struct wiimote_t* wm) { /* * Smooth the angles. * diff --git a/src/events.h b/src/events.h index e9809e5..fde16a3 100644 --- a/src/events.h +++ b/src/events.h @@ -56,6 +56,8 @@ void handshake_expansion(struct wiimote_t* wm, byte* data, uint16_t len); void disable_expansion(struct wiimote_t* wm); void propagate_event(struct wiimote_t* wm, byte event, byte* msg); + +void idle_cycle(struct wiimote_t* wm); /** @} */ #endif /* EVENTS_H_INCLUDED */ diff --git a/src/os.h b/src/os.h index 8b0d814..3d8d68b 100644 --- a/src/os.h +++ b/src/os.h @@ -51,6 +51,7 @@ int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout); int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes); void wiiuse_os_disconnect(struct wiimote_t* wm); +int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes); int wiiuse_os_read(struct wiimote_t* wm); int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len); /** @} */ diff --git a/src/os_mac.m b/src/os_mac.m index c75740a..68e9c78 100644 --- a/src/os_mac.m +++ b/src/os_mac.m @@ -33,7 +33,9 @@ #ifdef __APPLE__ -#include "io.h" +#import "io.h" +#import "events.h" +#import "os.h" #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 @@ -51,23 +53,36 @@ void wiiuse_cleanup_platform_fields(struct wiimote_t* wm) { } int wiiuse_os_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { - return 0; + return 0; } int wiiuse_os_connect(struct wiimote_t** wm, int wiimotes) { - return 0; + return 0; } void wiiuse_os_disconnect(struct wiimote_t* wm) { } +int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { + int i; + + if (!wm) return 0; + + for (i = 0; i < wiimotes; ++i) { + wm[i]->event = WIIUSE_NONE; + idle_cycle(wm[i]); + } + + return 0; +} + int wiiuse_os_read(struct wiimote_t* wm) { - return 0; + return 0; } int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len) { - return 0; + return 0; } #endif // __APPLE__ diff --git a/src/os_nix.c b/src/os_nix.c index c70bb4d..838c84b 100644 --- a/src/os_nix.c +++ b/src/os_nix.c @@ -32,6 +32,8 @@ */ #include "io.h" +#include "events.h" +#include "os.h" #ifdef WIIUSE_BLUEZ @@ -229,6 +231,94 @@ void wiiuse_os_disconnect(struct wiimote_t* wm) { } +int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { + int evnt; + struct timeval tv; + fd_set fds; + int r; + int i; + int highest_fd = -1; + + evnt = 0; + if (!wm) return 0; + + /* block select() for 1/2000th of a second */ + tv.tv_sec = 0; + tv.tv_usec = 500; + + FD_ZERO(&fds); + + for (i = 0; i < wiimotes; ++i) { + /* only poll it if it is connected */ + if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) { + FD_SET(wm[i]->in_sock, &fds); + + /* find the highest fd of the connected wiimotes */ + if (wm[i]->in_sock > highest_fd) + highest_fd = wm[i]->in_sock; + } + + wm[i]->event = WIIUSE_NONE; + } + + if (highest_fd == -1) + /* nothing to poll */ + return 0; + + if (select(highest_fd + 1, &fds, NULL, NULL, &tv) == -1) { + WIIUSE_ERROR("Unable to select() the wiimote interrupt socket(s)."); + perror("Error Details"); + return 0; + } + + /* check each socket for an event */ + for (i = 0; i < wiimotes; ++i) { + /* if this wiimote is not connected, skip it */ + if (!WIIMOTE_IS_CONNECTED(wm[i])) + continue; + + if (FD_ISSET(wm[i]->in_sock, &fds)) { + /* clear out the event buffer */ + memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf)); + + /* clear out any old read requests */ + clear_dirty_reads(wm[i]); + + /* read the pending message into the buffer */ + r = read(wm[i]->in_sock, wm[i]->event_buf, sizeof(wm[i]->event_buf)); + if (r == -1) { + /* error reading data */ + WIIUSE_ERROR("Receiving wiimote data (id %i).", wm[i]->unid); + perror("Error Details"); + + if (errno == ENOTCONN) { + /* this can happen if the bluetooth dongle is disconnected */ + WIIUSE_ERROR("Bluetooth appears to be disconnected. Wiimote unid %i will be disconnected.", wm[i]->unid); + wiiuse_disconnect(wm[i]); + wiiuse_disconnected(wm[i]); + wm[i]->event = WIIUSE_UNEXPECTED_DISCONNECT; + } + + continue; + } + if (!r) { + /* remote disconnect */ + wiiuse_disconnected(wm[i]); + evnt = 1; + continue; + } + + /* propagate the event */ + propagate_event(wm[i], wm[i]->event_buf[1], wm[i]->event_buf+2); + evnt += (wm[i]->event != WIIUSE_NONE); + } else { + idle_cycle(wm[i]); + } + } + + return evnt; +} + int wiiuse_os_read(struct wiimote_t* wm) { /* not used */ return 0; diff --git a/src/os_win.c b/src/os_win.c index ca1cea6..fec5f50 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -33,6 +33,8 @@ #include "io.h" +#include "events.h" +#include "os.h" #ifdef WIIUSE_WIN32 #include @@ -177,6 +179,30 @@ void wiiuse_os_disconnect(struct wiimote_t* wm) { } +int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { + int i; + int evnt = 0; + + if (!wm) return 0; + + for (i = 0; i < wiimotes; ++i) { + wm[i]->event = WIIUSE_NONE; + + if (wiiuse_os_read(wm[i])) { + /* propagate the event */ + propagate_event(wm[i], wm[i]->event_buf[0], wm[i]->event_buf+1); + 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]); + } + } + + return evnt; +} + int wiiuse_os_read(struct wiimote_t* wm) { DWORD b, r;