summaryrefslogtreecommitdiffhomepage
path: root/wiiyourself/wiimote_state.h
diff options
context:
space:
mode:
Diffstat (limited to 'wiiyourself/wiimote_state.h')
-rw-r--r--wiiyourself/wiimote_state.h379
1 files changed, 379 insertions, 0 deletions
diff --git a/wiiyourself/wiimote_state.h b/wiiyourself/wiimote_state.h
new file mode 100644
index 00000000..1bf167a2
--- /dev/null
+++ b/wiiyourself/wiimote_state.h
@@ -0,0 +1,379 @@
+// _______________________________________________________________________________
+//
+// - WiiYourself! - native C++ Wiimote library v1.15
+// (c) gl.tter 2007-10 - http://gl.tter.org
+//
+// see License.txt for conditions of use. see History.txt for change log.
+// _______________________________________________________________________________
+//
+// wiimote_state.h (tab = 4 spaces)
+
+// the 'wiimote_state' struct contains all the Wiimote and Extension state data
+// (buttons etc) - the wiimote class inherits from this and the app can poll
+// the data there at any time.
+#ifdef _MSC_VER // VC
+# pragma once
+#endif
+
+#ifndef _WIIMOTE_STATE_H
+# define _WIIMOTE_STATE_H
+
+#include "wiimote_common.h"
+
+
+// wiimote_state (contains the Wiimote and Extension data and settings)
+struct wiimote_state
+ {
+ friend class wiimote; // for Clear()
+
+ // calibration information (stored on the Wiimote)
+ struct calibration_info
+ {
+ BYTE X0, Y0, Z0;
+ BYTE XG, YG, ZG;
+ } CalibrationInfo;
+
+ // button state:
+ struct buttons
+ {
+ // convenience accessors
+ inline bool A () const { return (Bits & _A) != 0; }
+ inline bool B () const { return (Bits & _B) != 0; }
+ inline bool Plus () const { return (Bits & PLUS) != 0; }
+ inline bool Home () const { return (Bits & HOME) != 0; }
+ inline bool Minus () const { return (Bits & MINUS) != 0; }
+ inline bool One () const { return (Bits & ONE) != 0; }
+ inline bool Two () const { return (Bits & TWO) != 0; }
+ inline bool Up () const { return (Bits & UP) != 0; }
+ inline bool Down () const { return (Bits & DOWN) != 0; }
+ inline bool Left () const { return (Bits & LEFT) != 0; }
+ inline bool Right () const { return (Bits & RIGHT) != 0; }
+
+ // all 11 buttons stored as bits (set = pressed)
+ WORD Bits;
+
+ // button bit masks (little-endian order)
+ enum mask
+ {
+ LEFT = 0x0001,
+ RIGHT = 0x0002,
+ DOWN = 0x0004,
+ UP = 0x0008,
+ PLUS = 0x0010,
+ TWO = 0x0100,
+ ONE = 0x0200,
+ _B = 0x0400, // ie. trigger
+ _A = 0x0800,
+ MINUS = 0x1000,
+ HOME = 0x8000,
+ //
+ ALL = LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME,
+ };
+ } Button;
+
+ // accelerometers state:
+ struct acceleration
+ {
+ BYTE RawX, RawY, RawZ;
+ float X, Y, Z;
+
+ // note: experimental! the orientation values can only be safely estimated
+ // if the controller isn't accelerating (otherwise there is no
+ // simple way to seperate orientation from acceleration - except
+ // perhaps using the IR reference and/or some clever assumptions).
+ // so for now the code only updates orientation if the controller
+ // appear to be stationary (by checking if the acceleration vector
+ // length is near 1G for several updates in a row).
+ // also note that there is no way to detect Yaw from the accelerometer
+ // alone when it's pointing at the screen (and I'm not curently
+ // processing IR):
+ struct orientation
+ {
+ float X, Y, Z;
+ unsigned UpdateAge; // how many acceleration updates ago the last
+ // orientation estimate was made (if this
+ // value is high, the values are out-of-date
+ // and probably shouldn't be used).
+ // Euler angle support (useful for some things).
+ // * note that decomposing to Euler angles is complex, not always reliable,
+ // and also depends on your assumptions about the order each component
+ // is applied in. you may need to handle this yourself for more
+ // complex scenarios *
+ float Pitch; // in degrees (-180 - +180)
+ float Roll; // "
+ // float Yaw;
+ } Orientation;
+ } Acceleration;
+
+ // IR camera state:
+ struct ir
+ {
+ // in theory the IR imager is 1024x768 and so should report raw coords
+ // 0-1023 x 0-767. in practice I have never seen them exceed the values
+ // below, so I'm using them instead to give the full 0-1 float range
+ // (it's possible that the edge pixels are used for processing, or masked
+ // out due to being unreliable). let me know if your wiimote reports
+ // a different range.
+ static const unsigned MAX_RAW_X = 1016;
+ static const unsigned MAX_RAW_Y = 760;
+
+ // data mode reported by the IR sensor
+ enum mode
+ {
+ OFF = 0x00,
+ BASIC = 0x01, // 10 bytes
+ EXTENDED = 0x03, // 12 bytes
+ FULL = 0x05, // 16 bytes * 2 (format unknown)
+ };
+
+ mode Mode; // read-only (depends on ReportType set)
+
+ struct dot
+ {
+ bool bVisible; // other values are not valid if == false
+ unsigned RawX;
+ unsigned RawY;
+ float X; // 0-1 (left-right)
+ float Y; // " (top -bottom)
+ int Size; // (not available in BASIC mode)
+ } Dot[4];
+ } IR;
+
+ struct leds
+ {
+ // all LEDs stored in bits 0-3 (1 = lit)
+ BYTE Bits;
+
+ // convenience accessors:
+ inline bool Lit (unsigned index)
+ { _ASSERT(index < 4);
+ return (index >= 4)? false : ((Bits & (1<<index)) != 0); }
+ } LED;
+
+ BYTE BatteryRaw; // 0 - ~200 (it seems 200 *may* be the maximum charge)
+ BYTE BatteryPercent; // (using the above assumption, where 200 raw = 100%)
+ bool bBatteryDrained; // battery is nearly flat
+ bool bRumble;
+ bool bExtension; // an extension (eg. Nunchuk) is connected.
+
+ // speaker state:
+ struct speaker
+ {
+ bool bEnabled;
+ bool bMuted;
+ speaker_freq Freq;
+ BYTE Volume;
+ } Speaker;
+
+ // the extension plugged into the Wiimote (if any)
+ enum extension_type
+ {
+ NONE = 0,
+ NUNCHUK,
+ CLASSIC,
+ GH3_GHWT_GUITAR, // GH3 or GHWT Guitar (treated as Classic)
+ GHWT_DRUMS, // not yet used
+ BALANCE_BOARD,
+ MOTION_PLUS,
+ PARTIALLY_INSERTED,
+ };
+ extension_type ExtensionType;
+
+ // joystick struct (shared between Nunchuk & Classic Controller)
+ struct joystick
+ {
+ friend class wiimote;
+
+ // raw unprocessed coordinates:
+ float RawX, RawY;
+
+ // processed coordinates in approximately -1 - +1 range (includes calibration
+ // data and deadzones) - note that due to calibration inaccuracies, the
+ // extremes may be slightly over/under (+-)1.0.
+ float X, Y;
+
+ // a 'deadzone' is a user-defined range near the joystick center which
+ // is treated as zero (joysticks often drift a little even at the center
+ // position). you can set a deadzone for each axis at any time, range is
+ // 0.0 (off) to 1.0 (entire range - not useful :). try 0.03.
+ struct deadzone
+ {
+ float X, Y;
+ } DeadZone;
+ };
+
+ // Nunchuk state (if connected)
+ struct nunchuk
+ {
+ struct calibration_info
+ {
+ BYTE X0, Y0, Z0;
+ BYTE XG, YG, ZG;
+ BYTE MinX, MidX, MaxX;
+ BYTE MinY, MidY, MaxY;
+ } CalibrationInfo;
+
+ acceleration Acceleration;
+ joystick Joystick;
+ bool C;
+ bool Z;
+ } Nunchuk;
+
+ // Classic Controller state (if connected)
+ struct classic_controller
+ {
+ // calibration information (stored on the controller)
+ struct calibration_info
+ {
+ BYTE MinXL, MidXL, MaxXL;
+ BYTE MinYL, MidYL, MaxYL;
+ BYTE MinXR, MidXR, MaxXR;
+ BYTE MinYR, MidYR, MaxYR;
+ BYTE MinTriggerL, MaxTriggerL;
+ BYTE MinTriggerR, MaxTriggerR;
+ } CalibrationInfo;
+
+ // button state
+ struct buttons
+ {
+ // convenience accessors
+ inline bool A () const { return (Bits & _A) != 0; }
+ inline bool B () const { return (Bits & _B) != 0; }
+ inline bool Plus () const { return (Bits & PLUS) != 0; }
+ inline bool Minus () const { return (Bits & MINUS) != 0; }
+ inline bool Home () const { return (Bits & HOME) != 0; }
+ inline bool Up () const { return (Bits & UP) != 0; }
+ inline bool Down () const { return (Bits & DOWN) != 0; }
+ inline bool Left () const { return (Bits & LEFT) != 0; }
+ inline bool Right () const { return (Bits & RIGHT) != 0; }
+ inline bool X () const { return (Bits & _X) != 0; }
+ inline bool Y () const { return (Bits & _Y) != 0; }
+ inline bool ZL () const { return (Bits & _ZL) != 0; }
+ inline bool ZR () const { return (Bits & _ZR) != 0; }
+ inline bool TriggerL () const { return (Bits & TRIG_L) != 0; }
+ inline bool TriggerR () const { return (Bits & TRIG_R) != 0; }
+
+ // all 15 buttons stored as bits (set = pressed)
+ WORD Bits;
+
+ // button bitmasks (little-endian order)
+ enum mask
+ {
+ TRIG_R = 0x0002,
+ PLUS = 0x0004,
+ HOME = 0x0008,
+ MINUS = 0x0010,
+ TRIG_L = 0x0020,
+ DOWN = 0x0040,
+ RIGHT = 0x0080,
+ UP = 0x0100,
+ LEFT = 0x0200,
+ _ZR = 0x0400,
+ _X = 0x0800,
+ _A = 0x1000,
+ _Y = 0x2000,
+ _B = 0x4000,
+ _ZL = 0x8000,
+ //
+ ALL = TRIG_R|PLUS|HOME|MINUS|TRIG_L|DOWN|RIGHT|UP|LEFT|
+ _ZR|_X|_A|_Y|_B|_ZL,
+ };
+ } Button;
+
+ // joysticks
+ joystick JoystickL;
+ joystick JoystickR;
+
+ // triggers
+ BYTE RawTriggerL, RawTriggerR;
+ float TriggerL, TriggerR;
+ } ClassicController;
+
+ struct balance_board
+ {
+ // values for each of the board's 4 sensors:
+ // (these values are always exposed unmodifed)
+ struct sensors_raw
+ {
+ short TopR;
+ short TopL;
+ short BottomR;
+ short BottomL;
+ };
+ struct sensors_f
+ {
+ float TopL;
+ float TopR;
+ float BottomL;
+ float BottomR;
+
+ float Total; // sum of the 4 corner weights
+ };
+
+ // calibration info
+ struct calibration_info
+ {
+ sensors_raw Kg0; // calibration at 0 Kg
+ sensors_raw Kg17; // " 17 Kg
+ sensors_raw Kg34; // " 34 Kg
+ } CalibrationInfo;
+
+ // state:
+ sensors_raw Raw; // raw values (per sensor)
+ sensors_f AtRestKg; // set by Connect() and CalibrateAtRest()
+ // (the values below have their 'at-rest' offsets automatically removed)
+ sensors_f Kg; // kilograms (per sensor)
+ sensors_f Lb; // pounds (per sensor)
+ } BalanceBoard;
+
+ struct motion_plus
+ {
+ // (these values are always exposed unmodifed)
+ struct sensors_raw
+ {
+ short Yaw;
+ short Pitch;
+ short Roll;
+ };
+ struct sensors_f
+ {
+ float Yaw;
+ float Pitch;
+ float Roll;
+ };
+
+ // state:
+ sensors_raw Raw;
+ sensors_f Speed;
+ } MotionPlus;
+
+ // ---- internal use only ----
+ protected:
+ unsigned WiimoteNearGUpdates;
+ unsigned NunchukNearGUpdates;
+
+ void Clear (bool including_deadzones)
+ {
+ joystick::deadzone nunchuk_deadzone,
+ classic_joyl_deadzone,
+ classic_joyr_deadzone;
+
+ // preserve the deadzone settings?
+ if(!including_deadzones) {
+ nunchuk_deadzone = Nunchuk.Joystick.DeadZone;
+ classic_joyl_deadzone = ClassicController.JoystickL.DeadZone;
+ classic_joyr_deadzone = ClassicController.JoystickR.DeadZone;
+ }
+
+ memset(this, 0, sizeof(wiimote_state));
+
+ // restore the deadzones?
+ if(!including_deadzones) {
+ Nunchuk.Joystick.DeadZone = nunchuk_deadzone;
+ ClassicController.JoystickL.DeadZone = classic_joyl_deadzone;
+ ClassicController.JoystickR.DeadZone = classic_joyr_deadzone;
+ }
+ }
+ };
+
+#endif // _WIIMOTE_STATE_H \ No newline at end of file