// _______________________________________________________________________________ // // - WiiYourself! - native C++ Wiimote library v1.00 // (c) gl.tter 2007-8 - 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 // speaker support: enum speaker_freq { // (keep in sync with FreqLookup in wiimote.cpp) FREQ_NONE = 0, // my PC can't keep up with these using bUseHIDwrite, so I haven't // been able to tune them yet FREQ_4200HZ = 1, FREQ_3920HZ = 2, FREQ_3640HZ = 3, FREQ_3360HZ = 4, // these were tuned until the square-wave was glitch-free on my remote - // may not be exactly right FREQ_3130HZ = 5, // +190 FREQ_2940HZ = 6, // +180 FREQ_2760HZ = 7, // +150 FREQ_2610HZ = 8, // +140 FREQ_2470HZ = 9, }; // wiimote_sample - holds the audio sample in the native wiimote format struct wiimote_sample { wiimote_sample() : samples(NULL), length(0), freq(FREQ_NONE) {} BYTE* samples; DWORD length; speaker_freq freq; }; // flags & masks that indicate which part(s) of the wiimote state have changed enum state_change_flags { // state didn't change at all NO_CHANGE = 0, // Wiimote specific CONNECTION_LOST = 1<<0, BATTERY_CHANGED = 1<<1, LEDS_CHANGED = 1<<2, // (probably redudant as wiimmote never BUTTONS_CHANGED = 1<<3, // changes them unless requested) ACCEL_CHANGED = 1<<4, ORIENTATION_CHANGED = 1<<5, IR_CHANGED = 1<<6, // all wiimote flags WIIMOTE_CHANGED = CONNECTION_LOST|BATTERY_CHANGED|LEDS_CHANGED| BUTTONS_CHANGED|ACCEL_CHANGED|ORIENTATION_CHANGED| IR_CHANGED, // Extensions - general EXTENSION_DISCONNECTED = 1<<7, EXTENSION_PARTIALLY_INSERTED = 1<<8, // Nunchuk specific NUNCHUK_CONNECTED = 1<<9, NUNCHUK_BUTTONS_CHANGED = 1<<10, NUNCHUK_ACCEL_CHANGED = 1<<11, NUNCHUK_ORIENTATION_CHANGED = 1<<12, NUNCHUK_JOYSTICK_CHANGED = 1<<13, // all flags NUNCHUK_CHANGED = NUNCHUK_CONNECTED|NUNCHUK_BUTTONS_CHANGED| NUNCHUK_ACCEL_CHANGED|NUNCHUK_ORIENTATION_CHANGED| NUNCHUK_JOYSTICK_CHANGED, // Classic Controller CLASSIC_CONNECTED = 1<<14, CLASSIC_BUTTONS_CHANGED = 1<<15, CLASSIC_JOYSTICK_L_CHANGED = 1<<16, CLASSIC_JOYSTICK_R_CHANGED = 1<<17, CLASSIC_TRIGGERS_CHANGED = 1<<18, // all flags CLASSIC_CHANGED = CLASSIC_CONNECTED|CLASSIC_BUTTONS_CHANGED| CLASSIC_JOYSTICK_L_CHANGED| CLASSIC_JOYSTICK_R_CHANGED|CLASSIC_TRIGGERS_CHANGED, // ALL extension-related flags EXTENSION_CHANGED = EXTENSION_DISCONNECTED| NUNCHUK_CHANGED|CLASSIC_CHANGED, // ALL flags CHANGED_ALL = WIIMOTE_CHANGED|EXTENSION_CHANGED, }; // 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) 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; struct dot { bool bFound; // wiimote can see it 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<