diff --git a/src/io.c b/src/io.c index c3171ce..9e8a749 100644 --- a/src/io.c +++ b/src/io.c @@ -122,19 +122,13 @@ void wiiuse_disconnect(struct wiimote_t* wm) { */ void wiiuse_wait_report(struct wiimote_t *wm, int report, byte *buffer, int bufferLength) { - byte readReport; for(;;) { if(wiiuse_os_read(wm, buffer, bufferLength) > 0) { -#ifdef WIIUSE_WIN32 - readReport = buffer[0]; -#else - readReport = buffer[1]; -#endif - if(readReport == report) { + if(buffer[0] == report) { break; } else { - WIIUSE_WARNING("(id %i) dropping report 0x%x, waiting for 0x%x", wm->unid, readReport, report); + WIIUSE_WARNING("(id %i) dropping report 0x%x, waiting for 0x%x", wm->unid, buffer[0], report); } } } @@ -153,7 +147,7 @@ void wiiuse_wait_report(struct wiimote_t *wm, int report, byte *buffer, int buff * amount of data from the Wiimote. * */ -void wiiuse_read(struct wiimote_t *wm, byte memory, unsigned addr, unsigned short size, byte *data) +void wiiuse_read_data_sync(struct wiimote_t *wm, byte memory, unsigned addr, unsigned short size, byte *data) { byte pkt[6]; byte buf[MAX_PAYLOAD]; @@ -185,7 +179,7 @@ void wiiuse_read(struct wiimote_t *wm, byte memory, unsigned addr, unsigned shor for(i = 0; i < n_full_reports; ++i) { wiiuse_wait_report(wm, WM_RPT_READ, buf, MAX_PAYLOAD); - memmove(output, buf + 7, 16); + memmove(output, buf + 6, 16); output += 16; } @@ -193,7 +187,7 @@ void wiiuse_read(struct wiimote_t *wm, byte memory, unsigned addr, unsigned shor if(last_report) { wiiuse_wait_report(wm, WM_RPT_READ, buf, MAX_PAYLOAD); - memmove(output, buf + 7, last_report); + memmove(output, buf + 6, last_report); } } @@ -240,7 +234,7 @@ void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len) { struct accel_t* accel = &wm->accel_calib; - wiiuse_read(wm, 1, WM_MEM_OFFSET_CALIBRATION, 8, buf); + wiiuse_read_data_sync(wm, 1, WM_MEM_OFFSET_CALIBRATION, 8, buf); /* received read data */ accel->cal_zero.x = buf[0]; diff --git a/src/io.h b/src/io.h index 5f83ac1..9dd1da8 100644 --- a/src/io.h +++ b/src/io.h @@ -45,7 +45,7 @@ extern "C" { void wiiuse_handshake(struct wiimote_t* wm, byte* data, uint16_t len); void wiiuse_wait_report(struct wiimote_t *wm, int report, byte *buffer, int bufferLength); -void wiiuse_read(struct wiimote_t *wm, byte memory, unsigned addr, unsigned short size, byte *data); +void wiiuse_read_data_sync(struct wiimote_t *wm, byte memory, unsigned addr, unsigned short size, byte *data); /** @} */ #ifdef __cplusplus diff --git a/src/motion_plus.c b/src/motion_plus.c index 711f541..84a3699 100644 --- a/src/motion_plus.c +++ b/src/motion_plus.c @@ -47,23 +47,19 @@ void wiiuse_probe_motion_plus(struct wiimote_t *wm) { byte buf[MAX_PAYLOAD]; unsigned id; - unsigned short offset = 0; -#ifdef WIIUSE_WIN32 - offset = 1; -#endif - wiiuse_read(wm, 0, WM_EXP_MOTION_PLUS_IDENT, 6, buf); + wiiuse_read_data_sync(wm, 0, WM_EXP_MOTION_PLUS_IDENT, 6, buf); /* check error code */ - if(buf[4-offset] & 0x0f) + if(buf[4] & 0x0f) { WIIUSE_DEBUG("No Motion+ available, stopping probe."); WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_MPLUS_PRESENT); return; } - /* decode the id*/ - id = from_big_endian_uint32_t(buf + 2 - offset); + /* decode the id */ + id = from_big_endian_uint32_t(buf + 2); if(id != EXP_ID_CODE_INACTIVE_MOTION_PLUS && id != EXP_ID_CODE_NLA_MOTION_PLUS && diff --git a/src/os.h b/src/os.h index 779fa3f..7b86c44 100644 --- a/src/os.h +++ b/src/os.h @@ -52,6 +52,7 @@ 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); +/* buf[0] will be the report type, buf+1 the rest of the report */ int wiiuse_os_read(struct wiimote_t* wm, byte* buf, int len); int wiiuse_os_write(struct wiimote_t* wm, byte* buf, int len); /** @} */ diff --git a/src/os_mac/os_mac.m b/src/os_mac/os_mac.m index 1f64f45..8e2f57a 100644 --- a/src/os_mac/os_mac.m +++ b/src/os_mac/os_mac.m @@ -253,7 +253,8 @@ } // copy the data into the buffer - WiiuseReceivedData* newData = [[WiiuseReceivedData alloc] initWithBytes: data length: length]; + // on Mac, we ignore the first byte + WiiuseReceivedData* newData = [[WiiuseReceivedData alloc] initWithBytes: data+1 length: length-1]; [receivedDataLock lock]; [receivedData addObject: newData]; [receivedDataLock unlock]; @@ -316,9 +317,9 @@ // log the received data #ifdef WITH_WIIUSE_DEBUG { - printf("[DEBUG] (id %i) RECV: (%x) ", wm->unid, bytes[1]); + printf("[DEBUG] (id %i) RECV: (%.2x) ", wm->unid, bytes[0]); int x; - for (x = 2; x < length; ++x) + for (x = 1; x < length; ++x) printf("%.2x ", bytes[x]); printf("\n"); } diff --git a/src/os_mac/os_mac_interface.m b/src/os_mac/os_mac_interface.m index c533d55..ed5adfa 100644 --- a/src/os_mac/os_mac_interface.m +++ b/src/os_mac/os_mac_interface.m @@ -152,8 +152,8 @@ int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { memset(read_buffer, 0, sizeof(read_buffer)); /* read */ if (wiiuse_os_read(wm[i], read_buffer, sizeof(read_buffer))) { - /* propagate the event, messages should be read as in linux, starting from the second element */ - propagate_event(wm[i], read_buffer[1], read_buffer+2); + /* 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]); diff --git a/src/os_nix.c b/src/os_nix.c index 69349b1..c454f58 100644 --- a/src/os_nix.c +++ b/src/os_nix.c @@ -286,32 +286,12 @@ int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { clear_dirty_reads(wm[i]); /* read the pending message into the buffer */ - r = read(wm[i]->in_sock, read_buffer, sizeof(read_buffer)); - 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_os_disconnect(wm[i]); - wiiuse_disconnected(wm[i]); - wm[i]->event = WIIUSE_UNEXPECTED_DISCONNECT; - } - - continue; + r = wiiuse_os_read(wm, read_buffer, sizeof(read_buffer)); + if (r > 0) { + /* propagate the event */ + propagate_event(wm[i], read_buffer[0], read_buffer+1); + evnt += (wm[i]->event != WIIUSE_NONE); } - if (!r) { - /* remote disconnect */ - wiiuse_disconnected(wm[i]); - evnt = 1; - continue; - } - - /* propagate the event */ - propagate_event(wm[i], read_buffer[1], read_buffer+2); - evnt += (wm[i]->event != WIIUSE_NONE); } else { /* send out any waiting writes */ wiiuse_send_next_pending_write_request(wm[i]); @@ -324,11 +304,41 @@ int wiiuse_os_poll(struct wiimote_t** wm, int wiimotes) { int wiiuse_os_read(struct wiimote_t* wm, byte* buf, int len) { int rc; + int i; rc = read(wm->in_sock, buf, len); - if(rc <= 0) + if (r == -1) { + /* error reading data */ + WIIUSE_ERROR("Receiving wiimote data (id %i).", wm->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->unid); + wiiuse_os_disconnect(wm); + wiiuse_disconnected(wm); + } + } else if(rc == 0) { + /* remote disconnect */ wiiuse_disconnected(wm); + } else { + /* read successful */ + /* on *nix we ignore the first byte */ + memmove(buf, buf+1, len-1); + + /* log the received data */ +#ifdef WITH_WIIUSE_DEBUG + { + int i; + printf("[DEBUG] (id %i) RECV: (%.2x) ", wm->unid, buf[0]); + for(i = 1; i < rc; i++) { + printf("%.2x ", buf[i]); + } + printf("\n"); + } +#endif + } return rc; } diff --git a/src/os_win.c b/src/os_win.c index 0b0c0fb..489ff40 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -240,12 +240,13 @@ int wiiuse_os_read(struct wiimote_t* wm, byte* buf, int len) { if (!GetOverlappedResult(wm->dev_handle, &wm->hid_overlap, &b, 0)) return 0; + /* log the received data */ #ifdef WITH_WIIUSE_DEBUG { int i; - printf("[DEBUG] (id %i) RECV: (%x) ", wm->unid, buf[0]); + printf("[DEBUG] (id %i) RECV: (%.2x) ", wm->unid, buf[0]); for(i = 1; i < b; i++) { - printf("%x ", buf[i]); + printf("%.2x ", buf[i]); } printf("\n"); } diff --git a/src/wiiuse.h b/src/wiiuse.h index 7e1616a..f801e3c 100644 --- a/src/wiiuse.h +++ b/src/wiiuse.h @@ -307,12 +307,6 @@ typedef enum ir_position_t { #define WIIUSE_IS_LED_SET(wm, num) ((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num) /** @} */ -/* - * Largest known payload is 21 bytes. - * Add 2 for the prefix and round up to a power of 2. - */ -#define MAX_PAYLOAD 32 - /* * This is left over from an old hack, but it may actually * be a useful feature to keep so it wasn't removed. diff --git a/src/wiiuse_internal.h b/src/wiiuse_internal.h index 39c1f1e..e4830c0 100644 --- a/src/wiiuse_internal.h +++ b/src/wiiuse_internal.h @@ -243,6 +243,12 @@ #define NUNCHUK_IS_FLAG_SET(wm, s) ((*(wm->flags) & (s)) == (s)) +/* + * Largest known payload is 21 bytes. + * Add 1 (Win32) or 2 (Mac, *nix) for the prefix and round up to a power of 2. + */ +#define MAX_PAYLOAD 32 + /* * Smooth tilt calculations are computed with the * exponential moving average formula: