diff --git a/Externals/WiiUse/Inc/wiiuse.h b/Externals/WiiUse/Inc/wiiuse.h
new file mode 100644
index 0000000000..a70dc9e344
--- /dev/null
+++ b/Externals/WiiUse/Inc/wiiuse.h
@@ -0,0 +1,657 @@
+/*
+ * 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.
+ */
+#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button))
+
+/**
+ * @brief Return the IR sensitivity level.
+ * @param wm Pointer to a wiimote_t structure.
+ * @param lvl [out] Pointer to an int that will hold the level setting.
+ * If no level is set 'lvl' will be set to 0.
+ */
+#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \
+ do { \
+ if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \
+ else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \
+ else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \
+ else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \
+ 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 */
+ 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 */
+
+ 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 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,
+ WIIUSE_STATUS,
+ WIIUSE_CONNECT,
+ WIIUSE_DISCONNECT,
+ WIIUSE_UNEXPECTED_DISCONNECT,
+ WIIUSE_READ_DATA,
+ 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 */
+
+ 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);
+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);
+
+/* io.c */
+WIIUSE_EXPORT extern int wiiuse_io_read(struct wiimote_t* wm);
+WIIUSE_EXPORT extern int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* WIIUSE_H_INCLUDED */
+
diff --git a/Externals/WiiUse/Win32/wiiuse.dll b/Externals/WiiUse/Win32/wiiuse.dll
new file mode 100644
index 0000000000..6b52becf21
Binary files /dev/null and b/Externals/WiiUse/Win32/wiiuse.dll differ
diff --git a/Externals/WiiUse/Win32/wiiuse.lib b/Externals/WiiUse/Win32/wiiuse.lib
new file mode 100644
index 0000000000..bf093f2f25
Binary files /dev/null and b/Externals/WiiUse/Win32/wiiuse.lib differ
diff --git a/Externals/WiiUse/X64/wiiuse.dll b/Externals/WiiUse/X64/wiiuse.dll
new file mode 100644
index 0000000000..24905a297d
Binary files /dev/null and b/Externals/WiiUse/X64/wiiuse.dll differ
diff --git a/Externals/WiiUse/X64/wiiuse.lib b/Externals/WiiUse/X64/wiiuse.lib
new file mode 100644
index 0000000000..f0013849ea
Binary files /dev/null and b/Externals/WiiUse/X64/wiiuse.lib differ
diff --git a/Externals/WiiUseSrc/Src/Makefile b/Externals/WiiUseSrc/Src/Makefile
new file mode 100644
index 0000000000..bab5b140f4
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/Makefile
@@ -0,0 +1,91 @@
+#
+# wiiuse Makefile
+#
+
+#
+# Change this to your GCC version.
+#
+CC = gcc
+
+####################################################
+#
+# You should not need to edit below this line.
+#
+####################################################
+
+#
+# Universal cflags
+#
+CFLAGS = -Wall -pipe -fPIC -funroll-loops
+
+ifeq ($(debug),1)
+ OBJ_PREFIX = debug
+ CFLAGS += -g -pg -DWITH_WIIUSE_DEBUG
+
+else
+ OBJ_PREFIX = release
+ CFLAGS += -O2
+endif
+
+OBJ_DIR = $(OBJ_PREFIX)-$(shell $(CC) -v 2>&1|grep ^Target:|cut -d' ' -f2)
+
+#
+# Linking flags
+#
+LDFLAGS = -shared -lm -lbluetooth
+
+#
+# Target binaries (always created as BIN)
+#
+BIN = ./$(OBJ_DIR)/libwiiuse.so
+
+#
+# Inclusion paths.
+#
+INCLUDES = -I.
+
+#
+# Generate a list of object files
+#
+OBJS = \
+ $(OBJ_DIR)/classic.o \
+ $(OBJ_DIR)/dynamics.o \
+ $(OBJ_DIR)/events.o \
+ $(OBJ_DIR)/io.o \
+ $(OBJ_DIR)/io_nix.o \
+ $(OBJ_DIR)/ir.o \
+ $(OBJ_DIR)/nunchuk.o \
+ $(OBJ_DIR)/guitar_hero_3.o \
+ $(OBJ_DIR)/wiiuse.o
+
+###############################
+#
+# Build targets.
+#
+###############################
+
+all: $(BIN)
+
+clean:
+ @-rm $(OBJS) 2> /dev/null
+
+distclean:
+ @-rm -r debug-* release-* 2> /dev/null
+
+install:
+ @if [ -e $(BIN) ]; then \
+ cp -v $(BIN) /usr/lib ; \
+ fi
+ @cp -v wiiuse.h /usr/include
+
+$(BIN): mkdir $(OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(BIN)
+
+$(OBJ_DIR)/%.o: %.c
+ $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
+
+mkdir:
+ @if [ ! -d $(OBJ_DIR) ]; then \
+ mkdir $(OBJ_DIR); \
+ fi
+
diff --git a/Externals/WiiUseSrc/Src/classic.c b/Externals/WiiUseSrc/Src/classic.c
new file mode 100644
index 0000000000..1d2c3ab275
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/classic.c
@@ -0,0 +1,190 @@
+/*
+ * 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 Classic controller expansion device.
+ */
+
+#include
+#include
+#include
+
+#ifdef WIN32
+ #include
+#endif
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "classic.h"
+
+static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now);
+
+/**
+ * @brief Handle the handshake data from the classic controller.
+ *
+ * @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 classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len) {
+ int i;
+ int offset = 0;
+
+ cc->btns = 0;
+ cc->btns_held = 0;
+ cc->btns_released = 0;
+ cc->r_shoulder = 0;
+ cc->l_shoulder = 0;
+
+ /* decrypt data */
+ for (i = 0; i < len; ++i)
+ data[i] = (data[i] ^ 0x17) + 0x17;
+
+ if (data[offset] == 0xFF) {
+ /*
+ * Sometimes the data returned here is not correct.
+ * This might happen because the wiimote is lagging
+ * behind our initialization sequence.
+ * To fix this just request the handshake again.
+ *
+ * Other times it's just the first 16 bytes are 0xFF,
+ * but since the next 16 bytes are the same, just use
+ * those.
+ */
+ if (data[offset + 16] == 0xFF) {
+ /* get the calibration data */
+ byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+ WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again.");
+ wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+ return 0;
+ } else
+ offset += 16;
+ }
+
+
+ /* joystick stuff */
+ cc->ljs.max.x = data[0 + offset] / 4;
+ cc->ljs.min.x = data[1 + offset] / 4;
+ cc->ljs.center.x = data[2 + offset] / 4;
+ cc->ljs.max.y = data[3 + offset] / 4;
+ cc->ljs.min.y = data[4 + offset] / 4;
+ cc->ljs.center.y = data[5 + offset] / 4;
+
+ cc->rjs.max.x = data[6 + offset] / 8;
+ cc->rjs.min.x = data[7 + offset] / 8;
+ cc->rjs.center.x = data[8 + offset] / 8;
+ cc->rjs.max.y = data[9 + offset] / 8;
+ cc->rjs.min.y = data[10 + offset] / 8;
+ cc->rjs.center.y = data[11 + offset] / 8;
+
+ /* handshake done */
+ wm->exp.type = EXP_CLASSIC;
+
+ #ifdef WIN32
+ wm->timeout = WIIMOTE_DEFAULT_TIMEOUT;
+ #endif
+
+ return 1;
+}
+
+
+/**
+ * @brief The classic controller disconnected.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ */
+void classic_ctrl_disconnected(struct classic_ctrl_t* cc) {
+ memset(cc, 0, sizeof(struct classic_ctrl_t));
+}
+
+
+
+/**
+ * @brief Handle classic controller event.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ * @param msg The message specified in the event packet.
+ */
+void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg) {
+ int i, lx, ly, rx, ry;
+ byte l, r;
+
+ /* decrypt data */
+ for (i = 0; i < 6; ++i)
+ msg[i] = (msg[i] ^ 0x17) + 0x17;
+
+ classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
+
+ /* left/right buttons */
+ l = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5));
+ r = (msg[3] & 0x1F);
+
+ /*
+ * TODO - LR range hardcoded from 0x00 to 0x1F.
+ * This is probably in the calibration somewhere.
+ */
+ cc->r_shoulder = ((float)r / 0x1F);
+ cc->l_shoulder = ((float)l / 0x1F);
+
+ /* calculate joystick orientation */
+ lx = (msg[0] & 0x3F);
+ ly = (msg[1] & 0x3F);
+ rx = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7);
+ ry = (msg[2] & 0x1F);
+
+ calc_joystick_state(&cc->ljs, lx, ly);
+ calc_joystick_state(&cc->rjs, rx, ry);
+}
+
+
+/**
+ * @brief Find what buttons are pressed.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ * @param msg The message byte specified in the event packet.
+ */
+static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) {
+ /* message is inverted (0 is active, 1 is inactive) */
+ now = ~now & CLASSIC_CTRL_BUTTON_ALL;
+
+ /* pressed now & were pressed, then held */
+ cc->btns_held = (now & cc->btns);
+
+ /* were pressed or were held & not pressed now, then released */
+ cc->btns_released = ((cc->btns | cc->btns_held) & ~now);
+
+ /* buttons pressed now */
+ cc->btns = now;
+}
diff --git a/Externals/WiiUseSrc/Src/classic.h b/Externals/WiiUseSrc/Src/classic.h
new file mode 100644
index 0000000000..356f6a458b
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/classic.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 Classic controller expansion device.
+ */
+
+#ifndef CLASSIC_H_INCLUDED
+#define CLASSIC_H_INCLUDED
+
+#include "wiiuse_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, byte* data, unsigned short len);
+
+void classic_ctrl_disconnected(struct classic_ctrl_t* cc);
+
+void classic_ctrl_event(struct classic_ctrl_t* cc, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CLASSIC_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/definitions.h b/Externals/WiiUseSrc/Src/definitions.h
new file mode 100644
index 0000000000..5a8da85def
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/definitions.h
@@ -0,0 +1,79 @@
+/*
+ * 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 General definitions.
+ */
+
+#ifndef DEFINITIONS_H_INCLUDED
+#define DEFINITIONS_H_INCLUDED
+
+/* this is wiiuse - used to distinguish from third party programs using wiiuse.h */
+#include "os.h"
+
+#define WIIMOTE_PI 3.14159265f
+
+//#define WITH_WIIUSE_DEBUG
+
+/* Error output macros */
+#define WIIUSE_ERROR(fmt, ...) fprintf(stderr, "[ERROR] " fmt "\n", ##__VA_ARGS__)
+
+/* Warning output macros */
+#define WIIUSE_WARNING(fmt, ...) fprintf(stderr, "[WARNING] " fmt "\n", ##__VA_ARGS__)
+
+/* Information output macros */
+#define WIIUSE_INFO(fmt, ...) fprintf(stderr, "[INFO] " fmt "\n", ##__VA_ARGS__)
+
+#ifdef WITH_WIIUSE_DEBUG
+ #ifdef WIN32
+ #define WIIUSE_DEBUG(fmt, ...) do { \
+ char* file = __FILE__; \
+ int i = strlen(file) - 1; \
+ for (; i && (file[i] != '\\'); --i); \
+ fprintf(stderr, "[DEBUG] %s:%i: " fmt "\n", file+i+1, __LINE__, ##__VA_ARGS__); \
+ } while (0)
+ #else
+ #define WIIUSE_DEBUG(fmt, ...) fprintf(stderr, "[DEBUG] " __FILE__ ":%i: " fmt "\n", __LINE__, ##__VA_ARGS__)
+ #endif
+#else
+ #define WIIUSE_DEBUG(fmt, ...)
+#endif
+
+/* Convert between radians and degrees */
+#define RAD_TO_DEGREE(r) ((r * 180.0f) / WIIMOTE_PI)
+#define DEGREE_TO_RAD(d) (d * (WIIMOTE_PI / 180.0f))
+
+/* Convert to big endian */
+#define BIG_ENDIAN_LONG(i) (htonl(i))
+#define BIG_ENDIAN_SHORT(i) (htons(i))
+
+#define absf(x) ((x >= 0) ? (x) : (x * -1.0f))
+#define diff_f(x, y) ((x >= y) ? (absf(x - y)) : (absf(y - x)))
+
+#endif // DEFINITIONS_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/dynamics.c b/Externals/WiiUseSrc/Src/dynamics.c
new file mode 100644
index 0000000000..53612a6b90
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/dynamics.c
@@ -0,0 +1,228 @@
+/*
+ * 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 the dynamics of the wiimote.
+ *
+ * The file includes functions that handle the dynamics
+ * of the wiimote. Such dynamics include orientation and
+ * motion sensing.
+ */
+
+#include
+#include
+#include
+
+#ifdef WIN32
+ #include
+#endif
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "ir.h"
+#include "dynamics.h"
+
+/**
+ * @brief Calculate the roll, pitch, yaw.
+ *
+ * @param ac An accelerometer (accel_t) structure.
+ * @param accel [in] Pointer to a vec3b_t structure that holds the raw acceleration data.
+ * @param orient [out] Pointer to a orient_t structure that will hold the orientation data.
+ * @param rorient [out] Pointer to a orient_t structure that will hold the non-smoothed orientation data.
+ * @param smooth If smoothing should be performed on the angles calculated. 1 to enable, 0 to disable.
+ *
+ * Given the raw acceleration data from the accelerometer struct, calculate
+ * the orientation of the device and set it in the \a orient parameter.
+ */
+void calculate_orientation(struct accel_t* ac, struct vec3b_t* accel, struct orient_t* orient, int smooth) {
+ float xg, yg, zg;
+ float x, y, z;
+
+ /*
+ * roll - use atan(z / x) [ ranges from -180 to 180 ]
+ * pitch - use atan(z / y) [ ranges from -180 to 180 ]
+ * yaw - impossible to tell without IR
+ */
+
+ /* yaw - set to 0, IR will take care of it if it's enabled */
+ orient->yaw = 0.0f;
+
+ /* find out how much it has to move to be 1g */
+ xg = (float)ac->cal_g.x;
+ yg = (float)ac->cal_g.y;
+ zg = (float)ac->cal_g.z;
+
+ /* find out how much it actually moved and normalize to +/- 1g */
+ x = ((float)accel->x - (float)ac->cal_zero.x) / xg;
+ y = ((float)accel->y - (float)ac->cal_zero.y) / yg;
+ z = ((float)accel->z - (float)ac->cal_zero.z) / zg;
+
+ /* make sure x,y,z are between -1 and 1 for the tan functions */
+ if (x < -1.0f) x = -1.0f;
+ else if (x > 1.0f) x = 1.0f;
+ if (y < -1.0f) y = -1.0f;
+ else if (y > 1.0f) y = 1.0f;
+ if (z < -1.0f) z = -1.0f;
+ else if (z > 1.0f) z = 1.0f;
+
+ /* if it is over 1g then it is probably accelerating and not reliable */
+ if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x) {
+ /* roll */
+ x = RAD_TO_DEGREE(atan2f(x, z));
+
+ orient->roll = x;
+ orient->a_roll = x;
+ }
+
+ if (abs(accel->y - ac->cal_zero.y) <= ac->cal_g.y) {
+ /* pitch */
+ y = RAD_TO_DEGREE(atan2f(y, z));
+
+ orient->pitch = y;
+ orient->a_pitch = y;
+ }
+
+ /* smooth the angles if enabled */
+ if (smooth) {
+ apply_smoothing(ac, orient, SMOOTH_ROLL);
+ apply_smoothing(ac, orient, SMOOTH_PITCH);
+ }
+}
+
+
+/**
+ * @brief Calculate the gravity forces on each axis.
+ *
+ * @param ac An accelerometer (accel_t) structure.
+ * @param accel [in] Pointer to a vec3b_t structure that holds the raw acceleration data.
+ * @param gforce [out] Pointer to a gforce_t structure that will hold the gravity force data.
+ */
+void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce) {
+ float xg, yg, zg;
+
+ /* find out how much it has to move to be 1g */
+ xg = (float)ac->cal_g.x;
+ yg = (float)ac->cal_g.y;
+ zg = (float)ac->cal_g.z;
+
+ /* find out how much it actually moved and normalize to +/- 1g */
+ gforce->x = ((float)accel->x - (float)ac->cal_zero.x) / xg;
+ gforce->y = ((float)accel->y - (float)ac->cal_zero.y) / yg;
+ gforce->z = ((float)accel->z - (float)ac->cal_zero.z) / zg;
+}
+
+
+/**
+ * @brief Calculate the angle and magnitude of a joystick.
+ *
+ * @param js [out] Pointer to a joystick_t structure.
+ * @param x The raw x-axis value.
+ * @param y The raw y-axis value.
+ */
+void calc_joystick_state(struct joystick_t* js, float x, float y) {
+ float rx, ry, ang;
+
+ /*
+ * Since the joystick center may not be exactly:
+ * (min + max) / 2
+ * Then the range from the min to the center and the center to the max
+ * may be different.
+ * Because of this, depending on if the current x or y value is greater
+ * or less than the assoicated axis center value, it needs to be interpolated
+ * between the center and the minimum or maxmimum rather than between
+ * the minimum and maximum.
+ *
+ * So we have something like this:
+ * (x min) [-1] ---------*------ [0] (x center) [0] -------- [1] (x max)
+ * Where the * is the current x value.
+ * The range is therefore -1 to 1, 0 being the exact center rather than
+ * the middle of min and max.
+ */
+ if (x == js->center.x)
+ rx = 0;
+ else if (x >= js->center.x)
+ rx = ((float)(x - js->center.x) / (float)(js->max.x - js->center.x));
+ else
+ rx = ((float)(x - js->min.x) / (float)(js->center.x - js->min.x)) - 1.0f;
+
+ if (y == js->center.y)
+ ry = 0;
+ else if (y >= js->center.y)
+ ry = ((float)(y - js->center.y) / (float)(js->max.y - js->center.y));
+ else
+ ry = ((float)(y - js->min.y) / (float)(js->center.y - js->min.y)) - 1.0f;
+
+ /* calculate the joystick angle and magnitude */
+ ang = RAD_TO_DEGREE(atanf(ry / rx));
+ ang -= 90.0f;
+ if (rx < 0.0f)
+ ang -= 180.0f;
+ js->ang = absf(ang);
+ js->mag = (float) sqrt((rx * rx) + (ry * ry));
+}
+
+
+void apply_smoothing(struct accel_t* ac, struct orient_t* orient, int type) {
+ switch (type) {
+ case SMOOTH_ROLL:
+ {
+ /* it's possible last iteration was nan or inf, so set it to 0 if that happened */
+ if (isnan(ac->st_roll) || isinf(ac->st_roll))
+ ac->st_roll = 0.0f;
+
+ /*
+ * If the sign changes (which will happen if going from -180 to 180)
+ * or from (-1 to 1) then don't smooth, just use the new angle.
+ */
+ if (((ac->st_roll < 0) && (orient->roll > 0)) || ((ac->st_roll > 0) && (orient->roll < 0))) {
+ ac->st_roll = orient->roll;
+ } else {
+ orient->roll = ac->st_roll + (ac->st_alpha * (orient->a_roll - ac->st_roll));
+ ac->st_roll = orient->roll;
+ }
+
+ return;
+ }
+
+ case SMOOTH_PITCH:
+ {
+ if (isnan(ac->st_pitch) || isinf(ac->st_pitch))
+ ac->st_pitch = 0.0f;
+
+ if (((ac->st_pitch < 0) && (orient->pitch > 0)) || ((ac->st_pitch > 0) && (orient->pitch < 0))) {
+ ac->st_pitch = orient->pitch;
+ } else {
+ orient->pitch = ac->st_pitch + (ac->st_alpha * (orient->a_pitch - ac->st_pitch));
+ ac->st_pitch = orient->pitch;
+ }
+
+ return;
+ }
+ }
+}
diff --git a/Externals/WiiUseSrc/Src/dynamics.h b/Externals/WiiUseSrc/Src/dynamics.h
new file mode 100644
index 0000000000..2a8f96500b
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/dynamics.h
@@ -0,0 +1,56 @@
+/*
+ * 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 the dynamics of the wiimote.
+ *
+ * The file includes functions that handle the dynamics
+ * of the wiimote. Such dynamics include orientation and
+ * motion sensing.
+ */
+
+#ifndef DYNAMICS_H_INCLUDED
+#define DYNAMICS_H_INCLUDED
+
+#include "wiiuse_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void calculate_orientation(struct accel_t* ac, struct vec3b_t* accel, struct orient_t* orient, int smooth);
+void calculate_gforce(struct accel_t* ac, struct vec3b_t* accel, struct gforce_t* gforce);
+void calc_joystick_state(struct joystick_t* js, float x, float y);
+void apply_smoothing(struct accel_t* ac, struct orient_t* orient, int type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DYNAMICS_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/events.c b/Externals/WiiUseSrc/Src/events.c
new file mode 100644
index 0000000000..6668eda5c8
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/events.c
@@ -0,0 +1,878 @@
+/*
+ * 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
+ #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);
+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 */
+ memset(wm[i]->event_buf, 0, sizeof(wm[i]->event_buf));
+
+ /* clear out any old read requests */
+ clear_dirty_reads(wm[i]);
+
+ /* read the pending message into the buffer */
+ r = read(wm[i]->in_sock, wm[i]->event_buf, sizeof(wm[i]->event_buf));
+ if (r == -1) {
+ /* error reading data */
+ WIIUSE_ERROR("Receiving wiimote data (id %i).", wm[i]->unid);
+ perror("Error Details");
+
+ if (errno == ENOTCONN) {
+ /* this can happen if the bluetooth dongle is disconnected */
+ WIIUSE_ERROR("Bluetooth appears to be disconnected. Wiimote unid %i will be disconnected.", wm[i]->unid);
+ wiiuse_disconnect(wm[i]);
+ 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);
+ }
+
+ /* clear out any old read requests */
+ clear_dirty_reads(wm);
+}
+
+
+/**
+ * @brief Clear out all old 'dirty' read requests.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+static void clear_dirty_reads(struct wiimote_t* wm) {
+ struct read_req_t* req = wm->read_req;
+
+ while (req && req->dirty) {
+ WIIUSE_DEBUG("Cleared old read request for address: %x", req->addr);
+
+ wm->read_req = req->next;
+ 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);
+
+ /* 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 (!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;
+ free(req);
+ } else {
+ /*
+ * This should generate an event.
+ * We need to leave the event in the array so the client
+ * can access it still. We'll flag is as being 'dirty'
+ * and give the client one cycle to use it. Next event
+ * we will remove it from the list.
+ */
+ 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 (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;
+}
diff --git a/Externals/WiiUseSrc/Src/events.h b/Externals/WiiUseSrc/Src/events.h
new file mode 100644
index 0000000000..5e9b955c55
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/events.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef EVENTS_H_INCLUDED
+#define EVENTS_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void wiiuse_pressed_buttons(struct wiimote_t* wm, byte* msg);
+
+void handshake_expansion(struct wiimote_t* wm, byte* data, unsigned short len);
+void disable_expansion(struct wiimote_t* wm);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // EVENTS_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/guitar_hero_3.c b/Externals/WiiUseSrc/Src/guitar_hero_3.c
new file mode 100644
index 0000000000..5837dc016f
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/guitar_hero_3.c
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+#include
+#include
+#include
+
+#ifdef WIN32
+ #include
+#endif
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "guitar_hero_3.h"
+
+static void guitar_hero_3_pressed_buttons(struct guitar_hero_3_t* gh3, short now);
+
+/**
+ * @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 guitar_hero_3_handshake(struct wiimote_t* wm, struct guitar_hero_3_t* gh3, byte* data, unsigned short len) {
+ int i;
+ int offset = 0;
+
+ /*
+ * The good fellows that made the Guitar Hero 3 controller
+ * failed to factory calibrate the devices. There is no
+ * calibration data on the device.
+ */
+
+ gh3->btns = 0;
+ gh3->btns_held = 0;
+ gh3->btns_released = 0;
+ gh3->whammy_bar = 0.0f;
+
+ /* decrypt data */
+ for (i = 0; i < len; ++i)
+ data[i] = (data[i] ^ 0x17) + 0x17;
+
+ if (data[offset] == 0xFF) {
+ /*
+ * Sometimes the data returned here is not correct.
+ * This might happen because the wiimote is lagging
+ * behind our initialization sequence.
+ * To fix this just request the handshake again.
+ *
+ * Other times it's just the first 16 bytes are 0xFF,
+ * but since the next 16 bytes are the same, just use
+ * those.
+ */
+ if (data[offset + 16] == 0xFF) {
+ /* get the calibration data */
+ byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+ WIIUSE_DEBUG("Guitar Hero 3 handshake appears invalid, trying again.");
+ wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+ return 0;
+ } else
+ offset += 16;
+ }
+
+ /* joystick stuff */
+ gh3->js.max.x = GUITAR_HERO_3_JS_MAX_X;
+ gh3->js.min.x = GUITAR_HERO_3_JS_MIN_X;
+ gh3->js.center.x = GUITAR_HERO_3_JS_CENTER_X;
+ gh3->js.max.y = GUITAR_HERO_3_JS_MAX_Y;
+ gh3->js.min.y = GUITAR_HERO_3_JS_MIN_Y;
+ gh3->js.center.y = GUITAR_HERO_3_JS_CENTER_Y;
+
+ /* handshake done */
+ wm->exp.type = EXP_GUITAR_HERO_3;
+
+ #ifdef WIN32
+ wm->timeout = WIIMOTE_DEFAULT_TIMEOUT;
+ #endif
+
+ return 1;
+}
+
+
+/**
+ * @brief The guitar disconnected.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ */
+void guitar_hero_3_disconnected(struct guitar_hero_3_t* gh3) {
+ memset(gh3, 0, sizeof(struct guitar_hero_3_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 guitar_hero_3_event(struct guitar_hero_3_t* gh3, byte* msg) {
+ int i;
+
+ /* decrypt data */
+ for (i = 0; i < 6; ++i)
+ msg[i] = (msg[i] ^ 0x17) + 0x17;
+
+ guitar_hero_3_pressed_buttons(gh3, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
+
+ /* whammy bar */
+ gh3->whammy_bar = (msg[3] - GUITAR_HERO_3_WHAMMY_BAR_MIN) / (float)(GUITAR_HERO_3_WHAMMY_BAR_MAX - GUITAR_HERO_3_WHAMMY_BAR_MIN);
+
+ /* joy stick */
+ calc_joystick_state(&gh3->js, msg[0], msg[1]);
+}
+
+
+/**
+ * @brief Find what buttons are pressed.
+ *
+ * @param cc A pointer to a classic_ctrl_t structure.
+ * @param msg The message byte specified in the event packet.
+ */
+static void guitar_hero_3_pressed_buttons(struct guitar_hero_3_t* gh3, short now) {
+ /* message is inverted (0 is active, 1 is inactive) */
+ now = ~now & GUITAR_HERO_3_BUTTON_ALL;
+
+ /* pressed now & were pressed, then held */
+ gh3->btns_held = (now & gh3->btns);
+
+ /* were pressed or were held & not pressed now, then released */
+ gh3->btns_released = ((gh3->btns | gh3->btns_held) & ~now);
+
+ /* buttons pressed now */
+ gh3->btns = now;
+}
diff --git a/Externals/WiiUseSrc/Src/guitar_hero_3.h b/Externals/WiiUseSrc/Src/guitar_hero_3.h
new file mode 100644
index 0000000000..024d603177
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/guitar_hero_3.h
@@ -0,0 +1,62 @@
+/*
+ * 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 GUITAR_HERO_3_H_INCLUDED
+#define GUITAR_HERO_3_H_INCLUDED
+
+#include "wiiuse_internal.h"
+
+#define GUITAR_HERO_3_JS_MIN_X 0xC5
+#define GUITAR_HERO_3_JS_MAX_X 0xFC
+#define GUITAR_HERO_3_JS_CENTER_X 0xE0
+#define GUITAR_HERO_3_JS_MIN_Y 0xC5
+#define GUITAR_HERO_3_JS_MAX_Y 0xFA
+#define GUITAR_HERO_3_JS_CENTER_Y 0xE0
+#define GUITAR_HERO_3_WHAMMY_BAR_MIN 0xEF
+#define GUITAR_HERO_3_WHAMMY_BAR_MAX 0xFA
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int guitar_hero_3_handshake(struct wiimote_t* wm, struct guitar_hero_3_t* gh3, byte* data, unsigned short len);
+
+void guitar_hero_3_disconnected(struct guitar_hero_3_t* gh3);
+
+void guitar_hero_3_event(struct guitar_hero_3_t* gh3, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GUITAR_HERO_3_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/io.c b/Externals/WiiUseSrc/Src/io.c
new file mode 100644
index 0000000000..ae420b9ef3
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/io.c
@@ -0,0 +1,119 @@
+/*
+ * 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 device I/O (non-OS specific).
+ */
+
+#include
+#include
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "io.h"
+
+
+ /**
+ * @brief Get initialization data from the wiimote.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param data unused
+ * @param len unused
+ *
+ * When first called for a wiimote_t structure, a request
+ * is sent to the wiimote for initialization information.
+ * This includes factory set accelerometer data.
+ * The handshake will be concluded when the wiimote responds
+ * with this data.
+ */
+void wiiuse_handshake(struct wiimote_t* wm, byte* data, unsigned short len) {
+ if (!wm) return;
+
+ switch (wm->handshake_state) {
+ case 0:
+ {
+ /* send request to wiimote for accelerometer calibration */
+ byte* buf;
+
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+ wiiuse_set_leds(wm, WIIMOTE_LED_NONE);
+
+ buf = (byte*)malloc(sizeof(byte) * 8);
+ wiiuse_read_data_cb(wm, wiiuse_handshake, buf, WM_MEM_OFFSET_CALIBRATION, 7);
+ wm->handshake_state++;
+
+ wiiuse_set_leds(wm, WIIMOTE_LED_NONE);
+
+ break;
+ }
+ case 1:
+ {
+ struct read_req_t* req = wm->read_req;
+ struct accel_t* accel = &wm->accel_calib;
+
+ /* received read data */
+ accel->cal_zero.x = req->buf[0];
+ accel->cal_zero.y = req->buf[1];
+ accel->cal_zero.z = req->buf[2];
+
+ accel->cal_g.x = req->buf[4] - accel->cal_zero.x;
+ accel->cal_g.y = req->buf[5] - accel->cal_zero.y;
+ accel->cal_g.z = req->buf[6] - accel->cal_zero.z;
+
+ /* done with the buffer */
+ free(req->buf);
+
+ /* handshake is done */
+ WIIUSE_DEBUG("Handshake finished. Calibration: Idle: X=%x Y=%x Z=%x\t+1g: X=%x Y=%x Z=%x",
+ accel->cal_zero.x, accel->cal_zero.y, accel->cal_zero.z,
+ accel->cal_g.x, accel->cal_g.y, accel->cal_g.z);
+
+
+ /* request the status of the wiimote to see if there is an expansion */
+ wiiuse_status(wm);
+
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE);
+ wm->handshake_state++;
+
+ /* now enable IR if it was set before the handshake completed */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) {
+ WIIUSE_DEBUG("Handshake finished, enabling IR.");
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
+ wiiuse_set_ir(wm, 1);
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
diff --git a/Externals/WiiUseSrc/Src/io.h b/Externals/WiiUseSrc/Src/io.h
new file mode 100644
index 0000000000..7a683e4ee5
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/io.h
@@ -0,0 +1,56 @@
+/*
+ * 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 device I/O.
+ */
+
+#ifndef CONNECT_H_INCLUDED
+#define CONNECT_H_INCLUDED
+
+#ifndef WIN32
+ #include
+#endif
+
+#include "wiiuse_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void wiiuse_handshake(struct wiimote_t* wm, byte* data, unsigned short len);
+
+int wiiuse_io_read(struct wiimote_t* wm);
+int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CONNECT_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/io_nix.c b/Externals/WiiUseSrc/Src/io_nix.c
new file mode 100644
index 0000000000..ec4e0e1780
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/io_nix.c
@@ -0,0 +1,270 @@
+/*
+ * 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 device I/O for *nix.
+ */
+
+#ifndef WIN32
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "io.h"
+
+static int wiiuse_connect_single(struct wiimote_t* wm, char* address);
+
+/**
+ * @brief Find a wiimote or wiimotes.
+ *
+ * @param wm An array of wiimote_t structures.
+ * @param max_wiimotes The number of wiimote structures in \a wm.
+ * @param timeout The number of seconds before the search times out.
+ *
+ * @return The number of wiimotes found.
+ *
+ * @see wiimote_connect()
+ *
+ * This function will only look for wiimote devices. \n
+ * When a device is found the address in the structures will be set. \n
+ * You can then call wiimote_connect() to connect to the found \n
+ * devices.
+ */
+int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
+ int device_id;
+ int device_sock;
+ int found_devices;
+ int found_wiimotes;
+
+ /* reset all wiimote bluetooth device addresses */
+ for (found_wiimotes = 0; found_wiimotes < max_wiimotes; ++found_wiimotes)
+ wm[found_wiimotes]->bdaddr = *BDADDR_ANY;
+ found_wiimotes = 0;
+
+ /* get the id of the first bluetooth device. */
+ device_id = hci_get_route(NULL);
+ if (device_id < 0) {
+ perror("hci_get_route");
+ return 0;
+ }
+
+ /* create a socket to the device */
+ device_sock = hci_open_dev(device_id);
+ if (device_sock < 0) {
+ perror("hci_open_dev");
+ return 0;
+ }
+
+ inquiry_info scan_info_arr[128];
+ inquiry_info* scan_info = scan_info_arr;
+ memset(&scan_info_arr, 0, sizeof(scan_info_arr));
+
+ /* scan for bluetooth devices for 'timeout' seconds */
+ found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH);
+ if (found_devices < 0) {
+ perror("hci_inquiry");
+ return 0;
+ }
+
+ WIIUSE_INFO("Found %i bluetooth device(s).", found_devices);
+
+ int i = 0;
+
+ /* display discovered devices */
+ for (; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) {
+ if ((scan_info[i].dev_class[0] == WM_DEV_CLASS_0) &&
+ (scan_info[i].dev_class[1] == WM_DEV_CLASS_1) &&
+ (scan_info[i].dev_class[2] == WM_DEV_CLASS_2))
+ {
+ /* found a device */
+ ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str);
+
+ WIIUSE_INFO("Found wiimote (%s) [id %i].", wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid);
+
+ wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr;
+ WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND);
+ ++found_wiimotes;
+ }
+ }
+
+ close(device_sock);
+ return found_wiimotes;
+}
+
+
+/**
+ * @brief Connect to a wiimote or wiimotes once an address is known.
+ *
+ * @param wm An array of wiimote_t structures.
+ * @param wiimotes The number of wiimote structures in \a wm.
+ *
+ * @return The number of wiimotes that successfully connected.
+ *
+ * @see wiiuse_find()
+ * @see wiiuse_connect_single()
+ * @see wiiuse_disconnect()
+ *
+ * Connect to a number of wiimotes when the address is already set
+ * in the wiimote_t structures. These addresses are normally set
+ * by the wiiuse_find() function, but can also be set manually.
+ */
+int wiiuse_connect(struct wiimote_t** wm, int wiimotes) {
+ int connected = 0;
+ int i = 0;
+
+ for (; i < wiimotes; ++i) {
+ if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND))
+ /* if the device address is not set, skip it */
+ continue;
+
+ if (wiiuse_connect_single(wm[i], NULL))
+ ++connected;
+ }
+
+ return connected;
+}
+
+
+/**
+ * @brief Connect to a wiimote with a known address.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param address The address of the device to connect to.
+ * If NULL, use the address in the struct set by wiiuse_find().
+ *
+ * @return 1 on success, 0 on failure
+ */
+static int wiiuse_connect_single(struct wiimote_t* wm, char* address) {
+ struct sockaddr_l2 addr;
+
+ if (!wm || WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+
+ addr.l2_family = AF_BLUETOOTH;
+
+ if (address)
+ /* use provided address */
+ str2ba(address, &addr.l2_bdaddr);
+ else
+ /* use address of device discovered */
+ addr.l2_bdaddr = wm->bdaddr;
+
+ /*
+ * OUTPUT CHANNEL
+ */
+ wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+ if (wm->out_sock == -1)
+ return 0;
+
+ addr.l2_psm = htobs(WM_OUTPUT_CHANNEL);
+
+ /* connect to wiimote */
+ if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ perror("connect() output sock");
+ return 0;
+ }
+
+ /*
+ * INPUT CHANNEL
+ */
+ wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+ if (wm->in_sock == -1) {
+ close(wm->out_sock);
+ wm->out_sock = -1;
+ return 0;
+ }
+
+ addr.l2_psm = htobs(WM_INPUT_CHANNEL);
+
+ /* connect to wiimote */
+ if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ perror("connect() interrupt sock");
+ close(wm->out_sock);
+ wm->out_sock = -1;
+ return 0;
+ }
+
+ WIIUSE_INFO("Connected to wiimote [id %i].", wm->unid);
+
+ /* do the handshake */
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+ wiiuse_handshake(wm, NULL, 0);
+
+ wiiuse_set_report_type(wm);
+
+ return 1;
+}
+
+
+/**
+ * @brief Disconnect a wiimote.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ *
+ * @see wiiuse_connect()
+ *
+ * Note that this will not free the wiimote structure.
+ */
+void wiiuse_disconnect(struct wiimote_t* wm) {
+ if (!wm || WIIMOTE_IS_CONNECTED(wm))
+ return;
+
+ close(wm->out_sock);
+ close(wm->in_sock);
+
+ wm->out_sock = -1;
+ wm->in_sock = -1;
+ wm->event = WIIUSE_NONE;
+
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+}
+
+
+int wiiuse_io_read(struct wiimote_t* wm) {
+ /* not used */
+ return 0;
+}
+
+
+int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) {
+ return write(wm->out_sock, buf, len);
+}
+
+
+
+#endif /* ifndef WIN32 */
diff --git a/Externals/WiiUseSrc/Src/io_win.c b/Externals/WiiUseSrc/Src/io_win.c
new file mode 100644
index 0000000000..17fac360d3
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/io_win.c
@@ -0,0 +1,247 @@
+/*
+ * 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 device I/O for Windows.
+ */
+
+#ifdef WIN32
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "io.h"
+
+
+int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout) {
+ GUID device_id;
+ HANDLE dev;
+ HDEVINFO device_info;
+ int i, index;
+ DWORD len;
+ SP_DEVICE_INTERFACE_DATA device_data;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL;
+ HIDD_ATTRIBUTES attr;
+ int found = 0;
+
+ (void) timeout; // unused
+
+ device_data.cbSize = sizeof(device_data);
+ index = 0;
+
+ /* get the device id */
+ HidD_GetHidGuid(&device_id);
+
+ /* get all hid devices connected */
+ device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));
+
+ for (;; ++index) {
+
+ if (detail_data) {
+ free(detail_data);
+ detail_data = NULL;
+ }
+
+ /* query the next hid device info */
+ if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data))
+ break;
+
+ /* get the size of the data block required */
+ i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL);
+ detail_data = malloc(len);
+ detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+ /* query the data for this device */
+ if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL))
+ continue;
+
+ /* open the device */
+ dev = CreateFile(detail_data->DevicePath,
+ (GENERIC_READ | GENERIC_WRITE),
+ (FILE_SHARE_READ | FILE_SHARE_WRITE),
+ NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (dev == INVALID_HANDLE_VALUE)
+ continue;
+
+ /* get device attributes */
+ attr.Size = sizeof(attr);
+ i = HidD_GetAttributes(dev, &attr);
+
+ if ((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) {
+ /* this is a wiimote */
+ wm[found]->dev_handle = dev;
+
+ wm[found]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, "");
+ wm[found]->hid_overlap.Offset = 0;
+ wm[found]->hid_overlap.OffsetHigh = 0;
+
+ WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_DEV_FOUND);
+ WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);
+
+ /* try to set the output report to see if the device is actually connected */
+ if (!wiiuse_set_report_type(wm[found])) {
+ WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED);
+ continue;
+ }
+
+ /* do the handshake */
+ wiiuse_handshake(wm[found], NULL, 0);
+
+ WIIUSE_INFO("Connected to wiimote [id %i].", wm[found]->unid);
+
+ ++found;
+ if (found >= max_wiimotes)
+ break;
+ } else {
+ /* not a wiimote */
+ CloseHandle(dev);
+ }
+ }
+
+ if (detail_data)
+ free(detail_data);
+
+ SetupDiDestroyDeviceInfoList(device_info);
+
+ return found;
+}
+
+
+int wiiuse_connect(struct wiimote_t** wm, int wiimotes) {
+ int connected = 0;
+ int i = 0;
+
+ for (; i < wiimotes; ++i) {
+ if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED))
+ ++connected;
+ }
+
+ return connected;
+}
+
+
+void wiiuse_disconnect(struct wiimote_t* wm) {
+ if (!wm || WIIMOTE_IS_CONNECTED(wm))
+ return;
+
+ CloseHandle(wm->dev_handle);
+ wm->dev_handle = 0;
+
+ ResetEvent(&wm->hid_overlap);
+
+ wm->event = WIIUSE_NONE;
+
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE);
+}
+
+
+int wiiuse_io_read(struct wiimote_t* wm) {
+ DWORD b, r;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+
+ if (!ReadFile(wm->dev_handle, wm->event_buf, sizeof(wm->event_buf), &b, &wm->hid_overlap)) {
+ /* partial read */
+ b = GetLastError();
+
+ if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) {
+ /* remote disconnect */
+ wiiuse_disconnected(wm);
+ return 0;
+ }
+
+ r = WaitForSingleObject(wm->hid_overlap.hEvent, wm->timeout);
+ if (r == WAIT_TIMEOUT) {
+ /* timeout - cancel and continue */
+
+ if (*wm->event_buf)
+ WIIUSE_WARNING("Packet ignored. This may indicate a problem (timeout is %i ms).", wm->timeout);
+
+ CancelIo(wm->dev_handle);
+ ResetEvent(wm->hid_overlap.hEvent);
+ return 0;
+ } else if (r == WAIT_FAILED) {
+ WIIUSE_WARNING("A wait error occured on reading from wiimote %i.", wm->unid);
+ return 0;
+ }
+
+ if (!GetOverlappedResult(wm->dev_handle, &wm->hid_overlap, &b, 0))
+ return 0;
+ }
+
+ ResetEvent(wm->hid_overlap.hEvent);
+ return 1;
+}
+
+
+int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) {
+ DWORD bytes;
+ int i;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+
+ switch (wm->stack) {
+ case WIIUSE_STACK_UNKNOWN:
+ {
+ /* try to auto-detect the stack type */
+ if (i = WriteFile(wm->dev_handle, buf, 22, &bytes, &wm->hid_overlap)) {
+ /* bluesoleil will always return 1 here, even if it's not connected */
+ wm->stack = WIIUSE_STACK_BLUESOLEIL;
+ return i;
+ }
+
+ if (i = HidD_SetOutputReport(wm->dev_handle, buf, len)) {
+ wm->stack = WIIUSE_STACK_MS;
+ return i;
+ }
+
+ WIIUSE_ERROR("Unable to determine bluetooth stack type.");
+ return 0;
+ }
+
+ case WIIUSE_STACK_MS:
+ return HidD_SetOutputReport(wm->dev_handle, buf, len);
+
+ case WIIUSE_STACK_BLUESOLEIL:
+ return WriteFile(wm->dev_handle, buf, 22, &bytes, &wm->hid_overlap);
+ }
+
+ return 0;
+}
+
+#endif /* ifdef WIN32 */
diff --git a/Externals/WiiUseSrc/Src/ir.c b/Externals/WiiUseSrc/Src/ir.c
new file mode 100644
index 0000000000..7a9bb68289
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/ir.c
@@ -0,0 +1,748 @@
+/*
+ * 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 IR data.
+ */
+
+#include
+#include
+
+#ifndef WIN32
+ #include
+#endif
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "ir.h"
+
+static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2);
+static void interpret_ir_data(struct wiimote_t* wm);
+static void fix_rotated_ir_dots(struct ir_dot_t* dot, float ang);
+static void get_ir_dot_avg(struct ir_dot_t* dot, int* x, int* y);
+static void reorder_ir_dots(struct ir_dot_t* dot);
+static float ir_distance(struct ir_dot_t* dot);
+static int ir_correct_for_bounds(int* x, int* y, enum aspect_t aspect, int offset_x, int offset_y);
+static void ir_convert_to_vres(int* x, int* y, enum aspect_t aspect, int vx, int vy);
+
+
+/**
+ * @brief Set if the wiimote should track IR targets.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param status 1 to enable, 0 to disable.
+ */
+void wiiuse_set_ir(struct wiimote_t* wm, int status) {
+ byte buf;
+ char* block1 = NULL;
+ char* block2 = NULL;
+ int ir_level;
+
+ if (!wm)
+ return;
+
+ /*
+ * Wait for the handshake to finish first.
+ * When it handshake finishes and sees that
+ * IR is enabled, it will call this function
+ * again to actually enable IR.
+ */
+ if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_HANDSHAKE_COMPLETE)) {
+ WIIUSE_DEBUG("Tried to enable IR, will wait until handshake finishes.");
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
+ return;
+ }
+
+ /*
+ * Check to make sure a sensitivity setting is selected.
+ */
+ ir_level = get_ir_sens(wm, &block1, &block2);
+ if (!ir_level) {
+ WIIUSE_ERROR("No IR sensitivity setting selected.");
+ return;
+ }
+
+ if (status) {
+ /* if already enabled then stop */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
+ return;
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR);
+ } else {
+ /* if already disabled then stop */
+ if (!WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
+ return;
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_IR);
+ }
+
+ /* set camera 1 and 2 */
+ buf = (status ? 0x04 : 0x00);
+ wiiuse_send(wm, WM_CMD_IR, &buf, 1);
+ wiiuse_send(wm, WM_CMD_IR_2, &buf, 1);
+
+ if (!status) {
+ WIIUSE_DEBUG("Disabled IR cameras for wiimote id %i.", wm->unid);
+ wiiuse_set_report_type(wm);
+ return;
+ }
+
+ /* enable IR, set sensitivity */
+ buf = 0x08;
+ wiiuse_write_data(wm, WM_REG_IR, &buf, 1);
+
+ /* wait for the wiimote to catch up */
+ #ifndef WIN32
+ usleep(50000);
+ #else
+ Sleep(50);
+ #endif
+
+ /* write sensitivity blocks */
+ wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
+ wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);
+
+ /* set the IR mode */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP))
+ buf = WM_IR_TYPE_BASIC;
+ else
+ buf = WM_IR_TYPE_EXTENDED;
+ wiiuse_write_data(wm, WM_REG_IR_MODENUM, &buf, 1);
+
+ #ifndef WIN32
+ usleep(50000);
+ #else
+ Sleep(50);
+ #endif
+
+ /* set the wiimote report type */
+ wiiuse_set_report_type(wm);
+
+ WIIUSE_DEBUG("Enabled IR camera for wiimote id %i (sensitivity level %i).", wm->unid, ir_level);
+}
+
+
+/**
+ * @brief Get the IR sensitivity settings.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param block1 [out] Pointer to where block1 will be set.
+ * @param block2 [out] Pointer to where block2 will be set.
+ *
+ * @return Returns the sensitivity level.
+ */
+static int get_ir_sens(struct wiimote_t* wm, char** block1, char** block2) {
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL1)) {
+ *block1 = WM_IR_BLOCK1_LEVEL1;
+ *block2 = WM_IR_BLOCK2_LEVEL1;
+ return 1;
+ } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL2)) {
+ *block1 = WM_IR_BLOCK1_LEVEL2;
+ *block2 = WM_IR_BLOCK2_LEVEL2;
+ return 2;
+ } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL3)) {
+ *block1 = WM_IR_BLOCK1_LEVEL3;
+ *block2 = WM_IR_BLOCK2_LEVEL3;
+ return 3;
+ } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL4)) {
+ *block1 = WM_IR_BLOCK1_LEVEL4;
+ *block2 = WM_IR_BLOCK2_LEVEL4;
+ return 4;
+ } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL5)) {
+ *block1 = WM_IR_BLOCK1_LEVEL5;
+ *block2 = WM_IR_BLOCK2_LEVEL5;
+ return 5;
+ }
+
+ *block1 = NULL;
+ *block2 = NULL;
+ return 0;
+}
+
+
+/**
+ * @brief Set the virtual screen resolution for IR tracking.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param status 1 to enable, 0 to disable.
+ */
+void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y) {
+ if (!wm) return;
+
+ wm->ir.vres[0] = (x-1);
+ wm->ir.vres[1] = (y-1);
+}
+
+
+/**
+ * @brief Set the XY position for the IR cursor.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos) {
+ if (!wm) return;
+
+ wm->ir.pos = pos;
+
+ switch (pos) {
+
+ case WIIUSE_IR_ABOVE:
+ wm->ir.offset[0] = 0;
+
+ if (wm->ir.aspect == WIIUSE_ASPECT_16_9)
+ wm->ir.offset[1] = WM_ASPECT_16_9_Y/2 - 70;
+ else if (wm->ir.aspect == WIIUSE_ASPECT_4_3)
+ wm->ir.offset[1] = WM_ASPECT_4_3_Y/2 - 100;
+
+ return;
+
+ case WIIUSE_IR_BELOW:
+ wm->ir.offset[0] = 0;
+
+ if (wm->ir.aspect == WIIUSE_ASPECT_16_9)
+ wm->ir.offset[1] = -WM_ASPECT_16_9_Y/2 + 100;
+ else if (wm->ir.aspect == WIIUSE_ASPECT_4_3)
+ wm->ir.offset[1] = -WM_ASPECT_4_3_Y/2 + 70;
+
+ return;
+
+ default:
+ return;
+ };
+}
+
+
+/**
+ * @brief Set the aspect ratio of the TV/monitor.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param aspect Either WIIUSE_ASPECT_16_9 or WIIUSE_ASPECT_4_3
+ */
+void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect) {
+ if (!wm) return;
+
+ wm->ir.aspect = aspect;
+
+ if (aspect == WIIUSE_ASPECT_4_3) {
+ wm->ir.vres[0] = WM_ASPECT_4_3_X;
+ wm->ir.vres[1] = WM_ASPECT_4_3_Y;
+ } else {
+ wm->ir.vres[0] = WM_ASPECT_16_9_X;
+ wm->ir.vres[1] = WM_ASPECT_16_9_Y;
+ }
+
+ /* reset the position offsets */
+ wiiuse_set_ir_position(wm, wm->ir.pos);
+}
+
+
+/**
+ * @brief Set the IR sensitivity.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param level 1-5, same as Wii system sensitivity setting.
+ *
+ * If the level is < 1, then level will be set to 1.
+ * If the level is > 5, then level will be set to 5.
+ */
+void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level) {
+ char* block1 = NULL;
+ char* block2 = NULL;
+
+ if (!wm) return;
+
+ if (level > 5) level = 5;
+ if (level < 1) level = 1;
+
+ WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR_SENS_LVL1 |
+ WIIMOTE_STATE_IR_SENS_LVL2 |
+ WIIMOTE_STATE_IR_SENS_LVL3 |
+ WIIMOTE_STATE_IR_SENS_LVL4 |
+ WIIMOTE_STATE_IR_SENS_LVL5));
+
+ switch (level) {
+ case 1:
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL1);
+ break;
+ case 2:
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL2);
+ break;
+ case 3:
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL3);
+ break;
+ case 4:
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL4);
+ break;
+ case 5:
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL5);
+ break;
+ default:
+ return;
+ }
+
+ /* set the new sensitivity */
+ get_ir_sens(wm, &block1, &block2);
+
+ wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9);
+ wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2);
+
+ WIIUSE_DEBUG("Set IR sensitivity to level %i (unid %i)", level, wm->unid);
+}
+
+
+/**
+ * @brief Calculate the data from the IR spots. Basic IR mode.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param data Data returned by the wiimote for the IR spots.
+ */
+void calculate_basic_ir(struct wiimote_t* wm, byte* data) {
+ struct ir_dot_t* dot = wm->ir.dot;
+ int i;
+
+ dot[0].rx = 1023 - (data[0] | ((data[2] & 0x30) << 4));
+ dot[0].ry = data[1] | ((data[2] & 0xC0) << 2);
+
+ dot[1].rx = 1023 - (data[3] | ((data[2] & 0x03) << 8));
+ dot[1].ry = data[4] | ((data[2] & 0x0C) << 6);
+
+ dot[2].rx = 1023 - (data[5] | ((data[7] & 0x30) << 4));
+ dot[2].ry = data[6] | ((data[7] & 0xC0) << 2);
+
+ dot[3].rx = 1023 - (data[8] | ((data[7] & 0x03) << 8));
+ dot[3].ry = data[9] | ((data[7] & 0x0C) << 6);
+
+ /* set each IR spot to visible if spot is in range */
+ for (i = 0; i < 4; ++i) {
+ if (dot[i].ry == 1023)
+ dot[i].visible = 0;
+ else {
+ dot[i].visible = 1;
+ dot[i].size = 0; /* since we don't know the size, set it as 0 */
+ }
+ }
+
+ interpret_ir_data(wm);
+}
+
+
+/**
+ * @brief Calculate the data from the IR spots. Extended IR mode.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param data Data returned by the wiimote for the IR spots.
+ */
+void calculate_extended_ir(struct wiimote_t* wm, byte* data) {
+ struct ir_dot_t* dot = wm->ir.dot;
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ dot[i].rx = 1023 - (data[3*i] | ((data[(3*i)+2] & 0x30) << 4));
+ dot[i].ry = data[(3*i)+1] | ((data[(3*i)+2] & 0xC0) << 2);
+
+ dot[i].size = data[(3*i)+2] & 0x0F;
+
+ /* if in range set to visible */
+ if (dot[i].ry == 1023)
+ dot[i].visible = 0;
+ else
+ dot[i].visible = 1;
+ }
+
+ interpret_ir_data(wm);
+}
+
+
+/**
+ * @brief Interpret IR data into more user friendly variables.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+static void interpret_ir_data(struct wiimote_t* wm) {
+ struct ir_dot_t* dot = wm->ir.dot;
+ int i;
+ float roll = 0.0f;
+ int last_num_dots = wm->ir.num_dots;
+
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC))
+ roll = wm->orient.roll;
+
+ /* count visible dots */
+ wm->ir.num_dots = 0;
+ for (i = 0; i < 4; ++i) {
+ if (dot[i].visible)
+ wm->ir.num_dots++;
+ }
+
+ switch (wm->ir.num_dots) {
+ case 0:
+ {
+ wm->ir.state = 0;
+
+ /* reset the dot ordering */
+ for (i = 0; i < 4; ++i)
+ dot[i].order = 0;
+
+ wm->ir.x = 0;
+ wm->ir.y = 0;
+ wm->ir.z = 0.0f;
+
+ return;
+ }
+ case 1:
+ {
+ fix_rotated_ir_dots(wm->ir.dot, roll);
+
+ if (wm->ir.state < 2) {
+ /*
+ * Only 1 known dot, so use just that.
+ */
+ for (i = 0; i < 4; ++i) {
+ if (dot[i].visible) {
+ wm->ir.x = dot[i].x;
+ wm->ir.y = dot[i].y;
+
+ wm->ir.ax = wm->ir.x;
+ wm->ir.ay = wm->ir.y;
+
+ /* can't calculate yaw because we don't have the distance */
+ //wm->orient.yaw = calc_yaw(&wm->ir);
+
+ ir_convert_to_vres(&wm->ir.x, &wm->ir.y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]);
+ break;
+ }
+ }
+ } else {
+ /*
+ * Only see 1 dot but know theres 2.
+ * Try to estimate where the other one
+ * should be and use that.
+ */
+ for (i = 0; i < 4; ++i) {
+ if (dot[i].visible) {
+ int ox = 0;
+ int x, y;
+
+ if (dot[i].order == 1)
+ /* visible is the left dot - estimate where the right is */
+ ox = dot[i].x + wm->ir.distance;
+ else if (dot[i].order == 2)
+ /* visible is the right dot - estimate where the left is */
+ ox = dot[i].x - wm->ir.distance;
+
+ x = ((signed int)dot[i].x + ox) / 2;
+ y = dot[i].y;
+
+ wm->ir.ax = x;
+ wm->ir.ay = y;
+ wm->orient.yaw = calc_yaw(&wm->ir);
+
+ if (ir_correct_for_bounds(&x, &y, wm->ir.aspect, wm->ir.offset[0], wm->ir.offset[1])) {
+ ir_convert_to_vres(&x, &y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]);
+ wm->ir.x = x;
+ wm->ir.y = y;
+ }
+
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ case 2:
+ case 3:
+ case 4:
+ {
+ /*
+ * Two (or more) dots known and seen.
+ * Average them together to estimate the true location.
+ */
+ int x, y;
+ wm->ir.state = 2;
+
+ fix_rotated_ir_dots(wm->ir.dot, roll);
+
+ /* if there is at least 1 new dot, reorder them all */
+ if (wm->ir.num_dots > last_num_dots) {
+ reorder_ir_dots(dot);
+ wm->ir.x = 0;
+ wm->ir.y = 0;
+ }
+
+ wm->ir.distance = ir_distance(dot);
+ wm->ir.z = 1023 - wm->ir.distance;
+
+ get_ir_dot_avg(wm->ir.dot, &x, &y);
+
+ wm->ir.ax = x;
+ wm->ir.ay = y;
+ wm->orient.yaw = calc_yaw(&wm->ir);
+
+ if (ir_correct_for_bounds(&x, &y, wm->ir.aspect, wm->ir.offset[0], wm->ir.offset[1])) {
+ ir_convert_to_vres(&x, &y, wm->ir.aspect, wm->ir.vres[0], wm->ir.vres[1]);
+ wm->ir.x = x;
+ wm->ir.y = y;
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ #ifdef WITH_WIIUSE_DEBUG
+ {
+ int ir_level;
+ WIIUSE_GET_IR_SENSITIVITY(wm, &ir_level);
+ WIIUSE_DEBUG("IR sensitivity: %i", ir_level);
+ WIIUSE_DEBUG("IR visible dots: %i", wm->ir.num_dots);
+ for (i = 0; i < 4; ++i)
+ if (dot[i].visible)
+ WIIUSE_DEBUG("IR[%i][order %i] (%.3i, %.3i) -> (%.3i, %.3i)", i, dot[i].order, dot[i].rx, dot[i].ry, dot[i].x, dot[i].y);
+ WIIUSE_DEBUG("IR[absolute]: (%i, %i)", wm->ir.x, wm->ir.y);
+ }
+ #endif
+}
+
+
+
+/**
+ * @brief Fix the rotation of the IR dots.
+ *
+ * @param dot An array of 4 ir_dot_t objects.
+ * @param ang The roll angle to correct by (-180, 180)
+ *
+ * If there is roll then the dots are rotated
+ * around the origin and give a false cursor
+ * position. Correct for the roll.
+ *
+ * If the accelerometer is off then obviously
+ * this will not do anything and the cursor
+ * position may be inaccurate.
+ */
+static void fix_rotated_ir_dots(struct ir_dot_t* dot, float ang) {
+ float s, c;
+ int x, y;
+ int i;
+
+ if (!ang) {
+ for (i = 0; i < 4; ++i) {
+ dot[i].x = dot[i].rx;
+ dot[i].y = dot[i].ry;
+ }
+ return;
+ }
+
+ s = sin(DEGREE_TO_RAD(ang));
+ c = cos(DEGREE_TO_RAD(ang));
+
+ /*
+ * [ cos(theta) -sin(theta) ][ ir->rx ]
+ * [ sin(theta) cos(theta) ][ ir->ry ]
+ */
+
+ for (i = 0; i < 4; ++i) {
+ if (!dot[i].visible)
+ continue;
+
+ x = dot[i].rx - (1024/2);
+ y = dot[i].ry - (768/2);
+
+ dot[i].x = (c * x) + (-s * y);
+ dot[i].y = (s * x) + (c * y);
+
+ dot[i].x += (1024/2);
+ dot[i].y += (768/2);
+ }
+}
+
+
+/**
+ * @brief Average IR dots.
+ *
+ * @param dot An array of 4 ir_dot_t objects.
+ * @param x [out] Average X
+ * @param y [out] Average Y
+ */
+static void get_ir_dot_avg(struct ir_dot_t* dot, int* x, int* y) {
+ int vis = 0, i = 0;
+
+ *x = 0;
+ *y = 0;
+
+ for (; i < 4; ++i) {
+ if (dot[i].visible) {
+ *x += dot[i].x;
+ *y += dot[i].y;
+ ++vis;
+ }
+ }
+
+ *x /= vis;
+ *y /= vis;
+}
+
+
+/**
+ * @brief Reorder the IR dots.
+ *
+ * @param dot An array of 4 ir_dot_t objects.
+ */
+static void reorder_ir_dots(struct ir_dot_t* dot) {
+ int i, j, order;
+
+ /* reset the dot ordering */
+ for (i = 0; i < 4; ++i)
+ dot[i].order = 0;
+
+ for (order = 1; order < 5; ++order) {
+ i = 0;
+
+ for (; !dot[i].visible || dot[i].order; ++i)
+ if (i > 4)
+ return;
+
+ for (j = 0; j < 4; ++j) {
+ if (dot[j].visible && !dot[j].order && (dot[j].x < dot[i].x))
+ i = j;
+ }
+
+ dot[i].order = order;
+ }
+}
+
+
+/**
+ * @brief Calculate the distance between the first 2 visible IR dots.
+ *
+ * @param dot An array of 4 ir_dot_t objects.
+ */
+static float ir_distance(struct ir_dot_t* dot) {
+ int i1, i2;
+ int xd, yd;
+
+ for (i1 = 0; i1 < 4; ++i1)
+ if (dot[i1].visible)
+ break;
+ if (i1 == 4)
+ return 0.0f;
+
+ for (i2 = i1+1; i2 < 4; ++i2)
+ if (dot[i2].visible)
+ break;
+ if (i2 == 4)
+ return 0.0f;
+
+ xd = dot[i2].x - dot[i1].x;
+ yd = dot[i2].y - dot[i1].y;
+
+ return sqrt(xd*xd + yd*yd);
+}
+
+
+/**
+ * @brief Correct for the IR bounding box.
+ *
+ * @param x [out] The current X, it will be updated if valid.
+ * @param y [out] The current Y, it will be updated if valid.
+ * @param aspect Aspect ratio of the screen.
+ * @param offset_x The X offset of the bounding box.
+ * @param offset_y The Y offset of the bounding box.
+ *
+ * @return Returns 1 if the point is valid and was updated.
+ *
+ * Nintendo was smart with this bit. They sacrifice a little
+ * precision for a big increase in usability.
+ */
+static int ir_correct_for_bounds(int* x, int* y, enum aspect_t aspect, int offset_x, int offset_y) {
+ int x0, y0;
+ int xs, ys;
+
+ if (aspect == WIIUSE_ASPECT_16_9) {
+ xs = WM_ASPECT_16_9_X;
+ ys = WM_ASPECT_16_9_Y;
+ } else {
+ xs = WM_ASPECT_4_3_X;
+ ys = WM_ASPECT_4_3_Y;
+ }
+
+ x0 = ((1024 - xs) / 2) + offset_x;
+ y0 = ((768 - ys) / 2) + offset_y;
+
+ if ((*x >= x0)
+ && (*x <= (x0 + xs))
+ && (*y >= y0)
+ && (*y <= (y0 + ys)))
+ {
+ *x -= offset_x;
+ *y -= offset_y;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/**
+ * @brief Interpolate the point to the user defined virtual screen resolution.
+ */
+static void ir_convert_to_vres(int* x, int* y, enum aspect_t aspect, int vx, int vy) {
+ int xs, ys;
+
+ if (aspect == WIIUSE_ASPECT_16_9) {
+ xs = WM_ASPECT_16_9_X;
+ ys = WM_ASPECT_16_9_Y;
+ } else {
+ xs = WM_ASPECT_4_3_X;
+ ys = WM_ASPECT_4_3_Y;
+ }
+
+ *x -= ((1024-xs)/2);
+ *y -= ((768-ys)/2);
+
+ *x = (*x / (float)xs) * vx;
+ *y = (*y / (float)ys) * vy;
+}
+
+
+/**
+ * @brief Calculate yaw given the IR data.
+ *
+ * @param ir IR data structure.
+ */
+float calc_yaw(struct ir_t* ir) {
+ float x;
+
+ x = ir->ax - 512;
+ x = x * (ir->z / 1024.0f);
+
+ return RAD_TO_DEGREE( atanf(x / ir->z) );
+}
diff --git a/Externals/WiiUseSrc/Src/ir.h b/Externals/WiiUseSrc/Src/ir.h
new file mode 100644
index 0000000000..9082492987
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/ir.h
@@ -0,0 +1,56 @@
+/*
+ * 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 IR data.
+ */
+
+#ifndef IR_H_INCLUDED
+#define IR_H_INCLUDED
+
+#include "wiiuse_internal.h"
+
+#define WII_VRES_X 560
+#define WII_VRES_Y 340
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void calculate_basic_ir(struct wiimote_t* wm, byte* data);
+void calculate_extended_ir(struct wiimote_t* wm, byte* data);
+float calc_yaw(struct ir_t* ir);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IR_H_INCLUDED
+
+
diff --git a/Externals/WiiUseSrc/Src/nunchuk.c b/Externals/WiiUseSrc/Src/nunchuk.c
new file mode 100644
index 0000000000..48dbe6a089
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/nunchuk.c
@@ -0,0 +1,210 @@
+/*
+ * 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 Nunchuk expansion device.
+ */
+
+#include
+#include
+#include
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "dynamics.h"
+#include "events.h"
+#include "nunchuk.h"
+
+static void nunchuk_pressed_buttons(struct nunchuk_t* nc, byte now);
+
+/**
+ * @brief Handle the handshake data from the nunchuk.
+ *
+ * @param nc A pointer to a nunchuk_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 nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len) {
+ int i;
+ int offset = 0;
+
+ nc->btns = 0;
+ nc->btns_held = 0;
+ nc->btns_released = 0;
+
+ /* set the smoothing to the same as the wiimote */
+ nc->flags = &wm->flags;
+ nc->accel_calib.st_alpha = wm->accel_calib.st_alpha;
+
+ /* decrypt data */
+ for (i = 0; i < len; ++i)
+ data[i] = (data[i] ^ 0x17) + 0x17;
+
+ if (data[offset] == 0xFF) {
+ /*
+ * Sometimes the data returned here is not correct.
+ * This might happen because the wiimote is lagging
+ * behind our initialization sequence.
+ * To fix this just request the handshake again.
+ *
+ * Other times it's just the first 16 bytes are 0xFF,
+ * but since the next 16 bytes are the same, just use
+ * those.
+ */
+ if (data[offset + 16] == 0xFF) {
+ /* get the calibration data */
+ byte* handshake_buf = malloc(EXP_HANDSHAKE_LEN * sizeof(byte));
+
+ WIIUSE_DEBUG("Nunchuk handshake appears invalid, trying again.");
+ wiiuse_read_data_cb(wm, handshake_expansion, handshake_buf, WM_EXP_MEM_CALIBR, EXP_HANDSHAKE_LEN);
+
+ return 0;
+ } else
+ offset += 16;
+ }
+
+ nc->accel_calib.cal_zero.x = data[offset + 0];
+ nc->accel_calib.cal_zero.y = data[offset + 1];
+ nc->accel_calib.cal_zero.z = data[offset + 2];
+ nc->accel_calib.cal_g.x = data[offset + 4];
+ nc->accel_calib.cal_g.y = data[offset + 5];
+ nc->accel_calib.cal_g.z = data[offset + 6];
+ nc->js.max.x = data[offset + 8];
+ nc->js.min.x = data[offset + 9];
+ nc->js.center.x = data[offset + 10];
+ nc->js.max.y = data[offset + 11];
+ nc->js.min.y = data[offset + 12];
+ nc->js.center.y = data[offset + 13];
+
+ /* default the thresholds to the same as the wiimote */
+ nc->orient_threshold = wm->orient_threshold;
+ nc->accel_threshold = wm->accel_threshold;
+
+ /* handshake done */
+ wm->exp.type = EXP_NUNCHUK;
+
+ #ifdef WIN32
+ wm->timeout = WIIMOTE_DEFAULT_TIMEOUT;
+ #endif
+
+ return 1;
+}
+
+
+/**
+ * @brief The nunchuk disconnected.
+ *
+ * @param nc A pointer to a nunchuk_t structure.
+ */
+void nunchuk_disconnected(struct nunchuk_t* nc) {
+ memset(nc, 0, sizeof(struct nunchuk_t));
+}
+
+
+
+/**
+ * @brief Handle nunchuk event.
+ *
+ * @param nc A pointer to a nunchuk_t structure.
+ * @param msg The message specified in the event packet.
+ */
+void nunchuk_event(struct nunchuk_t* nc, byte* msg) {
+ int i;
+
+ /* decrypt data */
+ for (i = 0; i < 6; ++i)
+ msg[i] = (msg[i] ^ 0x17) + 0x17;
+
+ /* get button states */
+ nunchuk_pressed_buttons(nc, msg[5]);
+
+ /* calculate joystick state */
+ calc_joystick_state(&nc->js, msg[0], msg[1]);
+
+ /* calculate orientation */
+ nc->accel.x = msg[2];
+ nc->accel.y = msg[3];
+ nc->accel.z = msg[4];
+
+ calculate_orientation(&nc->accel_calib, &nc->accel, &nc->orient, NUNCHUK_IS_FLAG_SET(nc, WIIUSE_SMOOTHING));
+ calculate_gforce(&nc->accel_calib, &nc->accel, &nc->gforce);
+}
+
+
+/**
+ * @brief Find what buttons are pressed.
+ *
+ * @param nc Pointer to a nunchuk_t structure.
+ * @param msg The message byte specified in the event packet.
+ */
+static void nunchuk_pressed_buttons(struct nunchuk_t* nc, byte now) {
+ /* message is inverted (0 is active, 1 is inactive) */
+ now = ~now & NUNCHUK_BUTTON_ALL;
+
+ /* pressed now & were pressed, then held */
+ nc->btns_held = (now & nc->btns);
+
+ /* were pressed or were held & not pressed now, then released */
+ nc->btns_released = ((nc->btns | nc->btns_held) & ~now);
+
+ /* buttons pressed now */
+ nc->btns = now;
+}
+
+
+/**
+ * @brief Set the orientation event threshold for the nunchuk.
+ *
+ * @param wm Pointer to a wiimote_t structure with a nunchuk attached.
+ * @param threshold The decimal place that should be considered a significant change.
+ *
+ * See wiiuse_set_orient_threshold() for details.
+ */
+void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold) {
+ if (!wm) return;
+
+ wm->exp.nunchuk.orient_threshold = threshold;
+}
+
+
+/**
+ * @brief Set the accelerometer event threshold for the nunchuk.
+ *
+ * @param wm Pointer to a wiimote_t structure with a nunchuk attached.
+ * @param threshold The decimal place that should be considered a significant change.
+ *
+ * See wiiuse_set_orient_threshold() for details.
+ */
+void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold) {
+ if (!wm) return;
+
+ wm->exp.nunchuk.accel_threshold = threshold;
+}
diff --git a/Externals/WiiUseSrc/Src/nunchuk.h b/Externals/WiiUseSrc/Src/nunchuk.h
new file mode 100644
index 0000000000..f036073d64
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/nunchuk.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 Nunchuk expansion device.
+ */
+
+#ifndef NUNCHUK_H_INCLUDED
+#define NUNCHUK_H_INCLUDED
+
+#include "wiiuse_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int nunchuk_handshake(struct wiimote_t* wm, struct nunchuk_t* nc, byte* data, unsigned short len);
+
+void nunchuk_disconnected(struct nunchuk_t* nc);
+
+void nunchuk_event(struct nunchuk_t* nc, byte* msg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NUNCHUK_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/os.h b/Externals/WiiUseSrc/Src/os.h
new file mode 100644
index 0000000000..53b80f557c
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/os.h
@@ -0,0 +1,56 @@
+/*
+ * 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 Operating system related definitions.
+ *
+ * This file is an attempt to separate operating system
+ * dependent functions and choose what should be used
+ * at compile time.
+ */
+
+#ifndef OS_H_INCLUDED
+#define OS_H_INCLUDED
+
+#ifdef WIN32
+ /* windows */
+ #define isnan(x) _isnan(x)
+ #define isinf(x) !_finite(x)
+
+ /* disable warnings I don't care about */
+ #pragma warning(disable:4244) /* possible loss of data conversion */
+ #pragma warning(disable:4273) /* inconsistent dll linkage */
+ #pragma warning(disable:4217)
+#else
+ /* nix */
+#endif
+
+
+#endif // OS_H_INCLUDED
diff --git a/Externals/WiiUseSrc/Src/wiiuse.c b/Externals/WiiUseSrc/Src/wiiuse.c
new file mode 100644
index 0000000000..8d4b763864
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/wiiuse.c
@@ -0,0 +1,764 @@
+/*
+ * 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 General wiimote operations.
+ *
+ * The file includes functions that handle general
+ * tasks. Most of these are functions that are part
+ * of the API.
+ */
+
+#include
+#include
+
+#ifndef WIN32
+ #include
+#else
+ #include
+#endif
+
+#include "definitions.h"
+#include "wiiuse_internal.h"
+#include "events.h"
+#include "io.h"
+
+static int g_banner = 0;
+
+/**
+ * @breif Returns the version of the library.
+ */
+const char* wiiuse_version() {
+ return WIIUSE_VERSION;
+}
+
+
+/**
+ * @brief Clean up wiimote_t array created by wiiuse_init()
+ */
+void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes) {
+ int i = 0;
+
+ if (!wm)
+ return;
+
+ WIIUSE_INFO("wiiuse clean up...");
+
+ for (; i < wiimotes; ++i) {
+ wiiuse_disconnect(wm[i]);
+ free(wm[i]);
+ }
+
+ free(wm);
+
+ return;
+}
+
+
+/**
+ * @brief Initialize an array of wiimote structures.
+ *
+ * @param wiimotes Number of wiimote_t structures to create.
+ *
+ * @return An array of initialized wiimote_t structures.
+ *
+ * @see wiiuse_connect()
+ *
+ * The array returned by this function can be passed to various
+ * functions, including wiiuse_connect().
+ */
+struct wiimote_t** wiiuse_init(int wiimotes) {
+ int i = 0;
+ struct wiimote_t** wm = NULL;
+
+ /*
+ * Please do not remove this banner.
+ * GPL asks that you please leave output credits intact.
+ * Thank you.
+ *
+ * This banner is only displayed once so that if you need
+ * to call this function again it won't be intrusive.
+ */
+ if (!g_banner) {
+ printf( "wiiuse v" WIIUSE_VERSION " loaded.\n"
+ " By: Michael Laforest \n"
+ " http://wiiuse.net http://wiiuse.sf.net\n");
+ g_banner = 1;
+ }
+
+ if (!wiimotes)
+ return NULL;
+
+ wm = malloc(sizeof(struct wiimote_t*) * wiimotes);
+
+ for (i = 0; i < wiimotes; ++i) {
+ wm[i] = malloc(sizeof(struct wiimote_t));
+ memset(wm[i], 0, sizeof(struct wiimote_t));
+
+ wm[i]->unid = i+1;
+
+ #ifndef WIN32
+ wm[i]->bdaddr = *BDADDR_ANY;
+ wm[i]->out_sock = -1;
+ wm[i]->in_sock = -1;
+ #else
+ wm[i]->dev_handle = 0;
+ wm[i]->stack = WIIUSE_STACK_UNKNOWN;
+ wm[i]->normal_timeout = WIIMOTE_DEFAULT_TIMEOUT;
+ wm[i]->exp_timeout = WIIMOTE_EXP_TIMEOUT;
+ wm[i]->timeout = wm[i]->normal_timeout;
+ #endif
+
+ wm[i]->state = WIIMOTE_INIT_STATES;
+ wm[i]->flags = WIIUSE_INIT_FLAGS;
+
+ wm[i]->event = WIIUSE_NONE;
+
+ wm[i]->exp.type = EXP_NONE;
+
+ wiiuse_set_aspect_ratio(wm[i], WIIUSE_ASPECT_4_3);
+ wiiuse_set_ir_position(wm[i], WIIUSE_IR_ABOVE);
+
+ wm[i]->orient_threshold = 0.5f;
+ wm[i]->accel_threshold = 5;
+
+ wm[i]->accel_calib.st_alpha = WIIUSE_DEFAULT_SMOOTH_ALPHA;
+ }
+
+ return wm;
+}
+
+
+/**
+ * @brief The wiimote disconnected.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+void wiiuse_disconnected(struct wiimote_t* wm) {
+ if (!wm) return;
+
+ WIIUSE_INFO("Wiimote disconnected [id %i].", wm->unid);
+
+ /* disable the connected flag */
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED);
+
+ /* reset a bunch of stuff */
+ #ifndef WIN32
+ wm->out_sock = -1;
+ wm->in_sock = -1;
+ #else
+ wm->dev_handle = 0;
+ #endif
+
+ wm->leds = 0;
+ wm->state = WIIMOTE_INIT_STATES;
+ wm->read_req = NULL;
+ wm->handshake_state = 0;
+ wm->btns = 0;
+ wm->btns_held = 0;
+ wm->btns_released = 0;
+ memset(wm->event_buf, 0, sizeof(wm->event_buf));
+
+ wm->event = WIIUSE_DISCONNECT;
+}
+
+
+/**
+ * @brief Enable or disable the rumble.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param status 1 to enable, 0 to disable.
+ */
+void wiiuse_rumble(struct wiimote_t* wm, int status) {
+ byte buf;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return;
+
+ /* make sure to keep the current lit leds */
+ buf = wm->leds;
+
+ if (status) {
+ WIIUSE_DEBUG("Starting rumble...");
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
+ buf |= 0x01;
+ } else {
+ WIIUSE_DEBUG("Stopping rumble...");
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE);
+ }
+
+ /* preserve IR state */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR))
+ buf |= 0x04;
+
+ wiiuse_send(wm, WM_CMD_RUMBLE, &buf, 1);
+}
+
+
+/**
+ * @brief Toggle the state of the rumble.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+void wiiuse_toggle_rumble(struct wiimote_t* wm) {
+ if (!wm) return;
+
+ wiiuse_rumble(wm, !WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE));
+}
+
+
+/**
+ * @brief Set the enabled LEDs.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param leds What LEDs to enable.
+ *
+ * \a leds is a bitwise or of WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, or WIIMOTE_LED_4.
+ */
+void wiiuse_set_leds(struct wiimote_t* wm, int leds) {
+ byte buf;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return;
+
+ /* remove the lower 4 bits because they control rumble */
+ wm->leds = (leds & 0xF0);
+
+ /* make sure if the rumble is on that we keep it on */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE))
+ wm->leds |= 0x01;
+
+ buf = wm->leds;
+
+ wiiuse_send(wm, WM_CMD_LED, &buf, 1);
+}
+
+
+/**
+ * @brief Set if the wiimote should report motion sensing.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param status 1 to enable, 0 to disable.
+ *
+ * Since reporting motion sensing sends a lot of data,
+ * the wiimote saves power by not transmitting it
+ * by default.
+ */
+void wiiuse_motion_sensing(struct wiimote_t* wm, int status) {
+ if (status)
+ WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_ACC);
+ else
+ WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_ACC);
+
+ wiiuse_set_report_type(wm);
+}
+
+
+/**
+ * @brief Set the report type based on the current wiimote state.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ *
+ * @return The report type sent.
+ *
+ * The wiimote reports formatted packets depending on the
+ * report type that was last requested. This function will
+ * update the type of report that should be sent based on
+ * the current state of the device.
+ */
+int wiiuse_set_report_type(struct wiimote_t* wm) {
+ byte buf[2];
+ int motion, exp, ir;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+
+ buf[0] = (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_CONTINUOUS) ? 0x04 : 0x00); /* set to 0x04 for continuous reporting */
+ buf[1] = 0x00;
+
+ /* if rumble is enabled, make sure we keep it */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE))
+ buf[0] |= 0x01;
+
+ motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC);
+ exp = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP);
+ ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR);
+
+ if (motion && ir && exp) buf[1] = WM_RPT_BTN_ACC_IR_EXP;
+ else if (motion && exp) buf[1] = WM_RPT_BTN_ACC_EXP;
+ else if (motion && ir) buf[1] = WM_RPT_BTN_ACC_IR;
+ else if (ir && exp) buf[1] = WM_RPT_BTN_IR_EXP;
+ else if (ir) buf[1] = WM_RPT_BTN_ACC_IR;
+ else if (exp) buf[1] = WM_RPT_BTN_EXP;
+ else if (motion) buf[1] = WM_RPT_BTN_ACC;
+ else buf[1] = WM_RPT_BTN;
+
+ WIIUSE_DEBUG("Setting report type: 0x%x", buf[1]);
+
+ exp = wiiuse_send(wm, WM_CMD_REPORT_TYPE, buf, 2);
+ if (exp <= 0)
+ return exp;
+
+ return buf[1];
+}
+
+
+/**
+ * @brief Read data from the wiimote (callback version).
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param read_cb Function pointer to call when the data arrives from the wiimote.
+ * @param buffer An allocated buffer to store the data as it arrives from the wiimote.
+ * Must be persistent in memory and large enough to hold the data.
+ * @param addr The address of wiimote memory to read from.
+ * @param len The length of the block to be read.
+ *
+ * The library can only handle one data read request at a time
+ * because it must keep track of the buffer and other
+ * events that are specific to that request. So if a request
+ * has already been made, subsequent requests will be added
+ * to a pending list and be sent out when the previous
+ * finishes.
+ */
+int wiiuse_read_data_cb(struct wiimote_t* wm, wiiuse_read_cb read_cb, byte* buffer, unsigned int addr, unsigned short len) {
+ struct read_req_t* req;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+ if (!buffer || !len || !read_cb)
+ return 0;
+
+ /* make this request structure */
+ req = (struct read_req_t*)malloc(sizeof(struct read_req_t));
+ req->cb = read_cb;
+ req->buf = buffer;
+ req->addr = addr;
+ req->size = len;
+ req->wait = len;
+ req->dirty = 0;
+ req->next = NULL;
+
+ /* add this to the request list */
+ if (!wm->read_req) {
+ /* root node */
+ wm->read_req = req;
+
+ WIIUSE_DEBUG("Data read request can be sent out immediately.");
+
+ /* send the request out immediately */
+ wiiuse_send_next_pending_read_request(wm);
+ } else {
+ struct read_req_t* nptr = wm->read_req;
+ for (; nptr->next; nptr = nptr->next);
+ nptr->next = req;
+
+ WIIUSE_DEBUG("Added pending data read request.");
+ }
+
+ return 1;
+}
+
+
+/**
+ * @brief Read data from the wiimote (event version).
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param buffer An allocated buffer to store the data as it arrives from the wiimote.
+ * Must be persistent in memory and large enough to hold the data.
+ * @param addr The address of wiimote memory to read from.
+ * @param len The length of the block to be read.
+ *
+ * The library can only handle one data read request at a time
+ * because it must keep track of the buffer and other
+ * events that are specific to that request. So if a request
+ * has already been made, subsequent requests will be added
+ * to a pending list and be sent out when the previous
+ * finishes.
+ */
+int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int addr, unsigned short len) {
+ struct read_req_t* req;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+ if (!buffer || !len)
+ return 0;
+
+ /* make this request structure */
+ req = (struct read_req_t*)malloc(sizeof(struct read_req_t));
+ req->cb = NULL;
+ req->buf = buffer;
+ req->addr = addr;
+ req->size = len;
+ req->wait = len;
+ req->dirty = 0;
+ req->next = NULL;
+
+ /* add this to the request list */
+ if (!wm->read_req) {
+ /* root node */
+ wm->read_req = req;
+
+ WIIUSE_DEBUG("Data read request can be sent out immediately.");
+
+ /* send the request out immediately */
+ wiiuse_send_next_pending_read_request(wm);
+ } else {
+ struct read_req_t* nptr = wm->read_req;
+ for (; nptr->next; nptr = nptr->next);
+ nptr->next = req;
+
+ WIIUSE_DEBUG("Added pending data read request.");
+ }
+
+ return 1;
+}
+
+
+/**
+ * @brief Send the next pending data read request to the wiimote.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ *
+ * @see wiiuse_read_data()
+ *
+ * This function is not part of the wiiuse API.
+ */
+void wiiuse_send_next_pending_read_request(struct wiimote_t* wm) {
+ byte buf[6];
+ struct read_req_t* req;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return;
+ if (!wm->read_req) return;
+
+ /* skip over dirty ones since they have already been read */
+ req = wm->read_req;
+ while (req && req->dirty)
+ req = req->next;
+ if (!req)
+ return;
+
+ /* the offset is in big endian */
+ *(int*)(buf) = BIG_ENDIAN_LONG(req->addr);
+
+ /* the length is in big endian */
+ *(short*)(buf + 4) = BIG_ENDIAN_SHORT(req->size);
+
+ WIIUSE_DEBUG("Request read at address: 0x%x length: %i", req->addr, req->size);
+ wiiuse_send(wm, WM_CMD_READ_DATA, buf, 6);
+}
+
+
+/**
+ * @brief Request the wiimote controller status.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ *
+ * Controller status includes: battery level, LED status, expansions
+ */
+void wiiuse_status(struct wiimote_t* wm) {
+ byte buf = 0;
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return;
+
+ WIIUSE_DEBUG("Requested wiimote status.");
+
+ wiiuse_send(wm, WM_CMD_CTRL_STATUS, &buf, 1);
+}
+
+
+/**
+ * @brief Find a wiimote_t structure by its unique identifier.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param wiimotes The number of wiimote_t structures in \a wm.
+ * @param unid The unique identifier to search for.
+ *
+ * @return Pointer to a wiimote_t structure, or NULL if not found.
+ */
+struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid) {
+ int i = 0;
+
+ for (; i < wiimotes; ++i) {
+ if (wm[i]->unid == unid)
+ return wm[i];
+ }
+
+ return NULL;
+}
+
+
+/**
+ * @brief Write data to the wiimote.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param addr The address to write to.
+ * @param data The data to be written to the memory location.
+ * @param len The length of the block to be written.
+ */
+int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len) {
+ byte buf[21] = {0}; /* the payload is always 23 */
+
+ if (!wm || !WIIMOTE_IS_CONNECTED(wm))
+ return 0;
+ if (!data || !len)
+ return 0;
+
+ WIIUSE_DEBUG("Writing %i bytes to memory location 0x%x...", len, addr);
+
+ #ifdef WITH_WIIUSE_DEBUG
+ {
+ int i = 0;
+ printf("Write data is: ");
+ for (; i < len; ++i)
+ printf("%x ", data[i]);
+ printf("\n");
+ }
+ #endif
+
+ /* the offset is in big endian */
+ *(int*)(buf) = BIG_ENDIAN_LONG(addr);
+
+ /* length */
+ *(byte*)(buf + 4) = len;
+
+ /* data */
+ memcpy(buf + 5, data, len);
+
+ wiiuse_send(wm, WM_CMD_WRITE_DATA, buf, 21);
+ return 1;
+}
+
+
+/**
+ * @brief Send a packet to the wiimote.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param report_type The report type to send (WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc). Found in wiiuse.h
+ * @param msg The payload.
+ * @param len Length of the payload in bytes.
+ *
+ * This function should replace any write()s directly to the wiimote device.
+ */
+int wiiuse_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) {
+ byte buf[32]; /* no payload is better than this */
+ int rumble = 0;
+
+ #ifndef WIN32
+ buf[0] = WM_SET_REPORT | WM_BT_OUTPUT;
+ buf[1] = report_type;
+ #else
+ buf[0] = report_type;
+ #endif
+
+ switch (report_type) {
+ case WM_CMD_LED:
+ case WM_CMD_RUMBLE:
+ case WM_CMD_CTRL_STATUS:
+ {
+ /* Rumble flag for: 0x11, 0x13, 0x14, 0x15, 0x19 or 0x1a */
+ if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE))
+ rumble = 1;
+ break;
+ }
+ default:
+ break;
+ }
+
+ #ifndef WIN32
+ memcpy(buf+2, msg, len);
+ if (rumble)
+ buf[2] |= 0x01;
+ #else
+ memcpy(buf+1, msg, len);
+ if (rumble)
+ buf[1] |= 0x01;
+ #endif
+
+ #ifdef WITH_WIIUSE_DEBUG
+ {
+ int x = 2;
+ printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]);
+ #ifndef WIN32
+ for (; x < len+2; ++x)
+ #else
+ for (; x < len+1; ++x)
+ #endif
+ printf("%.2x ", buf[x]);
+ printf("\n");
+ }
+ #endif
+
+ #ifndef WIN32
+ return wiiuse_io_write(wm, buf, len+2);
+ #else
+ return wiiuse_io_write(wm, buf, len+1);
+ #endif
+}
+
+
+/**
+ * @brief Set flags for the specified wiimote.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param enable Flags to enable.
+ * @param disable Flags to disable.
+ *
+ * @return The flags set after 'enable' and 'disable' have been applied.
+ *
+ * The values 'enable' and 'disable' may be any flags OR'ed together.
+ * Flags are defined in wiiuse.h.
+ */
+int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable) {
+ if (!wm) return 0;
+
+ /* remove mutually exclusive flags */
+ enable &= ~disable;
+ disable &= ~enable;
+
+ wm->flags |= enable;
+ wm->flags &= ~disable;
+
+ return wm->flags;
+}
+
+
+/**
+ * @brief Set the wiimote smoothing alpha value.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param alpha The alpha value to set. Between 0 and 1.
+ *
+ * @return Returns the old alpha value.
+ *
+ * The alpha value is between 0 and 1 and is used in an exponential
+ * smoothing algorithm.
+ *
+ * Smoothing is only performed if the WIIMOTE_USE_SMOOTHING is set.
+ */
+float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha) {
+ float old;
+
+ if (!wm) return 0.0f;
+
+ old = wm->accel_calib.st_alpha;
+
+ wm->accel_calib.st_alpha = alpha;
+
+ /* if there is a nunchuk set that too */
+ if (wm->exp.type == EXP_NUNCHUK)
+ wm->exp.nunchuk.accel_calib.st_alpha = alpha;
+
+ return old;
+}
+
+
+/**
+ * @brief Set the bluetooth stack type to use.
+ *
+ * @param wm Array of wiimote_t structures.
+ * @param wiimotes Number of objects in the wm array.
+ * @param type The type of bluetooth stack to use.
+ */
+void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type) {
+ #ifdef WIN32
+ int i;
+
+ if (!wm) return;
+
+ for (i = 0; i < wiimotes; ++i)
+ wm[i]->stack = type;
+ #endif
+}
+
+
+/**
+ * @brief Set the orientation event threshold.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param threshold The decimal place that should be considered a significant change.
+ *
+ * If threshold is 0.01, and any angle changes by 0.01 then a significant change
+ * has occured and the event callback will be invoked. If threshold is 1 then
+ * the angle has to change by a full degree to generate an event.
+ */
+void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold) {
+ if (!wm) return;
+
+ wm->orient_threshold = threshold;
+}
+
+
+/**
+ * @brief Set the accelerometer event threshold.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ * @param threshold The decimal place that should be considered a significant change.
+ */
+void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold) {
+ if (!wm) return;
+
+ wm->accel_threshold = threshold;
+}
+
+
+/**
+ * @brief Try to resync with the wiimote by starting a new handshake.
+ *
+ * @param wm Pointer to a wiimote_t structure.
+ */
+void wiiuse_resync(struct wiimote_t* wm) {
+ if (!wm) return;
+
+ wm->handshake_state = 0;
+ wiiuse_handshake(wm, NULL, 0);
+}
+
+
+/**
+ * @brief Set the normal and expansion handshake timeouts.
+ *
+ * @param wm Array of wiimote_t structures.
+ * @param wiimotes Number of objects in the wm array.
+ * @param normal_timeout The timeout in milliseconds for a normal read.
+ * @param exp_timeout The timeout in millisecondsd to wait for an expansion handshake.
+ */
+void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout) {
+ #ifdef WIN32
+ int i;
+
+ if (!wm) return;
+
+ for (i = 0; i < wiimotes; ++i) {
+ wm[i]->normal_timeout = normal_timeout;
+ wm[i]->exp_timeout = exp_timeout;
+ }
+ #endif
+}
diff --git a/Externals/WiiUseSrc/Src/wiiuse.h b/Externals/WiiUseSrc/Src/wiiuse.h
new file mode 100644
index 0000000000..a70dc9e344
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/wiiuse.h
@@ -0,0 +1,657 @@
+/*
+ * 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.
+ */
+#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button))
+
+/**
+ * @brief Return the IR sensitivity level.
+ * @param wm Pointer to a wiimote_t structure.
+ * @param lvl [out] Pointer to an int that will hold the level setting.
+ * If no level is set 'lvl' will be set to 0.
+ */
+#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \
+ do { \
+ if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \
+ else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \
+ else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \
+ else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \
+ 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 */
+ 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 */
+
+ 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 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,
+ WIIUSE_STATUS,
+ WIIUSE_CONNECT,
+ WIIUSE_DISCONNECT,
+ WIIUSE_UNEXPECTED_DISCONNECT,
+ WIIUSE_READ_DATA,
+ 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 */
+
+ 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);
+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);
+
+/* io.c */
+WIIUSE_EXPORT extern int wiiuse_io_read(struct wiimote_t* wm);
+WIIUSE_EXPORT extern int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* WIIUSE_H_INCLUDED */
+
diff --git a/Externals/WiiUseSrc/Src/wiiuse_internal.h b/Externals/WiiUseSrc/Src/wiiuse_internal.h
new file mode 100644
index 0000000000..1b2f423862
--- /dev/null
+++ b/Externals/WiiUseSrc/Src/wiiuse_internal.h
@@ -0,0 +1,226 @@
+/*
+ * 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 General internal wiiuse stuff.
+ *
+ * Since Wiiuse is a library, wiiuse.h is a duplicate
+ * of the API header.
+ *
+ * The code that would normally go in that file, but
+ * which is not needed by third party developers,
+ * is put here.
+ *
+ * So wiiuse_internal.h is included by other files
+ * internally, wiiuse.h is included only here.
+ */
+
+#ifndef WIIUSE_INTERNAL_H_INCLUDED
+#define WIIUSE_INTERNAL_H_INCLUDED
+
+#ifndef WIN32
+ #include /* htons() */
+ #include
+#endif
+
+#include "definitions.h"
+
+/* wiiuse version */
+#define WIIUSE_VERSION "0.12"
+
+/********************
+ *
+ * Wiimote internal codes
+ *
+ ********************/
+
+/* Communication channels */
+#define WM_OUTPUT_CHANNEL 0x11
+#define WM_INPUT_CHANNEL 0x13
+
+#define WM_SET_REPORT 0x50
+
+/* commands */
+#define WM_CMD_LED 0x11
+#define WM_CMD_REPORT_TYPE 0x12
+#define WM_CMD_RUMBLE 0x13
+#define WM_CMD_IR 0x13
+#define WM_CMD_CTRL_STATUS 0x15
+#define WM_CMD_WRITE_DATA 0x16
+#define WM_CMD_READ_DATA 0x17
+#define WM_CMD_IR_2 0x1A
+
+/* input report ids */
+#define WM_RPT_CTRL_STATUS 0x20
+#define WM_RPT_READ 0x21
+#define WM_RPT_WRITE 0x22
+#define WM_RPT_BTN 0x30
+#define WM_RPT_BTN_ACC 0x31
+#define WM_RPT_BTN_ACC_IR 0x33
+#define WM_RPT_BTN_EXP 0x34
+#define WM_RPT_BTN_ACC_EXP 0x35
+#define WM_RPT_BTN_IR_EXP 0x36
+#define WM_RPT_BTN_ACC_IR_EXP 0x37
+
+#define WM_BT_INPUT 0x01
+#define WM_BT_OUTPUT 0x02
+
+/* Identify the wiimote device by its class */
+#define WM_DEV_CLASS_0 0x04
+#define WM_DEV_CLASS_1 0x25
+#define WM_DEV_CLASS_2 0x00
+#define WM_VENDOR_ID 0x057E
+#define WM_PRODUCT_ID 0x0306
+
+/* controller status stuff */
+#define WM_MAX_BATTERY_CODE 0xC8
+
+/* offsets in wiimote memory */
+#define WM_MEM_OFFSET_CALIBRATION 0x16
+#define WM_EXP_MEM_BASE 0x04A40000
+#define WM_EXP_MEM_ENABLE 0x04A40040
+#define WM_EXP_MEM_CALIBR 0x04A40020
+
+#define WM_REG_IR 0x04B00030
+#define WM_REG_IR_BLOCK1 0x04B00000
+#define WM_REG_IR_BLOCK2 0x04B0001A
+#define WM_REG_IR_MODENUM 0x04B00033
+
+/* ir block data */
+#define WM_IR_BLOCK1_LEVEL1 "\x02\x00\x00\x71\x01\x00\x64\x00\xfe"
+#define WM_IR_BLOCK2_LEVEL1 "\xfd\x05"
+#define WM_IR_BLOCK1_LEVEL2 "\x02\x00\x00\x71\x01\x00\x96\x00\xb4"
+#define WM_IR_BLOCK2_LEVEL2 "\xb3\x04"
+#define WM_IR_BLOCK1_LEVEL3 "\x02\x00\x00\x71\x01\x00\xaa\x00\x64"
+#define WM_IR_BLOCK2_LEVEL3 "\x63\x03"
+#define WM_IR_BLOCK1_LEVEL4 "\x02\x00\x00\x71\x01\x00\xc8\x00\x36"
+#define WM_IR_BLOCK2_LEVEL4 "\x35\x03"
+#define WM_IR_BLOCK1_LEVEL5 "\x07\x00\x00\x71\x01\x00\x72\x00\x20"
+#define WM_IR_BLOCK2_LEVEL5 "\x1f\x03"
+
+#define WM_IR_TYPE_BASIC 0x01
+#define WM_IR_TYPE_EXTENDED 0x03
+
+/* controller status flags for the first message byte */
+/* bit 1 is unknown */
+#define WM_CTRL_STATUS_BYTE1_ATTACHMENT 0x02
+#define WM_CTRL_STATUS_BYTE1_SPEAKER_ENABLED 0x04
+#define WM_CTRL_STATUS_BYTE1_IR_ENABLED 0x08
+#define WM_CTRL_STATUS_BYTE1_LED_1 0x10
+#define WM_CTRL_STATUS_BYTE1_LED_2 0x20
+#define WM_CTRL_STATUS_BYTE1_LED_3 0x40
+#define WM_CTRL_STATUS_BYTE1_LED_4 0x80
+
+/* aspect ratio */
+#define WM_ASPECT_16_9_X 660
+#define WM_ASPECT_16_9_Y 370
+#define WM_ASPECT_4_3_X 560
+#define WM_ASPECT_4_3_Y 420
+
+
+/**
+ * Expansion stuff
+ */
+
+/* encrypted expansion id codes (located at 0x04A400FC) */
+#define EXP_ID_CODE_NUNCHUK 0x9A1EFEFE
+#define EXP_ID_CODE_CLASSIC_CONTROLLER 0x9A1EFDFD
+#define EXP_ID_CODE_GUITAR 0x9A1EFDFB
+
+#define EXP_HANDSHAKE_LEN 224
+
+/********************
+ *
+ * End Wiimote internal codes
+ *
+ ********************/
+
+/* wiimote state flags - (some duplicated in wiiuse.h)*/
+#define WIIMOTE_STATE_DEV_FOUND 0x0001
+#define WIIMOTE_STATE_HANDSHAKE 0x0002 /* actual connection exists but no handshake yet */
+#define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x0004 /* actual connection exists but no handshake yet */
+#define WIIMOTE_STATE_CONNECTED 0x0008
+#define WIIMOTE_STATE_RUMBLE 0x0010
+#define WIIMOTE_STATE_ACC 0x0020
+#define WIIMOTE_STATE_EXP 0x0040
+#define WIIMOTE_STATE_IR 0x0080
+#define WIIMOTE_STATE_SPEAKER 0x0100
+#define WIIMOTE_STATE_IR_SENS_LVL1 0x0200
+#define WIIMOTE_STATE_IR_SENS_LVL2 0x0400
+#define WIIMOTE_STATE_IR_SENS_LVL3 0x0800
+#define WIIMOTE_STATE_IR_SENS_LVL4 0x1000
+#define WIIMOTE_STATE_IR_SENS_LVL5 0x2000
+
+#define WIIMOTE_INIT_STATES (WIIMOTE_STATE_IR_SENS_LVL3)
+
+/* macro to manage states */
+#define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s))
+#define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s))
+#define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s))
+#define WIIMOTE_TOGGLE_STATE(wm, s) ((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s))
+
+#define WIIMOTE_IS_FLAG_SET(wm, s) ((wm->flags & (s)) == (s))
+#define WIIMOTE_ENABLE_FLAG(wm, s) (wm->flags |= (s))
+#define WIIMOTE_DISABLE_FLAG(wm, s) (wm->flags &= ~(s))
+#define WIIMOTE_TOGGLE_FLAG(wm, s) ((wm->flags & (s)) ? WIIMOTE_DISABLE_FLAG(wm, s) : WIIMOTE_ENABLE_FLAG(wm, s))
+
+#define NUNCHUK_IS_FLAG_SET(wm, s) ((*(wm->flags) & (s)) == (s))
+
+/* misc macros */
+#define WIIMOTE_ID(wm) (wm->unid)
+#define WIIMOTE_IS_CONNECTED(wm) (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED))
+
+/*
+ * Smooth tilt calculations are computed with the
+ * exponential moving average formula:
+ * St = St_last + (alpha * (tilt - St_last))
+ * alpha is between 0 and 1
+ */
+#define WIIUSE_DEFAULT_SMOOTH_ALPHA 0.07f
+
+#define SMOOTH_ROLL 0x01
+#define SMOOTH_PITCH 0x02
+
+#include "wiiuse.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* not part of the api */
+int wiiuse_set_report_type(struct wiimote_t* wm);
+void wiiuse_send_next_pending_read_request(struct wiimote_t* wm);
+int wiiuse_send(struct wiimote_t* wm, byte report_type, byte* msg, int len);
+int wiiuse_read_data_cb(struct wiimote_t* wm, wiiuse_read_cb read_cb, byte* buffer, unsigned int offset, unsigned short len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WIIUSE_INTERNAL_H_INCLUDED */
diff --git a/Externals/WiiUseSrc/wiiuse.sln b/Externals/WiiUseSrc/wiiuse.sln
new file mode 100644
index 0000000000..beece4e143
--- /dev/null
+++ b/Externals/WiiUseSrc/wiiuse.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wiiuse", "wiiuse.vcproj", "{944EF6DE-471D-447E-A2FD-D37D58805169}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Debug|Win32.ActiveCfg = Debug|Win32
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Debug|Win32.Build.0 = Debug|Win32
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Debug|x64.ActiveCfg = Debug|x64
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Debug|x64.Build.0 = Debug|x64
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Release|Win32.ActiveCfg = Release|Win32
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Release|Win32.Build.0 = Release|Win32
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Release|x64.ActiveCfg = Release|x64
+ {944EF6DE-471D-447E-A2FD-D37D58805169}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Externals/WiiUseSrc/wiiuse.suo b/Externals/WiiUseSrc/wiiuse.suo
new file mode 100644
index 0000000000..3dfa0ede36
Binary files /dev/null and b/Externals/WiiUseSrc/wiiuse.suo differ
diff --git a/Externals/WiiUseSrc/wiiuse.vcproj b/Externals/WiiUseSrc/wiiuse.vcproj
new file mode 100644
index 0000000000..b18604f18a
--- /dev/null
+++ b/Externals/WiiUseSrc/wiiuse.vcproj
@@ -0,0 +1,508 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+