diff --git a/src/events.c b/src/events.c
index 6668eda..612891a 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1,146 +1,147 @@
-/*
- * 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 Handles wiimote events.
- *
- * The file includes functions that handle the events
- * that are sent from the wiimote to us.
- */
-
-#include
-
-#ifndef WIN32
- #include
- #include
+/*
+ * 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 Handles wiimote events.
+ *
+ * The file includes functions that handle the events
+ * that are sent from the wiimote to us.
+ */
+
+#include
+
+#ifndef WIN32
+ #include
+ #include
#include
-#else
+#else
#include
-#endif
-
-#include
-#include
-#include
-
-#include "definitions.h"
-#include "io.h"
-#include "wiiuse_internal.h"
-#include "dynamics.h"
-#include "ir.h"
-#include "nunchuk.h"
-#include "classic.h"
-#include "guitar_hero_3.h"
-#include "events.h"
-
-static void idle_cycle(struct wiimote_t* wm);
+#endif
+
+#include
+#include
+#include
+
+#include "definitions.h"
+#include "io.h"
+#include "wiiuse_internal.h"
+#include "dynamics.h"
+#include "ir.h"
+#include "nunchuk.h"
+#include "classic.h"
+#include "guitar_hero_3.h"
+#include "wiiboard.h"
+#include "events.h"
+
+static void idle_cycle(struct wiimote_t* wm);
static void clear_dirty_reads(struct wiimote_t* wm);
-static void propagate_event(struct wiimote_t* wm, byte event, byte* msg);
-static void event_data_read(struct wiimote_t* wm, byte* msg);
-static void event_status(struct wiimote_t* wm, byte* msg);
-static void handle_expansion(struct wiimote_t* wm, byte* msg);
-
-static void save_state(struct wiimote_t* wm);
-static int state_changed(struct wiimote_t* wm);
-
-/**
- * @brief Poll the wiimotes for any events.
- *
- * @param wm An array of pointers to wiimote_t structures.
- * @param wiimotes The number of wiimote_t structures in the \a wm array.
- *
- * @return Returns number of wiimotes that an event has occured on.
- *
- * It is necessary to poll the wiimote devices for events
- * that occur. If an event occurs on a particular wiimote,
- * the event variable will be set.
- */
-int wiiuse_poll(struct wiimote_t** wm, int wiimotes) {
- int evnt = 0;
-
- #ifndef WIN32
- /*
- * *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 */
+static void propagate_event(struct wiimote_t* wm, byte event, byte* msg);
+static void event_data_read(struct wiimote_t* wm, byte* msg);
+static void event_status(struct wiimote_t* wm, byte* msg);
+static void handle_expansion(struct wiimote_t* wm, byte* msg);
+
+static void save_state(struct wiimote_t* wm);
+static int state_changed(struct wiimote_t* wm);
+
+/**
+ * @brief Poll the wiimotes for any events.
+ *
+ * @param wm An array of pointers to wiimote_t structures.
+ * @param wiimotes The number of wiimote_t structures in the \a wm array.
+ *
+ * @return Returns number of wiimotes that an event has occured on.
+ *
+ * It is necessary to poll the wiimote devices for events
+ * that occur. If an event occurs on a particular wiimote,
+ * the event variable will be set.
+ */
+int wiiuse_poll(struct wiimote_t** wm, int wiimotes) {
+ int evnt = 0;
+
+ #ifndef WIN32
+ /*
+ * *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 */
+ 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");
@@ -150,72 +151,72 @@ int wiiuse_poll(struct wiimote_t** wm, int wiimotes) {
wiiuse_disconnect(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]);
- }
- }
- #else
- /*
- * Windows
- */
- int i;
-
- if (!wm) return 0;
-
- for (i = 0; i < wiimotes; ++i) {
- wm[i]->event = WIIUSE_NONE;
-
- if (wiiuse_io_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]);
- }
- }
- #endif
-
- return evnt;
-}
-
-
-/**
- * @brief Called on a cycle where no significant change occurs.
- *
- * @param wm Pointer to a wiimote_t structure.
- */
-static void idle_cycle(struct wiimote_t* wm) {
- /*
- * Smooth the angles.
- *
- * This is done to make sure that on every cycle the orientation
- * angles are smoothed. Normally when an event occurs the angles
- * are updated and smoothed, but if no packet comes in then the
- * angles remain the same. This means the angle wiiuse reports
- * is still an old value. Smoothing needs to be applied in this
- * case in order for the angle it reports to converge to the true
- * angle of the device.
- */
- if (WIIUSE_USING_ACC(wm) && WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)) {
- apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_ROLL);
- apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_PITCH);
- }
+
+ 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]);
+ }
+ }
+ #else
+ /*
+ * Windows
+ */
+ int i;
+
+ if (!wm) return 0;
+
+ for (i = 0; i < wiimotes; ++i) {
+ wm[i]->event = WIIUSE_NONE;
+
+ if (wiiuse_io_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]);
+ }
+ }
+ #endif
+
+ return evnt;
+}
+
+
+/**
+ * @brief Called on a cycle where no significant change occurs.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+static void idle_cycle(struct wiimote_t* wm) {
+ /*
+ * Smooth the angles.
+ *
+ * This is done to make sure that on every cycle the orientation
+ * angles are smoothed. Normally when an event occurs the angles
+ * are updated and smoothed, but if no packet comes in then the
+ * angles remain the same. This means the angle wiiuse reports
+ * is still an old value. Smoothing needs to be applied in this
+ * case in order for the angle it reports to converge to the true
+ * angle of the device.
+ */
+ if (WIIUSE_USING_ACC(wm) && WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING)) {
+ apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_ROLL);
+ apply_smoothing(&wm->accel_calib, &wm->orient, SMOOTH_PITCH);
+ }
/* clear out any old read requests */
clear_dirty_reads(wm);
@@ -237,264 +238,264 @@ static void clear_dirty_reads(struct wiimote_t* wm) {
free(req);
req = wm->read_req;
}
-}
-
-
-/**
- * @brief Analyze the event that occured on a wiimote.
- *
- * @param wm An array of pointers to wiimote_t structures.
- * @param event The event that occured.
- * @param msg The message specified in the event packet.
- *
- * Pass the event to the registered event callback.
- */
-static void propagate_event(struct wiimote_t* wm, byte event, byte* msg) {
- save_state(wm);
-
- switch (event) {
- case WM_RPT_BTN:
- {
- /* button */
- wiiuse_pressed_buttons(wm, msg);
- break;
- }
- case WM_RPT_BTN_ACC:
- {
- /* button - motion */
- wiiuse_pressed_buttons(wm, msg);
-
- wm->accel.x = msg[2];
- wm->accel.y = msg[3];
- wm->accel.z = msg[4];
-
- /* calculate the remote orientation */
- calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
-
- /* calculate the gforces on each axis */
- calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
-
- break;
- }
- case WM_RPT_READ:
- {
- /* data read */
- event_data_read(wm, msg);
-
- /* yeah buttons may be pressed, but this wasn't an "event" */
- return;
- }
- case WM_RPT_CTRL_STATUS:
- {
- /* controller status */
- event_status(wm, msg);
-
- /* don't execute the event callback */
- return;
- }
- case WM_RPT_BTN_EXP:
- {
- /* button - expansion */
- wiiuse_pressed_buttons(wm, msg);
- handle_expansion(wm, msg+2);
-
- break;
- }
- case WM_RPT_BTN_ACC_EXP:
- {
- /* button - motion - expansion */
- wiiuse_pressed_buttons(wm, msg);
-
- wm->accel.x = msg[2];
- wm->accel.y = msg[3];
- wm->accel.z = msg[4];
-
- calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
- calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
-
- handle_expansion(wm, msg+5);
-
- break;
- }
- case WM_RPT_BTN_ACC_IR:
- {
- /* button - motion - ir */
- wiiuse_pressed_buttons(wm, msg);
-
- wm->accel.x = msg[2];
- wm->accel.y = msg[3];
- wm->accel.z = msg[4];
-
- calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
- calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
-
- /* ir */
- calculate_extended_ir(wm, msg+5);
-
- break;
- }
- case WM_RPT_BTN_IR_EXP:
- {
- /* button - ir - expansion */
- wiiuse_pressed_buttons(wm, msg);
- handle_expansion(wm, msg+12);
-
- /* ir */
- calculate_basic_ir(wm, msg+2);
-
- break;
- }
- case WM_RPT_BTN_ACC_IR_EXP:
- {
- /* button - motion - ir - expansion */
- wiiuse_pressed_buttons(wm, msg);
-
- wm->accel.x = msg[2];
- wm->accel.y = msg[3];
- wm->accel.z = msg[4];
-
- calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
- calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
-
- handle_expansion(wm, msg+15);
-
- /* ir */
- calculate_basic_ir(wm, msg+5);
-
- break;
- }
- case WM_RPT_WRITE:
- {
- /* write feedback - safe to skip */
- break;
- }
- default:
- {
- WIIUSE_WARNING("Unknown event, can not handle it [Code 0x%x].", event);
- return;
- }
- }
-
- /* was there an event? */
- if (state_changed(wm))
- wm->event = WIIUSE_EVENT;
-}
-
-
-/**
- * @brief Find what buttons are pressed.
- *
- * @param wm Pointer to a wiimote_t structure.
- * @param msg The message specified in the event packet.
- */
-void wiiuse_pressed_buttons(struct wiimote_t* wm, byte* msg) {
- short now;
-
- /* convert to big endian */
- now = BIG_ENDIAN_SHORT(*(short*)msg) & WIIMOTE_BUTTON_ALL;
-
- /* pressed now & were pressed, then held */
- wm->btns_held = (now & wm->btns);
-
- /* were pressed or were held & not pressed now, then released */
- wm->btns_released = ((wm->btns | wm->btns_held) & ~now);
-
- /* buttons pressed now */
- wm->btns = now;
-}
-
-
-/**
- * @brief Received a data packet from a read request.
- *
- * @param wm Pointer to a wiimote_t structure.
- * @param msg The message specified in the event packet.
- *
- * Data from the wiimote comes in packets. If the requested
- * data segment size is bigger than one packet can hold then
- * several packets will be received. These packets are first
- * reassembled into one, then the registered callback function
- * that handles data reads is invoked.
- */
-static void event_data_read(struct wiimote_t* wm, byte* msg) {
- /* we must always assume the packet received is from the most recent request */
- byte err;
- byte len;
- unsigned short offset;
- struct read_req_t* req = wm->read_req;
-
- wiiuse_pressed_buttons(wm, msg);
+}
+
+
+/**
+ * @brief Analyze the event that occured on a wiimote.
+ *
+ * @param wm An array of pointers to wiimote_t structures.
+ * @param event The event that occured.
+ * @param msg The message specified in the event packet.
+ *
+ * Pass the event to the registered event callback.
+ */
+static void propagate_event(struct wiimote_t* wm, byte event, byte* msg) {
+ save_state(wm);
+
+ switch (event) {
+ case WM_RPT_BTN:
+ {
+ /* button */
+ wiiuse_pressed_buttons(wm, msg);
+ break;
+ }
+ case WM_RPT_BTN_ACC:
+ {
+ /* button - motion */
+ wiiuse_pressed_buttons(wm, msg);
+
+ wm->accel.x = msg[2];
+ wm->accel.y = msg[3];
+ wm->accel.z = msg[4];
+
+ /* calculate the remote orientation */
+ calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
+
+ /* calculate the gforces on each axis */
+ calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
+
+ break;
+ }
+ case WM_RPT_READ:
+ {
+ /* data read */
+ event_data_read(wm, msg);
+
+ /* yeah buttons may be pressed, but this wasn't an "event" */
+ return;
+ }
+ case WM_RPT_CTRL_STATUS:
+ {
+ /* controller status */
+ event_status(wm, msg);
+
+ /* don't execute the event callback */
+ return;
+ }
+ case WM_RPT_BTN_EXP:
+ {
+ /* button - expansion */
+ wiiuse_pressed_buttons(wm, msg);
+ handle_expansion(wm, msg+2);
+
+ break;
+ }
+ case WM_RPT_BTN_ACC_EXP:
+ {
+ /* button - motion - expansion */
+ wiiuse_pressed_buttons(wm, msg);
+
+ wm->accel.x = msg[2];
+ wm->accel.y = msg[3];
+ wm->accel.z = msg[4];
+
+ calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
+ calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
+
+ handle_expansion(wm, msg+5);
+
+ break;
+ }
+ case WM_RPT_BTN_ACC_IR:
+ {
+ /* button - motion - ir */
+ wiiuse_pressed_buttons(wm, msg);
+
+ wm->accel.x = msg[2];
+ wm->accel.y = msg[3];
+ wm->accel.z = msg[4];
+
+ calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
+ calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
+
+ /* ir */
+ calculate_extended_ir(wm, msg+5);
+
+ break;
+ }
+ case WM_RPT_BTN_IR_EXP:
+ {
+ /* button - ir - expansion */
+ wiiuse_pressed_buttons(wm, msg);
+ handle_expansion(wm, msg+12);
+
+ /* ir */
+ calculate_basic_ir(wm, msg+2);
+
+ break;
+ }
+ case WM_RPT_BTN_ACC_IR_EXP:
+ {
+ /* button - motion - ir - expansion */
+ wiiuse_pressed_buttons(wm, msg);
+
+ wm->accel.x = msg[2];
+ wm->accel.y = msg[3];
+ wm->accel.z = msg[4];
+
+ calculate_orientation(&wm->accel_calib, &wm->accel, &wm->orient, WIIMOTE_IS_FLAG_SET(wm, WIIUSE_SMOOTHING));
+ calculate_gforce(&wm->accel_calib, &wm->accel, &wm->gforce);
+
+ handle_expansion(wm, msg+15);
+
+ /* ir */
+ calculate_basic_ir(wm, msg+5);
+
+ break;
+ }
+ case WM_RPT_WRITE:
+ {
+ /* write feedback - safe to skip */
+ break;
+ }
+ default:
+ {
+ WIIUSE_WARNING("Unknown event, can not handle it [Code 0x%x].", event);
+ return;
+ }
+ }
+
+ /* was there an event? */
+ if (state_changed(wm))
+ wm->event = WIIUSE_EVENT;
+}
+
+
+/**
+ * @brief Find what buttons are pressed.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param msg The message specified in the event packet.
+ */
+void wiiuse_pressed_buttons(struct wiimote_t* wm, byte* msg) {
+ short now;
+
+ /* convert to big endian */
+ now = BIG_ENDIAN_SHORT(*(short*)msg) & WIIMOTE_BUTTON_ALL;
+
+ /* pressed now & were pressed, then held */
+ wm->btns_held = (now & wm->btns);
+
+ /* were pressed or were held & not pressed now, then released */
+ wm->btns_released = ((wm->btns | wm->btns_held) & ~now);
+
+ /* buttons pressed now */
+ wm->btns = now;
+}
+
+
+/**
+ * @brief Received a data packet from a read request.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param msg The message specified in the event packet.
+ *
+ * Data from the wiimote comes in packets. If the requested
+ * data segment size is bigger than one packet can hold then
+ * several packets will be received. These packets are first
+ * reassembled into one, then the registered callback function
+ * that handles data reads is invoked.
+ */
+static void event_data_read(struct wiimote_t* wm, byte* msg) {
+ /* we must always assume the packet received is from the most recent request */
+ byte err;
+ byte len;
+ unsigned short offset;
+ struct read_req_t* req = wm->read_req;
+
+ wiiuse_pressed_buttons(wm, msg);
/* find the next non-dirty request */
while (req && req->dirty)
req = req->next;
-
- /* if we don't have a request out then we didn't ask for this packet */
- if (!req) {
- WIIUSE_WARNING("Received data packet when no request was made.");
- return;
- }
-
- err = msg[2] & 0x0F;
-
- if (err == 0x08)
- WIIUSE_WARNING("Unable to read data - address does not exist.");
- else if (err == 0x07)
- WIIUSE_WARNING("Unable to read data - address is for write-only registers.");
- else if (err)
- WIIUSE_WARNING("Unable to read data - unknown error code %x.", err);
-
- if (err) {
- /* this request errored out, so skip it and go to the next one */
-
- /* delete this request */
- wm->read_req = req->next;
- free(req);
-
- /* if another request exists send it to the wiimote */
- if (wm->read_req)
- wiiuse_send_next_pending_read_request(wm);
-
- return;
- }
-
- len = ((msg[2] & 0xF0) >> 4) + 1;
- offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3));
- req->addr = (req->addr & 0xFFFF);
-
- req->wait -= len;
- if (req->wait >= req->size)
- /* this should never happen */
- req->wait = 0;
-
- WIIUSE_DEBUG("Received read packet:");
- WIIUSE_DEBUG(" Packet read offset: %i bytes", offset);
- WIIUSE_DEBUG(" Request read offset: %i bytes", req->addr);
- WIIUSE_DEBUG(" Read offset into buf: %i bytes", offset - req->addr);
- WIIUSE_DEBUG(" Read data size: %i bytes", len);
- WIIUSE_DEBUG(" Still need: %i bytes", req->wait);
-
- /* reconstruct this part of the data */
- memcpy((req->buf + offset - req->addr), (msg + 5), len);
-
- #ifdef WITH_WIIUSE_DEBUG
- {
- int i = 0;
- printf("Read: ");
- for (; i < req->size - req->wait; ++i)
- printf("%x ", req->buf[i]);
- printf("\n");
- }
- #endif
-
- /* if all data has been received, execute the read event callback or generate event */
+
+ /* if we don't have a request out then we didn't ask for this packet */
+ if (!req) {
+ WIIUSE_WARNING("Received data packet when no request was made.");
+ return;
+ }
+
+ err = msg[2] & 0x0F;
+
+ if (err == 0x08)
+ WIIUSE_WARNING("Unable to read data - address does not exist.");
+ else if (err == 0x07)
+ WIIUSE_WARNING("Unable to read data - address is for write-only registers.");
+ else if (err)
+ WIIUSE_WARNING("Unable to read data - unknown error code %x.", err);
+
+ if (err) {
+ /* this request errored out, so skip it and go to the next one */
+
+ /* delete this request */
+ wm->read_req = req->next;
+ free(req);
+
+ /* if another request exists send it to the wiimote */
+ if (wm->read_req)
+ wiiuse_send_next_pending_read_request(wm);
+
+ return;
+ }
+
+ len = ((msg[2] & 0xF0) >> 4) + 1;
+ offset = BIG_ENDIAN_SHORT(*(unsigned short*)(msg + 3));
+ req->addr = (req->addr & 0xFFFF);
+
+ req->wait -= len;
+ if (req->wait >= req->size)
+ /* this should never happen */
+ req->wait = 0;
+
+ WIIUSE_DEBUG("Received read packet:");
+ WIIUSE_DEBUG(" Packet read offset: %i bytes", offset);
+ WIIUSE_DEBUG(" Request read offset: %i bytes", req->addr);
+ WIIUSE_DEBUG(" Read offset into buf: %i bytes", offset - req->addr);
+ WIIUSE_DEBUG(" Read data size: %i bytes", len);
+ WIIUSE_DEBUG(" Still need: %i bytes", req->wait);
+
+ /* reconstruct this part of the data */
+ memcpy((req->buf + offset - req->addr), (msg + 5), len);
+
+ #ifdef WITH_WIIUSE_DEBUG
+ {
+ int i = 0;
+ printf("Read: ");
+ for (; i < req->size - req->wait; ++i)
+ printf("%x ", req->buf[i]);
+ printf("\n");
+ }
+ #endif
+
+ /* if all data has been received, execute the read event callback or generate event */
if (!req->wait) {
if (req->cb) {
- /* this was a callback, so invoke it now */
- req->cb(wm, req->buf, req->size);
-
- /* delete this request */
- wm->read_req = req->next;
+ /* this was a callback, so invoke it now */
+ req->cb(wm, req->buf, req->size);
+
+ /* delete this request */
+ wm->read_req = req->next;
free(req);
} else {
/*
@@ -506,373 +507,394 @@ static void event_data_read(struct wiimote_t* wm, byte* msg) {
*/
wm->event = WIIUSE_READ_DATA;
req->dirty = 1;
- }
-
- /* if another request exists send it to the wiimote */
- if (wm->read_req)
- wiiuse_send_next_pending_read_request(wm);
- }
-}
-
-
-/**
- * @brief Read the controller status.
- *
- * @param wm Pointer to a wiimote_t structure.
- * @param msg The message specified in the event packet.
- *
- * Read the controller status and execute the registered status callback.
- */
-static void event_status(struct wiimote_t* wm, byte* msg) {
- int led[4] = {0};
- int attachment = 0;
- int ir = 0;
- int exp_changed = 0;
-
- /*
- * An event occured.
- * This event can be overwritten by a more specific
- * event type during a handshake or expansion removal.
- */
- wm->event = WIIUSE_STATUS;
-
- wiiuse_pressed_buttons(wm, msg);
-
- /* find what LEDs are lit */
- if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_1) led[0] = 1;
- if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_2) led[1] = 1;
- if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_3) led[2] = 1;
- if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_4) led[3] = 1;
-
- /* is an attachment connected to the expansion port? */
- if ((msg[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == WM_CTRL_STATUS_BYTE1_ATTACHMENT)
- attachment = 1;
-
- /* is the speaker enabled? */
- if ((msg[2] & WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED) == WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED)
- WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER);
-
- /* is IR sensing enabled? */
- if ((msg[2] & WM_CTRL_STATUS_BYTE1_IR_ENABLED) == WM_CTRL_STATUS_BYTE1_IR_ENABLED)
- ir = 1;
-
- /* find the battery level and normalize between 0 and 1 */
- wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE);
-
- /* expansion port */
- if (attachment && !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) {
- /* send the initialization code for the attachment */
- handshake_expansion(wm, NULL, 0);
- exp_changed = 1;
- } else if (!attachment && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) {
- /* attachment removed */
- disable_expansion(wm);
- exp_changed = 1;
- }
-
- #ifdef WIN32
- if (!attachment) {
- WIIUSE_DEBUG("Setting timeout to normal %i ms.", wm->normal_timeout);
- wm->timeout = wm->normal_timeout;
- }
- #endif
-
- /*
- * From now on the remote will only send status packets.
- * We need to send a WIIMOTE_CMD_REPORT_TYPE packet to
- * reenable other incoming reports.
- */
- if (exp_changed && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
- /*
- * Since the expansion status changed IR needs to
- * be reset for the new IR report mode.
- */
- WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
- wiiuse_set_ir(wm, 1);
- } else
- wiiuse_set_report_type(wm);
-}
-
-
-/**
- * @brief Handle data from the expansion.
- *
- * @param wm A pointer to a wiimote_t structure.
- * @param msg The message specified in the event packet for the expansion.
- */
-static void handle_expansion(struct wiimote_t* wm, byte* msg) {
- switch (wm->exp.type) {
- case EXP_NUNCHUK:
- nunchuk_event(&wm->exp.nunchuk, msg);
- break;
- case EXP_CLASSIC:
- classic_ctrl_event(&wm->exp.classic, msg);
- break;
- case EXP_GUITAR_HERO_3:
- guitar_hero_3_event(&wm->exp.gh3, msg);
- break;
- default:
- break;
- }
-}
-
-
-/**
- * @brief Handle the handshake data from the expansion device.
- *
- * @param wm A pointer to a wiimote_t structure.
- * @param data The data read in from the device.
- * @param len The length of the data block, in bytes.
- *
- * Tries to determine what kind of expansion was attached
- * and invoke the correct handshake function.
- *
- * If the data is NULL then this function will try to start
- * a handshake with the expansion.
- */
-void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len) {
- int id;
-
- if (!data) {
- byte* handshake_buf;
- byte buf = 0x00;
-
- if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
- disable_expansion(wm);
-
- /* increase the timeout until the handshake completes */
- #ifdef WIN32
- WIIUSE_DEBUG("Setting timeout to expansion %i ms.", wm->exp_timeout);
- wm->timeout = wm->exp_timeout;
- #endif
-
- wiiuse_write_data(wm, WM_EXP_MEM_ENABLE, &buf, 1);
-
- /* get the calibration data */
- handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
- wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
-
- /* tell the wiimote to send expansion data */
- WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP);
-
- return;
- }
-
- id = BIG_ENDIAN_LONG(*(int*)(data + 220));
-
- /* call the corresponding handshake function for this expansion */
- switch (id) {
- case EXP_ID_CODE_NUNCHUK:
- {
- if (nunchuk_handshake(wm, &wm->exp.nunchuk, data, len))
- wm->event = WIIUSE_NUNCHUK_INSERTED;
- break;
- }
- case EXP_ID_CODE_CLASSIC_CONTROLLER:
+ }
+
+ /* if another request exists send it to the wiimote */
+ if (wm->read_req)
+ wiiuse_send_next_pending_read_request(wm);
+ }
+}
+
+
+/**
+ * @brief Read the controller status.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param msg The message specified in the event packet.
+ *
+ * Read the controller status and execute the registered status callback.
+ */
+static void event_status(struct wiimote_t* wm, byte* msg) {
+ int led[4] = {0};
+ int attachment = 0;
+ int ir = 0;
+ int exp_changed = 0;
+
+ /*
+ * An event occured.
+ * This event can be overwritten by a more specific
+ * event type during a handshake or expansion removal.
+ */
+ wm->event = WIIUSE_STATUS;
+
+ wiiuse_pressed_buttons(wm, msg);
+
+ /* find what LEDs are lit */
+ if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_1) led[0] = 1;
+ if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_2) led[1] = 1;
+ if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_3) led[2] = 1;
+ if (msg[2] & WM_CTRL_STATUS_BYTE1_LED_4) led[3] = 1;
+
+ /* is an attachment connected to the expansion port? */
+ if ((msg[2] & WM_CTRL_STATUS_BYTE1_ATTACHMENT) == WM_CTRL_STATUS_BYTE1_ATTACHMENT)
+ attachment = 1;
+
+ /* is the speaker enabled? */
+ if ((msg[2] & WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED) == WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED)
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_SPEAKER);
+
+ /* is IR sensing enabled? */
+ if ((msg[2] & WM_CTRL_STATUS_BYTE1_IR_ENABLED) == WM_CTRL_STATUS_BYTE1_IR_ENABLED)
+ ir = 1;
+
+ /* find the battery level and normalize between 0 and 1 */
+ wm->battery_level = (msg[5] / (float)WM_MAX_BATTERY_CODE);
+
+ /* expansion port */
+ if (attachment && !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) {
+ /* send the initialization code for the attachment */
+ handshake_expansion(wm, NULL, 0);
+ exp_changed = 1;
+ } else if (!attachment && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP)) {
+ /* attachment removed */
+ disable_expansion(wm);
+ exp_changed = 1;
+ }
+
+ #ifdef WIN32
+ if (!attachment) {
+ WIIUSE_DEBUG("Setting timeout to normal %i ms.", wm->normal_timeout);
+ wm->timeout = wm->normal_timeout;
+ }
+ #endif
+
+ /*
+ * From now on the remote will only send status packets.
+ * We need to send a WIIMOTE_CMD_REPORT_TYPE packet to
+ * reenable other incoming reports.
+ */
+ if (exp_changed && WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
+ /*
+ * Since the expansion status changed IR needs to
+ * be reset for the new IR report mode.
+ */
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
+ wiiuse_set_ir(wm, 1);
+ } else
+ wiiuse_set_report_type(wm);
+}
+
+
+/**
+ * @brief Handle data from the expansion.
+ *
+ * @param wm A pointer to a wiimote_t structure.
+ * @param msg The message specified in the event packet for the expansion.
+ */
+static void handle_expansion(struct wiimote_t* wm, byte* msg) {
+ switch (wm->exp.type) {
+ case EXP_NUNCHUK:
+ nunchuk_event(&wm->exp.nunchuk, msg);
+ break;
+ case EXP_CLASSIC:
+ classic_ctrl_event(&wm->exp.classic, msg);
+ break;
+ case EXP_GUITAR_HERO_3:
+ guitar_hero_3_event(&wm->exp.gh3, msg);
+ break;
+ case EXP_WII_BOARD:
+ wii_board_event(&wm->exp.wb, msg);
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**
+ * @brief Handle the handshake data from the expansion device.
+ *
+ * @param wm A pointer to a wiimote_t structure.
+ * @param data The data read in from the device.
+ * @param len The length of the data block, in bytes.
+ *
+ * Tries to determine what kind of expansion was attached
+ * and invoke the correct handshake function.
+ *
+ * If the data is NULL then this function will try to start
+ * a handshake with the expansion.
+ */
+void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len) {
+ int id;
+
+ if (!data) {
+ byte* handshake_buf;
+ byte buf = 0x00;
+
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
+ disable_expansion(wm);
+
+ /* increase the timeout until the handshake completes */
+ #ifdef WIN32
+ WIIUSE_DEBUG("Setting timeout to expansion %i ms.", wm->exp_timeout);
+ wm->timeout = wm->exp_timeout;
+ #endif
+
+ wiiuse_write_data(wm, WM_EXP_MEM_ENABLE, &buf, 1);
+
+ /* get the calibration data */
+ handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+ wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+ /* tell the wiimote to send expansion data */
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_EXP);
+
+ return;
+ }
+
+ id = BIG_ENDIAN_LONG(*(int*)(data + 220));
+
+ /* call the corresponding handshake function for this expansion */
+ switch (id) {
+ case EXP_ID_CODE_NUNCHUK:
{
- if (classic_ctrl_handshake(wm, &wm->exp.classic, data, len))
+ if (nunchuk_handshake(wm, &wm->exp.nunchuk, data, len))
+ wm->event = WIIUSE_NUNCHUK_INSERTED;
+ break;
+ }
+ case EXP_ID_CODE_CLASSIC_CONTROLLER:
+ {
+ if (classic_ctrl_handshake(wm, &wm->exp.classic, data, len))
wm->event = WIIUSE_CLASSIC_CTRL_INSERTED;
- break;
- }
- case EXP_ID_CODE_GUITAR:
- {
- if (guitar_hero_3_handshake(wm, &wm->exp.gh3, data, len))
- wm->event = WIIUSE_GUITAR_HERO_3_CTRL_INSERTED;
- break;
- }
- default:
- {
- WIIUSE_WARNING("Unknown expansion type. Code: 0x%x", id);
- break;
- }
- }
-
- free(data);
-}
-
-
-
-/**
- * @brief Disable the expansion device if it was enabled.
- *
- * @param wm A pointer to a wiimote_t structure.
- * @param data The data read in from the device.
- * @param len The length of the data block, in bytes.
- *
- * If the data is NULL then this function will try to start
- * a handshake with the expansion.
- */
-void disable_expansion(struct wiimote_t* wm) {
- if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
- return;
-
- /* tell the assoicated module the expansion was removed */
- switch (wm->exp.type) {
- case EXP_NUNCHUK:
- nunchuk_disconnected(&wm->exp.nunchuk);
- wm->event = WIIUSE_NUNCHUK_REMOVED;
- break;
- case EXP_CLASSIC:
- classic_ctrl_disconnected(&wm->exp.classic);
- wm->event = WIIUSE_CLASSIC_CTRL_REMOVED;
- break;
- case EXP_GUITAR_HERO_3:
- guitar_hero_3_disconnected(&wm->exp.gh3);
- wm->event = WIIUSE_GUITAR_HERO_3_CTRL_REMOVED;
- break;
- default:
- break;
- }
-
- WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
- wm->exp.type = EXP_NONE;
-}
-
-
-/**
- * @brief Save important state data.
- * @param wm A pointer to a wiimote_t structure.
- */
-static void save_state(struct wiimote_t* wm) {
- /* wiimote */
- wm->lstate.btns = wm->btns;
- wm->lstate.accel = wm->accel;
-
- /* ir */
- if (WIIUSE_USING_IR(wm)) {
- wm->lstate.ir_ax = wm->ir.ax;
- wm->lstate.ir_ay = wm->ir.ay;
- wm->lstate.ir_distance = wm->ir.distance;
- }
-
- /* expansion */
- switch (wm->exp.type) {
- case EXP_NUNCHUK:
- wm->lstate.exp_ljs_ang = wm->exp.nunchuk.js.ang;
- wm->lstate.exp_ljs_mag = wm->exp.nunchuk.js.mag;
- wm->lstate.exp_btns = wm->exp.nunchuk.btns;
- wm->lstate.exp_accel = wm->exp.nunchuk.accel;
- break;
-
- case EXP_CLASSIC:
- wm->lstate.exp_ljs_ang = wm->exp.classic.ljs.ang;
- wm->lstate.exp_ljs_mag = wm->exp.classic.ljs.mag;
- wm->lstate.exp_rjs_ang = wm->exp.classic.rjs.ang;
- wm->lstate.exp_rjs_mag = wm->exp.classic.rjs.mag;
- wm->lstate.exp_r_shoulder = wm->exp.classic.r_shoulder;
- wm->lstate.exp_l_shoulder = wm->exp.classic.l_shoulder;
- wm->lstate.exp_btns = wm->exp.classic.btns;
- break;
-
- case EXP_GUITAR_HERO_3:
- wm->lstate.exp_ljs_ang = wm->exp.gh3.js.ang;
- wm->lstate.exp_ljs_mag = wm->exp.gh3.js.mag;
- wm->lstate.exp_r_shoulder = wm->exp.gh3.whammy_bar;
- wm->lstate.exp_btns = wm->exp.gh3.btns;
- break;
-
- case EXP_NONE:
- break;
- }
-}
-
-
-/**
- * @brief Determine if the current state differs significantly from the previous.
- * @param wm A pointer to a wiimote_t structure.
- * @return 1 if a significant change occured, 0 if not.
- */
-static int state_changed(struct wiimote_t* wm) {
- #define STATE_CHANGED(a, b) if (a != b) return 1
-
- #define CROSS_THRESH(last, now, thresh) \
- do { \
- if (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_ORIENT_THRESH)) { \
- if ((diff_f(last.roll, now.roll) >= thresh) || \
- (diff_f(last.pitch, now.pitch) >= thresh) || \
- (diff_f(last.yaw, now.yaw) >= thresh)) \
- { \
- last = now; \
- return 1; \
- } \
- } else { \
- if (last.roll != now.roll) return 1; \
- if (last.pitch != now.pitch) return 1; \
- if (last.yaw != now.yaw) return 1; \
- } \
- } while (0)
-
- #define CROSS_THRESH_XYZ(last, now, thresh) \
- do { \
- if (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_ORIENT_THRESH)) { \
- if ((diff_f(last.x, now.x) >= thresh) || \
- (diff_f(last.y, now.y) >= thresh) || \
- (diff_f(last.z, now.z) >= thresh)) \
- { \
- last = now; \
- return 1; \
- } \
- } else { \
- if (last.x != now.x) return 1; \
- if (last.y != now.y) return 1; \
- if (last.z != now.z) return 1; \
- } \
- } while (0)
-
- /* ir */
- if (WIIUSE_USING_IR(wm)) {
- STATE_CHANGED(wm->lstate.ir_ax, wm->ir.ax);
- STATE_CHANGED(wm->lstate.ir_ay, wm->ir.ay);
- STATE_CHANGED(wm->lstate.ir_distance, wm->ir.distance);
- }
-
- /* accelerometer */
- if (WIIUSE_USING_ACC(wm)) {
- /* raw accelerometer */
- CROSS_THRESH_XYZ(wm->lstate.accel, wm->accel, wm->accel_threshold);
-
- /* orientation */
- CROSS_THRESH(wm->lstate.orient, wm->orient, wm->orient_threshold);
- }
-
- /* expansion */
- switch (wm->exp.type) {
- case EXP_NUNCHUK:
- {
- STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.nunchuk.js.ang);
- STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.nunchuk.js.mag);
- STATE_CHANGED(wm->lstate.exp_btns, wm->exp.nunchuk.btns);
-
- CROSS_THRESH(wm->lstate.exp_orient, wm->exp.nunchuk.orient, wm->exp.nunchuk.orient_threshold);
- CROSS_THRESH_XYZ(wm->lstate.exp_accel, wm->exp.nunchuk.accel, wm->exp.nunchuk.accel_threshold);
- break;
- }
- case EXP_CLASSIC:
- {
- STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.classic.ljs.ang);
- STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.classic.ljs.mag);
- STATE_CHANGED(wm->lstate.exp_rjs_ang, wm->exp.classic.rjs.ang);
- STATE_CHANGED(wm->lstate.exp_rjs_mag, wm->exp.classic.rjs.mag);
- STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.classic.r_shoulder);
- STATE_CHANGED(wm->lstate.exp_l_shoulder, wm->exp.classic.l_shoulder);
- STATE_CHANGED(wm->lstate.exp_btns, wm->exp.classic.btns);
- break;
- }
- case EXP_GUITAR_HERO_3:
- {
- STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.gh3.js.ang);
- STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.gh3.js.mag);
- STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.gh3.whammy_bar);
- STATE_CHANGED(wm->lstate.exp_btns, wm->exp.gh3.btns);
- break;
- }
- case EXP_NONE:
- {
- break;
- }
- }
-
- STATE_CHANGED(wm->lstate.btns, wm->btns);
-
- return 0;
-}
+ break;
+ }
+ case EXP_ID_CODE_GUITAR:
+ {
+ if (guitar_hero_3_handshake(wm, &wm->exp.gh3, data, len))
+ wm->event = WIIUSE_GUITAR_HERO_3_CTRL_INSERTED;
+ break;
+ }
+ case EXP_ID_CODE_WII_BOARD:
+ {
+ if (wii_board_handshake(wm, &wm->exp.wb, data, len))
+ wm->event = WIIUSE_WII_BOARD_CTRL_INSERTED;
+ break;
+ }
+ default:
+ {
+ WIIUSE_WARNING("Unknown expansion type. Code: 0x%x", id);
+ break;
+ }
+ }
+
+ free(data);
+}
+
+
+
+/**
+ * @brief Disable the expansion device if it was enabled.
+ *
+ * @param wm A pointer to a wiimote_t structure.
+ * @param data The data read in from the device.
+ * @param len The length of the data block, in bytes.
+ *
+ * If the data is NULL then this function will try to start
+ * a handshake with the expansion.
+ */
+void disable_expansion(struct wiimote_t* wm) {
+ if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
+ return;
+
+ /* tell the assoicated module the expansion was removed */
+ switch (wm->exp.type) {
+ case EXP_NUNCHUK:
+ nunchuk_disconnected(&wm->exp.nunchuk);
+ wm->event = WIIUSE_NUNCHUK_REMOVED;
+ break;
+ case EXP_CLASSIC:
+ classic_ctrl_disconnected(&wm->exp.classic);
+ wm->event = WIIUSE_CLASSIC_CTRL_REMOVED;
+ break;
+ case EXP_GUITAR_HERO_3:
+ guitar_hero_3_disconnected(&wm->exp.gh3);
+ wm->event = WIIUSE_GUITAR_HERO_3_CTRL_REMOVED;
+ break;
+ case EXP_WII_BOARD:
+ guitar_hero_3_disconnected(&wm->exp.gh3);
+ wm->event = WIIUSE_WII_BOARD_CTRL_REMOVED;
+ break;
+ default:
+ break;
+ }
+
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_EXP);
+ wm->exp.type = EXP_NONE;
+}
+
+
+/**
+ * @brief Save important state data.
+ * @param wm A pointer to a wiimote_t structure.
+ */
+static void save_state(struct wiimote_t* wm) {
+ /* wiimote */
+ wm->lstate.btns = wm->btns;
+ wm->lstate.accel = wm->accel;
+
+ /* ir */
+ if (WIIUSE_USING_IR(wm)) {
+ wm->lstate.ir_ax = wm->ir.ax;
+ wm->lstate.ir_ay = wm->ir.ay;
+ wm->lstate.ir_distance = wm->ir.distance;
+ }
+
+ /* expansion */
+ switch (wm->exp.type) {
+ case EXP_NUNCHUK:
+ wm->lstate.exp_ljs_ang = wm->exp.nunchuk.js.ang;
+ wm->lstate.exp_ljs_mag = wm->exp.nunchuk.js.mag;
+ wm->lstate.exp_btns = wm->exp.nunchuk.btns;
+ wm->lstate.exp_accel = wm->exp.nunchuk.accel;
+ break;
+
+ case EXP_CLASSIC:
+ wm->lstate.exp_ljs_ang = wm->exp.classic.ljs.ang;
+ wm->lstate.exp_ljs_mag = wm->exp.classic.ljs.mag;
+ wm->lstate.exp_rjs_ang = wm->exp.classic.rjs.ang;
+ wm->lstate.exp_rjs_mag = wm->exp.classic.rjs.mag;
+ wm->lstate.exp_r_shoulder = wm->exp.classic.r_shoulder;
+ wm->lstate.exp_l_shoulder = wm->exp.classic.l_shoulder;
+ wm->lstate.exp_btns = wm->exp.classic.btns;
+ break;
+
+ case EXP_GUITAR_HERO_3:
+ wm->lstate.exp_ljs_ang = wm->exp.gh3.js.ang;
+ wm->lstate.exp_ljs_mag = wm->exp.gh3.js.mag;
+ wm->lstate.exp_r_shoulder = wm->exp.gh3.whammy_bar;
+ wm->lstate.exp_btns = wm->exp.gh3.btns;
+ break;
+
+ case EXP_NONE:
+ break;
+ }
+}
+
+
+/**
+ * @brief Determine if the current state differs significantly from the previous.
+ * @param wm A pointer to a wiimote_t structure.
+ * @return 1 if a significant change occured, 0 if not.
+ */
+static int state_changed(struct wiimote_t* wm) {
+ #define STATE_CHANGED(a, b) if (a != b) return 1
+
+ #define CROSS_THRESH(last, now, thresh) \
+ do { \
+ if (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_ORIENT_THRESH)) { \
+ if ((diff_f(last.roll, now.roll) >= thresh) || \
+ (diff_f(last.pitch, now.pitch) >= thresh) || \
+ (diff_f(last.yaw, now.yaw) >= thresh)) \
+ { \
+ last = now; \
+ return 1; \
+ } \
+ } else { \
+ if (last.roll != now.roll) return 1; \
+ if (last.pitch != now.pitch) return 1; \
+ if (last.yaw != now.yaw) return 1; \
+ } \
+ } while (0)
+
+ #define CROSS_THRESH_XYZ(last, now, thresh) \
+ do { \
+ if (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_ORIENT_THRESH)) { \
+ if ((diff_f(last.x, now.x) >= thresh) || \
+ (diff_f(last.y, now.y) >= thresh) || \
+ (diff_f(last.z, now.z) >= thresh)) \
+ { \
+ last = now; \
+ return 1; \
+ } \
+ } else { \
+ if (last.x != now.x) return 1; \
+ if (last.y != now.y) return 1; \
+ if (last.z != now.z) return 1; \
+ } \
+ } while (0)
+
+ /* ir */
+ if (WIIUSE_USING_IR(wm)) {
+ STATE_CHANGED(wm->lstate.ir_ax, wm->ir.ax);
+ STATE_CHANGED(wm->lstate.ir_ay, wm->ir.ay);
+ STATE_CHANGED(wm->lstate.ir_distance, wm->ir.distance);
+ }
+
+ /* accelerometer */
+ if (WIIUSE_USING_ACC(wm)) {
+ /* raw accelerometer */
+ CROSS_THRESH_XYZ(wm->lstate.accel, wm->accel, wm->accel_threshold);
+
+ /* orientation */
+ CROSS_THRESH(wm->lstate.orient, wm->orient, wm->orient_threshold);
+ }
+
+ /* expansion */
+ switch (wm->exp.type) {
+ case EXP_NUNCHUK:
+ {
+ STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.nunchuk.js.ang);
+ STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.nunchuk.js.mag);
+ STATE_CHANGED(wm->lstate.exp_btns, wm->exp.nunchuk.btns);
+
+ CROSS_THRESH(wm->lstate.exp_orient, wm->exp.nunchuk.orient, wm->exp.nunchuk.orient_threshold);
+ CROSS_THRESH_XYZ(wm->lstate.exp_accel, wm->exp.nunchuk.accel, wm->exp.nunchuk.accel_threshold);
+ break;
+ }
+ case EXP_CLASSIC:
+ {
+ STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.classic.ljs.ang);
+ STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.classic.ljs.mag);
+ STATE_CHANGED(wm->lstate.exp_rjs_ang, wm->exp.classic.rjs.ang);
+ STATE_CHANGED(wm->lstate.exp_rjs_mag, wm->exp.classic.rjs.mag);
+ STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.classic.r_shoulder);
+ STATE_CHANGED(wm->lstate.exp_l_shoulder, wm->exp.classic.l_shoulder);
+ STATE_CHANGED(wm->lstate.exp_btns, wm->exp.classic.btns);
+ break;
+ }
+ case EXP_GUITAR_HERO_3:
+ {
+ STATE_CHANGED(wm->lstate.exp_ljs_ang, wm->exp.gh3.js.ang);
+ STATE_CHANGED(wm->lstate.exp_ljs_mag, wm->exp.gh3.js.mag);
+ STATE_CHANGED(wm->lstate.exp_r_shoulder, wm->exp.gh3.whammy_bar);
+ STATE_CHANGED(wm->lstate.exp_btns, wm->exp.gh3.btns);
+ break;
+ }
+ case EXP_WII_BOARD:
+ {
+ STATE_CHANGED(wm->exp.wb.ltr,wm->exp.wb.tr);
+ STATE_CHANGED(wm->exp.wb.ltl,wm->exp.wb.tl);
+ STATE_CHANGED(wm->exp.wb.lbr,wm->exp.wb.br);
+ STATE_CHANGED(wm->exp.wb.lbl,wm->exp.wb.bl);
+ break;
+ }
+ case EXP_NONE:
+ {
+ break;
+ }
+ }
+
+ STATE_CHANGED(wm->lstate.btns, wm->btns);
+
+ return 0;
+}
diff --git a/src/wiiboard.c b/src/wiiboard.c
new file mode 100644
index 0000000..72b593d
--- /dev/null
+++ b/src/wiiboard.c
@@ -0,0 +1,183 @@
+/*
+ * 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 Wii Fit Balance Board device.
+ */
+
+#include
+#include
+#include
+
+#ifdef WIN32
+ #include
+#endif
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "wiiboard.h"
+
+static short big_to_lil(unsigned short num)
+{
+ short ret = num;
+ char *bret = (char*)&ret;
+ char tmp = bret[1];
+ bret[1] = bret[0];
+ bret[0] = tmp;
+ return ret;
+}
+
+/**
+ * @brief Handle the handshake data from the guitar.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ * @param data The data read in from the device.
+ * @param len The length of the data block, in bytes.
+ *
+ * @return Returns 1 if handshake was successful, 0 if not.
+ */
+
+int wii_board_handshake(struct wiimote_t* wm, struct wii_board_t* wb, byte* data, unsigned short len) {
+ int i;
+ /* decrypt data */
+ printf("DECRYPTED DATA WIIBOARD\n");
+ for (i = 0; i < len; ++i)
+ {
+ if(i%16==0)
+ {
+ if(i!=0)
+ printf("\n");
+
+ printf("%X: ",0x4a40000+32+i);
+ }
+ printf("%02X ", data[i]);
+ }
+ printf("\n");
+
+ short *handshake_short = (short*)data;
+
+ wb->ctr[0] = big_to_lil(handshake_short[2]);
+ wb->cbr[0] = big_to_lil(handshake_short[3]);
+ wb->ctl[0] = big_to_lil(handshake_short[4]);
+ wb->cbl[0] = big_to_lil(handshake_short[5]);
+
+ wb->ctr[1] = big_to_lil(handshake_short[6]);
+ wb->cbr[1] = big_to_lil(handshake_short[7]);
+ wb->ctl[1] = big_to_lil(handshake_short[8]);
+ wb->cbl[1] = big_to_lil(handshake_short[9]);
+
+ wb->ctr[2] = big_to_lil(handshake_short[10]);
+ wb->cbr[2] = big_to_lil(handshake_short[11]);
+ wb->ctl[2] = big_to_lil(handshake_short[12]);
+ wb->cbl[2] = big_to_lil(handshake_short[13]);
+
+ /* handshake done */
+ wm->exp.type = EXP_WII_BOARD;
+
+ #ifdef WIN32
+ wm->timeout = WIIMOTE_DEFAULT_TIMEOUT;
+ #endif
+
+ return 1;
+}
+
+
+/**
+ * @brief The wii board disconnected.
+ *
+ * @param cc A pointer to a wii_board_t structure.
+ */
+void wii_board_disconnected(struct wii_board_t* wb) {
+ memset(wb, 0, sizeof(struct wii_board_t));
+}
+
+/**
+ * @brief Handle guitar event.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ * @param msg The message specified in the event packet.
+ */
+void wii_board_event(struct wii_board_t* wb, byte* msg) {
+ short *shmsg = (short*)(msg);
+ wb->rtr = big_to_lil(shmsg[0]);
+ if(wb->rtr<0) wb->rtr = 0;
+ wb->rbr = big_to_lil(shmsg[1]);
+ if(wb->rbr<0) wb->rbr = 0;
+ wb->rtl = big_to_lil(shmsg[2]);
+ if(wb->rtl<0) wb->rtl = 0;
+ wb->rbl = big_to_lil(shmsg[3]);
+ if(wb->rbl<0) wb->rbl = 0;
+
+ /*
+ Interpolate values
+ Calculations borrowed from wiili.org - No names to mention sadly :( http://www.wiili.org/index.php/Wii_Balance_Board_PC_Drivers page however!
+ */
+
+ if(wb->rtrctr[1])
+ {
+ wb->tr = 68*(wb->rtr-wb->ctr[0])/(wb->ctr[1]-wb->ctr[0]);
+ }
+ else if(wb->rtr >= wb->ctr[1])
+ {
+ wb->tr = 68*(wb->rtr-wb->ctr[1])/(wb->ctr[2]-wb->ctr[1]) + 68;
+ }
+
+ if(wb->rtlctl[1])
+ {
+ wb->tl = 68*(wb->rtl-wb->ctl[0])/(wb->ctl[1]-wb->ctl[0]);
+ }
+ else if(wb->rtl >= wb->ctl[1])
+ {
+ wb->tl = 68*(wb->rtl-wb->ctl[1])/(wb->ctl[2]-wb->ctl[1]) + 68;
+ }
+
+ if(wb->rbrcbr[1])
+ {
+ wb->br = 68*(wb->rbr-wb->cbr[0])/(wb->cbr[1]-wb->cbr[0]);
+ }
+ else if(wb->rbr >= wb->cbr[1])
+ {
+ wb->br = 68*(wb->rbr-wb->cbr[1])/(wb->cbr[2]-wb->cbr[1]) + 68;
+ }
+
+ if(wb->rblcbl[1])
+ {
+ wb->bl = 68*(wb->rbl-wb->cbl[0])/(wb->cbl[1]-wb->cbl[0]);
+ }
+ else if(wb->rbl >= wb->cbl[1])
+ {
+ wb->bl = 68*(wb->rbl-wb->cbl[1])/(wb->cbl[2]-wb->cbl[1]) + 68;
+ }
+}
+
+void wiiuse_set_wii_board_calib(struct wiimote_t *wm)
+{
+}
diff --git a/src/wiiboard.h b/src/wiiboard.h
new file mode 100644
index 0000000..eabbcf6
--- /dev/null
+++ b/src/wiiboard.h
@@ -0,0 +1,53 @@
+/*
+ * 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 Guitar Hero 3 expansion device.
+ */
+
+#ifndef WII_BOARD_H_INCLUDED
+#define WII_BOARD_H_INCLUDED
+
+#include "wiiuse_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int wii_board_handshake(struct wiimote_t* wm, struct wii_board_t* wb, byte* data, unsigned short len);
+
+void wii_board_disconnected(struct wii_board_t* wb);
+
+void wii_board_event(struct wii_board_t* wb, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/wiiuse.h b/src/wiiuse.h
index 9dff81c..6543bc9 100644
--- a/src/wiiuse.h
+++ b/src/wiiuse.h
@@ -1,173 +1,174 @@
-/*
- * 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 API header file.
- *
- * If this file is included from inside the wiiuse source
- * and not from a third party program, then wiimote_internal.h
- * is also included which extends this file.
- */
-
-#ifndef WIIUSE_H_INCLUDED
-#define WIIUSE_H_INCLUDED
-
-#ifdef _WIN32
- /* windows */
- #include
-#else
- /* nix */
- #include
-#endif
-
-#ifdef WIIUSE_INTERNAL_H_INCLUDED
- #define WCONST
-#else
- #define WCONST const
-#endif
-
-/* led bit masks */
-#define WIIMOTE_LED_NONE 0x00
-#define WIIMOTE_LED_1 0x10
-#define WIIMOTE_LED_2 0x20
-#define WIIMOTE_LED_3 0x40
-#define WIIMOTE_LED_4 0x80
-
-/* button codes */
-#define WIIMOTE_BUTTON_TWO 0x0001
-#define WIIMOTE_BUTTON_ONE 0x0002
-#define WIIMOTE_BUTTON_B 0x0004
-#define WIIMOTE_BUTTON_A 0x0008
-#define WIIMOTE_BUTTON_MINUS 0x0010
-#define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020
-#define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040
-#define WIIMOTE_BUTTON_HOME 0x0080
-#define WIIMOTE_BUTTON_LEFT 0x0100
-#define WIIMOTE_BUTTON_RIGHT 0x0200
-#define WIIMOTE_BUTTON_DOWN 0x0400
-#define WIIMOTE_BUTTON_UP 0x0800
-#define WIIMOTE_BUTTON_PLUS 0x1000
-#define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000
-#define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000
-#define WIIMOTE_BUTTON_UNKNOWN 0x8000
-#define WIIMOTE_BUTTON_ALL 0x1F9F
-
-/* nunchul button codes */
-#define NUNCHUK_BUTTON_Z 0x01
-#define NUNCHUK_BUTTON_C 0x02
-#define NUNCHUK_BUTTON_ALL 0x03
-
-/* classic controller button codes */
-#define CLASSIC_CTRL_BUTTON_UP 0x0001
-#define CLASSIC_CTRL_BUTTON_LEFT 0x0002
-#define CLASSIC_CTRL_BUTTON_ZR 0x0004
-#define CLASSIC_CTRL_BUTTON_X 0x0008
-#define CLASSIC_CTRL_BUTTON_A 0x0010
-#define CLASSIC_CTRL_BUTTON_Y 0x0020
-#define CLASSIC_CTRL_BUTTON_B 0x0040
-#define CLASSIC_CTRL_BUTTON_ZL 0x0080
-#define CLASSIC_CTRL_BUTTON_FULL_R 0x0200
-#define CLASSIC_CTRL_BUTTON_PLUS 0x0400
-#define CLASSIC_CTRL_BUTTON_HOME 0x0800
-#define CLASSIC_CTRL_BUTTON_MINUS 0x1000
-#define CLASSIC_CTRL_BUTTON_FULL_L 0x2000
-#define CLASSIC_CTRL_BUTTON_DOWN 0x4000
-#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000
-#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF
-
-/* guitar hero 3 button codes */
-#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001
-#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008
-#define GUITAR_HERO_3_BUTTON_GREEN 0x0010
-#define GUITAR_HERO_3_BUTTON_BLUE 0x0020
-#define GUITAR_HERO_3_BUTTON_RED 0x0040
-#define GUITAR_HERO_3_BUTTON_ORANGE 0x0080
-#define GUITAR_HERO_3_BUTTON_PLUS 0x0400
-#define GUITAR_HERO_3_BUTTON_MINUS 0x1000
-#define GUITAR_HERO_3_BUTTON_STRUM_DOWN 0x4000
-#define GUITAR_HERO_3_BUTTON_ALL 0xFEFF
-
-
-/* wiimote option flags */
-#define WIIUSE_SMOOTHING 0x01
-#define WIIUSE_CONTINUOUS 0x02
-#define WIIUSE_ORIENT_THRESH 0x04
-#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH)
-
-#define WIIUSE_ORIENT_PRECISION 100.0f
-
-/* expansion codes */
-#define EXP_NONE 0
-#define EXP_NUNCHUK 1
-#define EXP_CLASSIC 2
-#define EXP_GUITAR_HERO_3 3
-
-/* IR correction types */
-typedef enum ir_position_t {
- WIIUSE_IR_ABOVE,
- WIIUSE_IR_BELOW
-} ir_position_t;
-
-/**
- * @brief Check if a button is pressed.
- * @param dev Pointer to a wiimote_t or expansion structure.
- * @param button The button you are interested in.
- * @return 1 if the button is pressed, 0 if not.
- */
-#define IS_PRESSED(dev, button) ((dev->btns & button) == button)
-
-/**
- * @brief Check if a button is being held.
- * @param dev Pointer to a wiimote_t or expansion structure.
- * @param button The button you are interested in.
- * @return 1 if the button is held, 0 if not.
- */
-#define IS_HELD(dev, button) ((dev->btns_held & button) == button)
-
-/**
- * @brief Check if a button is released on this event. \n\n
- * This does not mean the button is not pressed, it means \n
- * this button was just now released.
- * @param dev Pointer to a wiimote_t or expansion structure.
- * @param button The button you are interested in.
- * @return 1 if the button is released, 0 if not.
- *
- */
-#define IS_RELEASED(dev, button) ((dev->btns_released & button) == button)
-
-/**
- * @brief Check if a button has just been pressed this event.
- * @param dev Pointer to a wiimote_t or expansion structure.
- * @param button The button you are interested in.
- * @return 1 if the button is pressed, 0 if not.
- */
+/*
+ * 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 API header file.
+ *
+ * If this file is included from inside the wiiuse source
+ * and not from a third party program, then wiimote_internal.h
+ * is also included which extends this file.
+ */
+
+#ifndef WIIUSE_H_INCLUDED
+#define WIIUSE_H_INCLUDED
+
+#ifdef _WIN32
+ /* windows */
+ #include
+#else
+ /* nix */
+ #include
+#endif
+
+#ifdef WIIUSE_INTERNAL_H_INCLUDED
+ #define WCONST
+#else
+ #define WCONST const
+#endif
+
+/* led bit masks */
+#define WIIMOTE_LED_NONE 0x00
+#define WIIMOTE_LED_1 0x10
+#define WIIMOTE_LED_2 0x20
+#define WIIMOTE_LED_3 0x40
+#define WIIMOTE_LED_4 0x80
+
+/* button codes */
+#define WIIMOTE_BUTTON_TWO 0x0001
+#define WIIMOTE_BUTTON_ONE 0x0002
+#define WIIMOTE_BUTTON_B 0x0004
+#define WIIMOTE_BUTTON_A 0x0008
+#define WIIMOTE_BUTTON_MINUS 0x0010
+#define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020
+#define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040
+#define WIIMOTE_BUTTON_HOME 0x0080
+#define WIIMOTE_BUTTON_LEFT 0x0100
+#define WIIMOTE_BUTTON_RIGHT 0x0200
+#define WIIMOTE_BUTTON_DOWN 0x0400
+#define WIIMOTE_BUTTON_UP 0x0800
+#define WIIMOTE_BUTTON_PLUS 0x1000
+#define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000
+#define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000
+#define WIIMOTE_BUTTON_UNKNOWN 0x8000
+#define WIIMOTE_BUTTON_ALL 0x1F9F
+
+/* nunchul button codes */
+#define NUNCHUK_BUTTON_Z 0x01
+#define NUNCHUK_BUTTON_C 0x02
+#define NUNCHUK_BUTTON_ALL 0x03
+
+/* classic controller button codes */
+#define CLASSIC_CTRL_BUTTON_UP 0x0001
+#define CLASSIC_CTRL_BUTTON_LEFT 0x0002
+#define CLASSIC_CTRL_BUTTON_ZR 0x0004
+#define CLASSIC_CTRL_BUTTON_X 0x0008
+#define CLASSIC_CTRL_BUTTON_A 0x0010
+#define CLASSIC_CTRL_BUTTON_Y 0x0020
+#define CLASSIC_CTRL_BUTTON_B 0x0040
+#define CLASSIC_CTRL_BUTTON_ZL 0x0080
+#define CLASSIC_CTRL_BUTTON_FULL_R 0x0200
+#define CLASSIC_CTRL_BUTTON_PLUS 0x0400
+#define CLASSIC_CTRL_BUTTON_HOME 0x0800
+#define CLASSIC_CTRL_BUTTON_MINUS 0x1000
+#define CLASSIC_CTRL_BUTTON_FULL_L 0x2000
+#define CLASSIC_CTRL_BUTTON_DOWN 0x4000
+#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000
+#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF
+
+/* guitar hero 3 button codes */
+#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001
+#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008
+#define GUITAR_HERO_3_BUTTON_GREEN 0x0010
+#define GUITAR_HERO_3_BUTTON_BLUE 0x0020
+#define GUITAR_HERO_3_BUTTON_RED 0x0040
+#define GUITAR_HERO_3_BUTTON_ORANGE 0x0080
+#define GUITAR_HERO_3_BUTTON_PLUS 0x0400
+#define GUITAR_HERO_3_BUTTON_MINUS 0x1000
+#define GUITAR_HERO_3_BUTTON_STRUM_DOWN 0x4000
+#define GUITAR_HERO_3_BUTTON_ALL 0xFEFF
+
+
+/* wiimote option flags */
+#define WIIUSE_SMOOTHING 0x01
+#define WIIUSE_CONTINUOUS 0x02
+#define WIIUSE_ORIENT_THRESH 0x04
+#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH)
+
+#define WIIUSE_ORIENT_PRECISION 100.0f
+
+/* expansion codes */
+#define EXP_NONE 0
+#define EXP_NUNCHUK 1
+#define EXP_CLASSIC 2
+#define EXP_GUITAR_HERO_3 3
+#define EXP_WII_BOARD 4
+
+/* IR correction types */
+typedef enum ir_position_t {
+ WIIUSE_IR_ABOVE,
+ WIIUSE_IR_BELOW
+} ir_position_t;
+
+/**
+ * @brief Check if a button is pressed.
+ * @param dev Pointer to a wiimote_t or expansion structure.
+ * @param button The button you are interested in.
+ * @return 1 if the button is pressed, 0 if not.
+ */
+#define IS_PRESSED(dev, button) ((dev->btns & button) == button)
+
+/**
+ * @brief Check if a button is being held.
+ * @param dev Pointer to a wiimote_t or expansion structure.
+ * @param button The button you are interested in.
+ * @return 1 if the button is held, 0 if not.
+ */
+#define IS_HELD(dev, button) ((dev->btns_held & button) == button)
+
+/**
+ * @brief Check if a button is released on this event. \n\n
+ * This does not mean the button is not pressed, it means \n
+ * this button was just now released.
+ * @param dev Pointer to a wiimote_t or expansion structure.
+ * @param button The button you are interested in.
+ * @return 1 if the button is released, 0 if not.
+ *
+ */
+#define IS_RELEASED(dev, button) ((dev->btns_released & button) == button)
+
+/**
+ * @brief Check if a button has just been pressed this event.
+ * @param dev Pointer to a wiimote_t or expansion structure.
+ * @param button The button you are interested in.
+ * @return 1 if the button is pressed, 0 if not.
+ */
#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button))
/**
@@ -185,469 +186,496 @@ typedef enum ir_position_t {
else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \
else *lvl = 0; \
} while (0)
-
-#define WIIUSE_USING_ACC(wm) ((wm->state & 0x020) == 0x020)
-#define WIIUSE_USING_EXP(wm) ((wm->state & 0x040) == 0x040)
-#define WIIUSE_USING_IR(wm) ((wm->state & 0x080) == 0x080)
-#define WIIUSE_USING_SPEAKER(wm) ((wm->state & 0x100) == 0x100)
-
-#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.
- */
-#ifdef WIN32
- #define WIIMOTE_DEFAULT_TIMEOUT 10
- #define WIIMOTE_EXP_TIMEOUT 10
-#endif
-
-typedef unsigned char byte;
-typedef char sbyte;
-
-struct wiimote_t;
-struct vec3b_t;
-struct orient_t;
-struct gforce_t;
-
-
-/**
- * @brief Callback that handles a read event.
- *
- * @param wm Pointer to a wiimote_t structure.
- * @param data Pointer to the filled data block.
- * @param len Length in bytes of the data block.
- *
- * @see wiiuse_init()
- *
- * A registered function of this type is called automatically by the wiiuse
- * library when the wiimote has returned the full data requested by a previous
- * call to wiiuse_read_data().
- */
-typedef void (*wiiuse_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len);
-
-
-/**
- * @struct read_req_t
- * @brief Data read request structure.
- */
-struct read_req_t {
- wiiuse_read_cb cb; /**< read data callback */
- byte* buf; /**< buffer where read data is written */
- unsigned int addr; /**< the offset that the read started at */
- unsigned short size; /**< the length of the data read */
+
+#define WIIUSE_USING_ACC(wm) ((wm->state & 0x020) == 0x020)
+#define WIIUSE_USING_EXP(wm) ((wm->state & 0x040) == 0x040)
+#define WIIUSE_USING_IR(wm) ((wm->state & 0x080) == 0x080)
+#define WIIUSE_USING_SPEAKER(wm) ((wm->state & 0x100) == 0x100)
+
+#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.
+ */
+#ifdef WIN32
+ #define WIIMOTE_DEFAULT_TIMEOUT 10
+ #define WIIMOTE_EXP_TIMEOUT 10
+#endif
+
+typedef unsigned char byte;
+typedef char sbyte;
+
+struct wiimote_t;
+struct vec3b_t;
+struct orient_t;
+struct gforce_t;
+
+
+/**
+ * @brief Callback that handles a read event.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param data Pointer to the filled data block.
+ * @param len Length in bytes of the data block.
+ *
+ * @see wiiuse_init()
+ *
+ * A registered function of this type is called automatically by the wiiuse
+ * library when the wiimote has returned the full data requested by a previous
+ * call to wiiuse_read_data().
+ */
+typedef void (*wiiuse_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len);
+
+
+/**
+ * @struct read_req_t
+ * @brief Data read request structure.
+ */
+struct read_req_t {
+ wiiuse_read_cb cb; /**< read data callback */
+ byte* buf; /**< buffer where read data is written */
+ unsigned int addr; /**< the offset that the read started at */
+ unsigned short size; /**< the length of the data read */
unsigned short wait; /**< num bytes still needed to finish read */
- byte dirty; /**< set to 1 if not using callback and needs to be cleaned up */
-
- struct read_req_t* next; /**< next read request in the queue */
-};
-
-
-/**
- * @struct vec2b_t
- * @brief Unsigned x,y byte vector.
- */
-typedef struct vec2b_t {
- byte x, y;
-} vec2b_t;
-
-
-/**
- * @struct vec3b_t
- * @brief Unsigned x,y,z byte vector.
- */
-typedef struct vec3b_t {
- byte x, y, z;
-} vec3b_t;
-
-
-/**
- * @struct vec3f_t
- * @brief Signed x,y,z float struct.
- */
-typedef struct vec3f_t {
- float x, y, z;
-} vec3f_t;
-
-
-/**
- * @struct orient_t
- * @brief Orientation struct.
- *
- * Yaw, pitch, and roll range from -180 to 180 degrees.
- */
-typedef struct orient_t {
- float roll; /**< roll, this may be smoothed if enabled */
- float pitch; /**< pitch, this may be smoothed if enabled */
- float yaw;
-
- float a_roll; /**< absolute roll, unsmoothed */
- float a_pitch; /**< absolute pitch, unsmoothed */
-} orient_t;
-
-
-/**
- * @struct gforce_t
- * @brief Gravity force struct.
- */
-typedef struct gforce_t {
- float x, y, z;
-} gforce_t;
-
-
-/**
- * @struct accel_t
- * @brief Accelerometer struct. For any device with an accelerometer.
- */
-typedef struct accel_t {
- struct vec3b_t cal_zero; /**< zero calibration */
- struct vec3b_t cal_g; /**< 1g difference around 0cal */
-
- float st_roll; /**< last smoothed roll value */
- float st_pitch; /**< last smoothed roll pitch */
- float st_alpha; /**< alpha value for smoothing [0-1] */
-} accel_t;
-
-
-/**
- * @struct ir_dot_t
- * @brief A single IR source.
- */
-typedef struct ir_dot_t {
- byte visible; /**< if the IR source is visible */
-
- unsigned int x; /**< interpolated X coordinate */
- unsigned int y; /**< interpolated Y coordinate */
-
- short rx; /**< raw X coordinate (0-1023) */
- short ry; /**< raw Y coordinate (0-767) */
-
- byte order; /**< increasing order by x-axis value */
-
- byte size; /**< size of the IR dot (0-15) */
-} ir_dot_t;
-
-
-/**
- * @enum aspect_t
- * @brief Screen aspect ratio.
- */
-typedef enum aspect_t {
- WIIUSE_ASPECT_4_3,
- WIIUSE_ASPECT_16_9
-} aspect_t;
-
-
-/**
- * @struct ir_t
- * @brief IR struct. Hold all data related to the IR tracking.
- */
-typedef struct ir_t {
- struct ir_dot_t dot[4]; /**< IR dots */
- byte num_dots; /**< number of dots at this time */
-
- enum aspect_t aspect; /**< aspect ratio of the screen */
-
- enum ir_position_t pos; /**< IR sensor bar position */
-
- unsigned int vres[2]; /**< IR virtual screen resolution */
- int offset[2]; /**< IR XY correction offset */
- int state; /**< keeps track of the IR state */
-
- int ax; /**< absolute X coordinate */
- int ay; /**< absolute Y coordinate */
-
- int x; /**< calculated X coordinate */
- int y; /**< calculated Y coordinate */
-
- float distance; /**< pixel distance between first 2 dots*/
- float z; /**< calculated distance */
-} ir_t;
-
-
-/**
- * @struct joystick_t
- * @brief Joystick calibration structure.
- *
- * The angle \a ang is relative to the positive y-axis into quadrant I
- * and ranges from 0 to 360 degrees. So if the joystick is held straight
- * upwards then angle is 0 degrees. If it is held to the right it is 90,
- * down is 180, and left is 270.
- *
- * The magnitude \a mag is the distance from the center to where the
- * joystick is being held. The magnitude ranges from 0 to 1.
- * If the joystick is only slightly tilted from the center the magnitude
- * will be low, but if it is closer to the outter edge the value will
- * be higher.
- */
-typedef struct joystick_t {
- struct vec2b_t max; /**< maximum joystick values */
- struct vec2b_t min; /**< minimum joystick values */
- struct vec2b_t center; /**< center joystick values */
-
- float ang; /**< angle the joystick is being held */
- float mag; /**< magnitude of the joystick (range 0-1) */
-} joystick_t;
-
-
-/**
- * @struct nunchuk_t
- * @brief Nunchuk expansion device.
- */
-typedef struct nunchuk_t {
- struct accel_t accel_calib; /**< nunchuk accelerometer calibration */
- struct joystick_t js; /**< joystick calibration */
-
- int* flags; /**< options flag (points to wiimote_t.flags) */
-
- byte btns; /**< what buttons have just been pressed */
- byte btns_held; /**< what buttons are being held down */
- byte btns_released; /**< what buttons were just released this */
+ byte dirty; /**< set to 1 if not using callback and needs to be cleaned up */
+
+ struct read_req_t* next; /**< next read request in the queue */
+};
+
+
+/**
+ * @struct vec2b_t
+ * @brief Unsigned x,y byte vector.
+ */
+typedef struct vec2b_t {
+ byte x, y;
+} vec2b_t;
+
+
+/**
+ * @struct vec3b_t
+ * @brief Unsigned x,y,z byte vector.
+ */
+typedef struct vec3b_t {
+ byte x, y, z;
+} vec3b_t;
+
+
+/**
+ * @struct vec3f_t
+ * @brief Signed x,y,z float struct.
+ */
+typedef struct vec3f_t {
+ float x, y, z;
+} vec3f_t;
+
+
+/**
+ * @struct orient_t
+ * @brief Orientation struct.
+ *
+ * Yaw, pitch, and roll range from -180 to 180 degrees.
+ */
+typedef struct orient_t {
+ float roll; /**< roll, this may be smoothed if enabled */
+ float pitch; /**< pitch, this may be smoothed if enabled */
+ float yaw;
+
+ float a_roll; /**< absolute roll, unsmoothed */
+ float a_pitch; /**< absolute pitch, unsmoothed */
+} orient_t;
+
+
+/**
+ * @struct gforce_t
+ * @brief Gravity force struct.
+ */
+typedef struct gforce_t {
+ float x, y, z;
+} gforce_t;
+
+
+/**
+ * @struct accel_t
+ * @brief Accelerometer struct. For any device with an accelerometer.
+ */
+typedef struct accel_t {
+ struct vec3b_t cal_zero; /**< zero calibration */
+ struct vec3b_t cal_g; /**< 1g difference around 0cal */
+
+ float st_roll; /**< last smoothed roll value */
+ float st_pitch; /**< last smoothed roll pitch */
+ float st_alpha; /**< alpha value for smoothing [0-1] */
+} accel_t;
+
+
+/**
+ * @struct ir_dot_t
+ * @brief A single IR source.
+ */
+typedef struct ir_dot_t {
+ byte visible; /**< if the IR source is visible */
+
+ unsigned int x; /**< interpolated X coordinate */
+ unsigned int y; /**< interpolated Y coordinate */
+
+ short rx; /**< raw X coordinate (0-1023) */
+ short ry; /**< raw Y coordinate (0-767) */
+
+ byte order; /**< increasing order by x-axis value */
+
+ byte size; /**< size of the IR dot (0-15) */
+} ir_dot_t;
+
+
+/**
+ * @enum aspect_t
+ * @brief Screen aspect ratio.
+ */
+typedef enum aspect_t {
+ WIIUSE_ASPECT_4_3,
+ WIIUSE_ASPECT_16_9
+} aspect_t;
+
+
+/**
+ * @struct ir_t
+ * @brief IR struct. Hold all data related to the IR tracking.
+ */
+typedef struct ir_t {
+ struct ir_dot_t dot[4]; /**< IR dots */
+ byte num_dots; /**< number of dots at this time */
+
+ enum aspect_t aspect; /**< aspect ratio of the screen */
+
+ enum ir_position_t pos; /**< IR sensor bar position */
+
+ unsigned int vres[2]; /**< IR virtual screen resolution */
+ int offset[2]; /**< IR XY correction offset */
+ int state; /**< keeps track of the IR state */
+
+ int ax; /**< absolute X coordinate */
+ int ay; /**< absolute Y coordinate */
+
+ int x; /**< calculated X coordinate */
+ int y; /**< calculated Y coordinate */
+
+ float distance; /**< pixel distance between first 2 dots*/
+ float z; /**< calculated distance */
+} ir_t;
+
+
+/**
+ * @struct joystick_t
+ * @brief Joystick calibration structure.
+ *
+ * The angle \a ang is relative to the positive y-axis into quadrant I
+ * and ranges from 0 to 360 degrees. So if the joystick is held straight
+ * upwards then angle is 0 degrees. If it is held to the right it is 90,
+ * down is 180, and left is 270.
+ *
+ * The magnitude \a mag is the distance from the center to where the
+ * joystick is being held. The magnitude ranges from 0 to 1.
+ * If the joystick is only slightly tilted from the center the magnitude
+ * will be low, but if it is closer to the outter edge the value will
+ * be higher.
+ */
+typedef struct joystick_t {
+ struct vec2b_t max; /**< maximum joystick values */
+ struct vec2b_t min; /**< minimum joystick values */
+ struct vec2b_t center; /**< center joystick values */
+
+ float ang; /**< angle the joystick is being held */
+ float mag; /**< magnitude of the joystick (range 0-1) */
+} joystick_t;
+
+
+/**
+ * @struct nunchuk_t
+ * @brief Nunchuk expansion device.
+ */
+typedef struct nunchuk_t {
+ struct accel_t accel_calib; /**< nunchuk accelerometer calibration */
+ struct joystick_t js; /**< joystick calibration */
+
+ int* flags; /**< options flag (points to wiimote_t.flags) */
+
+ byte btns; /**< what buttons have just been pressed */
+ byte btns_held; /**< what buttons are being held down */
+ byte btns_released; /**< what buttons were just released this */
float orient_threshold; /**< threshold for orient to generate an event */
int accel_threshold; /**< threshold for accel to generate an event */
-
- struct vec3b_t accel; /**< current raw acceleration data */
- struct orient_t orient; /**< current orientation on each axis */
- struct gforce_t gforce; /**< current gravity forces on each axis */
-} nunchuk_t;
-
-
-/**
- * @struct classic_ctrl_t
- * @brief Classic controller expansion device.
- */
-typedef struct classic_ctrl_t {
- short btns; /**< what buttons have just been pressed */
- short btns_held; /**< what buttons are being held down */
- short btns_released; /**< what buttons were just released this */
-
- float r_shoulder; /**< right shoulder button (range 0-1) */
- float l_shoulder; /**< left shoulder button (range 0-1) */
-
- struct joystick_t ljs; /**< left joystick calibration */
- struct joystick_t rjs; /**< right joystick calibration */
-} classic_ctrl_t;
-
-
-/**
- * @struct guitar_hero_3_t
- * @brief Guitar Hero 3 expansion device.
- */
-typedef struct guitar_hero_3_t {
- short btns; /**< what buttons have just been pressed */
- short btns_held; /**< what buttons are being held down */
- short btns_released; /**< what buttons were just released this */
-
- float whammy_bar; /**< whammy bar (range 0-1) */
-
- struct joystick_t js; /**< joystick calibration */
-} guitar_hero_3_t;
-
-
-/**
- * @struct expansion_t
- * @brief Generic expansion device plugged into wiimote.
- */
-typedef struct expansion_t {
- int type; /**< type of expansion attached */
-
- union {
- struct nunchuk_t nunchuk;
- struct classic_ctrl_t classic;
- struct guitar_hero_3_t gh3;
- };
-} expansion_t;
-
-
-/**
- * @enum win32_bt_stack_t
- * @brief Available bluetooth stacks for Windows.
- */
-typedef enum win_bt_stack_t {
- WIIUSE_STACK_UNKNOWN,
- WIIUSE_STACK_MS,
- WIIUSE_STACK_BLUESOLEIL
-} win_bt_stack_t;
-
-
-/**
- * @struct wiimote_state_t
- * @brief Significant data from the previous event.
- */
-typedef struct wiimote_state_t {
- /* expansion_t */
- float exp_ljs_ang;
- float exp_rjs_ang;
- float exp_ljs_mag;
- float exp_rjs_mag;
- unsigned short exp_btns;
- struct orient_t exp_orient;
+
+ struct vec3b_t accel; /**< current raw acceleration data */
+ struct orient_t orient; /**< current orientation on each axis */
+ struct gforce_t gforce; /**< current gravity forces on each axis */
+} nunchuk_t;
+
+
+/**
+ * @struct classic_ctrl_t
+ * @brief Classic controller expansion device.
+ */
+typedef struct classic_ctrl_t {
+ short btns; /**< what buttons have just been pressed */
+ short btns_held; /**< what buttons are being held down */
+ short btns_released; /**< what buttons were just released this */
+
+ float r_shoulder; /**< right shoulder button (range 0-1) */
+ float l_shoulder; /**< left shoulder button (range 0-1) */
+
+ struct joystick_t ljs; /**< left joystick calibration */
+ struct joystick_t rjs; /**< right joystick calibration */
+} classic_ctrl_t;
+
+
+/**
+ * @struct guitar_hero_3_t
+ * @brief Guitar Hero 3 expansion device.
+ */
+typedef struct guitar_hero_3_t {
+ short btns; /**< what buttons have just been pressed */
+ short btns_held; /**< what buttons are being held down */
+ short btns_released; /**< what buttons were just released this */
+
+ float whammy_bar; /**< whammy bar (range 0-1) */
+
+ struct joystick_t js; /**< joystick calibration */
+} guitar_hero_3_t;
+
+/*
+ Wii board
+*/
+typedef struct wii_board_t {
+ short tl; /* Interpolated */
+ short tr;
+ short bl;
+ short br; /* End interp */
+ short rtl; /* RAW */
+ short rtr;
+ short rbl;
+ short rbr; /* /RAW */
+ short ltl;
+ short ltr;
+ short lbl;
+ short lbr;
+ short ctl[3]; /* Calibration */
+ short ctr[3];
+ short cbl[3];
+ short cbr[3]; /* /Calibration */
+} wii_board_t;
+
+
+/**
+ * @struct expansion_t
+ * @brief Generic expansion device plugged into wiimote.
+ */
+typedef struct expansion_t {
+ int type; /**< type of expansion attached */
+
+ union {
+ struct nunchuk_t nunchuk;
+ struct classic_ctrl_t classic;
+ struct guitar_hero_3_t gh3;
+ struct wii_board_t wb;
+ };
+} expansion_t;
+
+
+/**
+ * @enum win32_bt_stack_t
+ * @brief Available bluetooth stacks for Windows.
+ */
+typedef enum win_bt_stack_t {
+ WIIUSE_STACK_UNKNOWN,
+ WIIUSE_STACK_MS,
+ WIIUSE_STACK_BLUESOLEIL
+} win_bt_stack_t;
+
+
+/**
+ * @struct wiimote_state_t
+ * @brief Significant data from the previous event.
+ */
+typedef struct wiimote_state_t {
+ /* expansion_t */
+ float exp_ljs_ang;
+ float exp_rjs_ang;
+ float exp_ljs_mag;
+ float exp_rjs_mag;
+ unsigned short exp_btns;
+ struct orient_t exp_orient;
struct vec3b_t exp_accel;
- float exp_r_shoulder;
- float exp_l_shoulder;
-
- /* ir_t */
- int ir_ax;
- int ir_ay;
- float ir_distance;
-
- struct orient_t orient;
- unsigned short btns;
-
- struct vec3b_t accel;
-} wiimote_state_t;
-
-
-/**
- * @enum WIIUSE_EVENT_TYPE
- * @brief Events that wiiuse can generate from a poll.
- */
-typedef enum WIIUSE_EVENT_TYPE {
- WIIUSE_NONE = 0,
- WIIUSE_EVENT,
+ float exp_r_shoulder;
+ float exp_l_shoulder;
+
+ /* ir_t */
+ int ir_ax;
+ int ir_ay;
+ float ir_distance;
+
+ struct orient_t orient;
+ unsigned short btns;
+
+ struct vec3b_t accel;
+} wiimote_state_t;
+
+
+/**
+ * @enum WIIUSE_EVENT_TYPE
+ * @brief Events that wiiuse can generate from a poll.
+ */
+typedef enum WIIUSE_EVENT_TYPE {
+ WIIUSE_NONE = 0,
+ WIIUSE_EVENT,
WIIUSE_STATUS,
- WIIUSE_CONNECT,
+ WIIUSE_CONNECT,
WIIUSE_DISCONNECT,
WIIUSE_UNEXPECTED_DISCONNECT,
WIIUSE_READ_DATA,
- WIIUSE_NUNCHUK_INSERTED,
+ WIIUSE_NUNCHUK_INSERTED,
WIIUSE_NUNCHUK_REMOVED,
WIIUSE_CLASSIC_CTRL_INSERTED,
WIIUSE_CLASSIC_CTRL_REMOVED,
WIIUSE_GUITAR_HERO_3_CTRL_INSERTED,
- WIIUSE_GUITAR_HERO_3_CTRL_REMOVED
-} WIIUSE_EVENT_TYPE;
-
-/**
- * @struct wiimote_t
- * @brief Wiimote structure.
- */
-typedef struct wiimote_t {
- WCONST int unid; /**< user specified id */
-
- #ifndef WIN32
- WCONST bdaddr_t bdaddr; /**< bt address */
- WCONST char bdaddr_str[18]; /**< readable bt address */
- WCONST int out_sock; /**< output socket */
- WCONST int in_sock; /**< input socket */
- #else
- WCONST HANDLE dev_handle; /**< HID handle */
- WCONST OVERLAPPED hid_overlap; /**< overlap handle */
- WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */
- WCONST int timeout; /**< read timeout */
- WCONST byte normal_timeout; /**< normal timeout */
- WCONST byte exp_timeout; /**< timeout for expansion handshake */
- #endif
-
- WCONST int state; /**< various state flags */
- WCONST byte leds; /**< currently lit leds */
- WCONST float battery_level; /**< battery level */
-
+ WIIUSE_GUITAR_HERO_3_CTRL_REMOVED,
+ WIIUSE_WII_BOARD_CTRL_INSERTED,
+ WIIUSE_WII_BOARD_CTRL_REMOVED
+} WIIUSE_EVENT_TYPE;
+
+/**
+ * @struct wiimote_t
+ * @brief Wiimote structure.
+ */
+typedef struct wiimote_t {
+ WCONST int unid; /**< user specified id */
+
+ #ifndef WIN32
+ WCONST bdaddr_t bdaddr; /**< bt address */
+ WCONST char bdaddr_str[18]; /**< readable bt address */
+ WCONST int out_sock; /**< output socket */
+ WCONST int in_sock; /**< input socket */
+ #else
+ WCONST HANDLE dev_handle; /**< HID handle */
+ WCONST OVERLAPPED hid_overlap; /**< overlap handle */
+ WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */
+ WCONST int timeout; /**< read timeout */
+ WCONST byte normal_timeout; /**< normal timeout */
+ WCONST byte exp_timeout; /**< timeout for expansion handshake */
+ #endif
+
+ WCONST int state; /**< various state flags */
+ WCONST byte leds; /**< currently lit leds */
+ WCONST float battery_level; /**< battery level */
+
WCONST int flags; /**< options flag */
- WCONST byte handshake_state; /**< the state of the connection handshake */
-
- WCONST struct read_req_t* read_req; /**< list of data read requests */
- WCONST struct accel_t accel_calib; /**< wiimote accelerometer calibration */
- WCONST struct expansion_t exp; /**< wiimote expansion device */
-
- WCONST struct vec3b_t accel; /**< current raw acceleration data */
- WCONST struct orient_t orient; /**< current orientation on each axis */
- WCONST struct gforce_t gforce; /**< current gravity forces on each axis */
-
- WCONST struct ir_t ir; /**< IR data */
-
- WCONST unsigned short btns; /**< what buttons have just been pressed */
- WCONST unsigned short btns_held; /**< what buttons are being held down */
- WCONST unsigned short btns_released; /**< what buttons were just released this */
-
- WCONST float orient_threshold; /**< threshold for orient to generate an event */
- WCONST int accel_threshold; /**< threshold for accel to generate an event */
-
- WCONST struct wiimote_state_t lstate; /**< last saved state */
-
- WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */
- WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */
-} wiimote;
-
-
-/*****************************************
- *
- * Include API specific stuff
- *
- *****************************************/
-
-#ifdef _WIN32
- #define WIIUSE_EXPORT_DECL __declspec(dllexport)
- #define WIIUSE_IMPORT_DECL __declspec(dllimport)
-#else
- #define WIIUSE_EXPORT_DECL
- #define WIIUSE_IMPORT_DECL
-#endif
-
-#ifdef WIIUSE_COMPILE_LIB
- #define WIIUSE_EXPORT WIIUSE_EXPORT_DECL
-#else
- #define WIIUSE_EXPORT WIIUSE_IMPORT_DECL
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* wiiuse.c */
-WIIUSE_EXPORT extern const char* wiiuse_version();
-
-WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes);
-WIIUSE_EXPORT extern void wiiuse_disconnected(struct wiimote_t* wm);
-WIIUSE_EXPORT extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes);
-WIIUSE_EXPORT extern void wiiuse_rumble(struct wiimote_t* wm, int status);
-WIIUSE_EXPORT extern void wiiuse_toggle_rumble(struct wiimote_t* wm);
-WIIUSE_EXPORT extern void wiiuse_set_leds(struct wiimote_t* wm, int leds);
-WIIUSE_EXPORT extern void wiiuse_motion_sensing(struct wiimote_t* wm, int status);
-WIIUSE_EXPORT extern int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len);
-WIIUSE_EXPORT extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len);
-WIIUSE_EXPORT extern void wiiuse_status(struct wiimote_t* wm);
-WIIUSE_EXPORT extern struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid);
-WIIUSE_EXPORT extern int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable);
-WIIUSE_EXPORT extern float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha);
-WIIUSE_EXPORT extern void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type);
-WIIUSE_EXPORT extern void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold);
-WIIUSE_EXPORT extern void wiiuse_resync(struct wiimote_t* wm);
-WIIUSE_EXPORT extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout);
-WIIUSE_EXPORT extern void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold);
-
-/* connect.c */
-WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout);
-WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes);
-WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm);
-
-/* events.c */
-WIIUSE_EXPORT extern int wiiuse_poll(struct wiimote_t** wm, int wiimotes);
-
-/* ir.c */
-WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status);
-WIIUSE_EXPORT extern void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y);
-WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos);
+ WCONST byte handshake_state; /**< the state of the connection handshake */
+
+ WCONST struct read_req_t* read_req; /**< list of data read requests */
+ WCONST struct accel_t accel_calib; /**< wiimote accelerometer calibration */
+ WCONST struct expansion_t exp; /**< wiimote expansion device */
+
+ WCONST struct vec3b_t accel; /**< current raw acceleration data */
+ WCONST struct orient_t orient; /**< current orientation on each axis */
+ WCONST struct gforce_t gforce; /**< current gravity forces on each axis */
+
+ WCONST struct ir_t ir; /**< IR data */
+
+ WCONST unsigned short btns; /**< what buttons have just been pressed */
+ WCONST unsigned short btns_held; /**< what buttons are being held down */
+ WCONST unsigned short btns_released; /**< what buttons were just released this */
+
+ WCONST float orient_threshold; /**< threshold for orient to generate an event */
+ WCONST int accel_threshold; /**< threshold for accel to generate an event */
+
+ WCONST struct wiimote_state_t lstate; /**< last saved state */
+
+ WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */
+ WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */
+} wiimote;
+
+
+/*****************************************
+ *
+ * Include API specific stuff
+ *
+ *****************************************/
+
+#ifdef _WIN32
+ #define WIIUSE_EXPORT_DECL __declspec(dllexport)
+ #define WIIUSE_IMPORT_DECL __declspec(dllimport)
+#else
+ #define WIIUSE_EXPORT_DECL
+ #define WIIUSE_IMPORT_DECL
+#endif
+
+#ifdef WIIUSE_COMPILE_LIB
+ #define WIIUSE_EXPORT WIIUSE_EXPORT_DECL
+#else
+ #define WIIUSE_EXPORT WIIUSE_IMPORT_DECL
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* wiiuse.c */
+WIIUSE_EXPORT extern const char* wiiuse_version();
+
+WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes);
+WIIUSE_EXPORT extern void wiiuse_disconnected(struct wiimote_t* wm);
+WIIUSE_EXPORT extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes);
+WIIUSE_EXPORT extern void wiiuse_rumble(struct wiimote_t* wm, int status);
+WIIUSE_EXPORT extern void wiiuse_toggle_rumble(struct wiimote_t* wm);
+WIIUSE_EXPORT extern void wiiuse_set_leds(struct wiimote_t* wm, int leds);
+WIIUSE_EXPORT extern void wiiuse_motion_sensing(struct wiimote_t* wm, int status);
+WIIUSE_EXPORT extern int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len);
+WIIUSE_EXPORT extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len);
+WIIUSE_EXPORT extern void wiiuse_status(struct wiimote_t* wm);
+WIIUSE_EXPORT extern struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid);
+WIIUSE_EXPORT extern int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable);
+WIIUSE_EXPORT extern float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha);
+WIIUSE_EXPORT extern void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type);
+WIIUSE_EXPORT extern void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold);
+WIIUSE_EXPORT extern void wiiuse_resync(struct wiimote_t* wm);
+WIIUSE_EXPORT extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout);
+WIIUSE_EXPORT extern void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold);
+
+/* connect.c */
+WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout);
+WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes);
+WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm);
+
+/* events.c */
+WIIUSE_EXPORT extern int wiiuse_poll(struct wiimote_t** wm, int wiimotes);
+
+/* ir.c */
+WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status);
+WIIUSE_EXPORT extern void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y);
+WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos);
WIIUSE_EXPORT extern void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect);
WIIUSE_EXPORT extern void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level);
/* nunchuk.c */
WIIUSE_EXPORT extern void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold);
WIIUSE_EXPORT extern void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* WIIUSE_H_INCLUDED */
-
+
+/* Balance Board */
+WIIUSE_EXPORT extern void wiiuse_set_wii_board_calib(struct wiimote_t *wm);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* WIIUSE_H_INCLUDED */
+
diff --git a/src/wiiuse_internal.h b/src/wiiuse_internal.h
index 1b2f423..86b3f40 100644
--- a/src/wiiuse_internal.h
+++ b/src/wiiuse_internal.h
@@ -150,11 +150,12 @@
/* encrypted expansion id codes (located at 0x04A400FC) */
#define EXP_ID_CODE_NUNCHUK 0x9A1EFEFE
+#define EXP_ID_CODE_WII_BOARD 0xA4200402
#define EXP_ID_CODE_CLASSIC_CONTROLLER 0x9A1EFDFD
#define EXP_ID_CODE_GUITAR 0x9A1EFDFB
-#define EXP_HANDSHAKE_LEN 224
-
+#define EXP_HANDSHAKE_LEN 224
+
/********************
*
* End Wiimote internal codes
@@ -205,10 +206,10 @@
#define WIIUSE_DEFAULT_SMOOTH_ALPHA 0.07f
#define SMOOTH_ROLL 0x01
-#define SMOOTH_PITCH 0x02
-
+#define SMOOTH_PITCH 0x02
+
#include "wiiuse.h"
-
+
#ifdef __cplusplus
extern "C" {
#endif