1 |
// _______________________________________________________________________________
|
2 |
//
|
3 |
// - WiiYourself! - native C++ Wiimote library v1.15
|
4 |
// (c) gl.tter 2007-10 - http://gl.tter.org
|
5 |
//
|
6 |
// see License.txt for conditions of use. see History.txt for change log.
|
7 |
// _______________________________________________________________________________
|
8 |
//
|
9 |
// wiimote_state.h (tab = 4 spaces)
|
10 |
|
11 |
// the 'wiimote_state' struct contains all the Wiimote and Extension state data
|
12 |
// (buttons etc) - the wiimote class inherits from this and the app can poll
|
13 |
// the data there at any time.
|
14 |
#ifdef _MSC_VER // VC
|
15 |
# pragma once
|
16 |
#endif
|
17 |
|
18 |
#ifndef _WIIMOTE_STATE_H
|
19 |
# define _WIIMOTE_STATE_H
|
20 |
|
21 |
#include "wiimote_common.h"
|
22 |
|
23 |
|
24 |
// wiimote_state (contains the Wiimote and Extension data and settings)
|
25 |
struct wiimote_state
|
26 |
{
|
27 |
friend class wiimote; // for Clear()
|
28 |
|
29 |
// calibration information (stored on the Wiimote)
|
30 |
struct calibration_info
|
31 |
{
|
32 |
BYTE X0, Y0, Z0;
|
33 |
BYTE XG, YG, ZG;
|
34 |
} CalibrationInfo;
|
35 |
|
36 |
// button state:
|
37 |
struct buttons
|
38 |
{
|
39 |
// convenience accessors
|
40 |
inline bool A () const { return (Bits & _A) != 0; }
|
41 |
inline bool B () const { return (Bits & _B) != 0; }
|
42 |
inline bool Plus () const { return (Bits & PLUS) != 0; }
|
43 |
inline bool Home () const { return (Bits & HOME) != 0; }
|
44 |
inline bool Minus () const { return (Bits & MINUS) != 0; }
|
45 |
inline bool One () const { return (Bits & ONE) != 0; }
|
46 |
inline bool Two () const { return (Bits & TWO) != 0; }
|
47 |
inline bool Up () const { return (Bits & UP) != 0; }
|
48 |
inline bool Down () const { return (Bits & DOWN) != 0; }
|
49 |
inline bool Left () const { return (Bits & LEFT) != 0; }
|
50 |
inline bool Right () const { return (Bits & RIGHT) != 0; }
|
51 |
|
52 |
// all 11 buttons stored as bits (set = pressed)
|
53 |
WORD Bits;
|
54 |
|
55 |
// button bit masks (little-endian order)
|
56 |
enum mask
|
57 |
{
|
58 |
LEFT = 0x0001,
|
59 |
RIGHT = 0x0002,
|
60 |
DOWN = 0x0004,
|
61 |
UP = 0x0008,
|
62 |
PLUS = 0x0010,
|
63 |
TWO = 0x0100,
|
64 |
ONE = 0x0200,
|
65 |
_B = 0x0400, // ie. trigger
|
66 |
_A = 0x0800,
|
67 |
MINUS = 0x1000,
|
68 |
HOME = 0x8000,
|
69 |
//
|
70 |
ALL = LEFT|RIGHT|DOWN|UP|PLUS|TWO|ONE|_A|_B|MINUS|HOME,
|
71 |
};
|
72 |
} Button;
|
73 |
|
74 |
// accelerometers state:
|
75 |
struct acceleration
|
76 |
{
|
77 |
BYTE RawX, RawY, RawZ;
|
78 |
float X, Y, Z;
|
79 |
|
80 |
// note: experimental! the orientation values can only be safely estimated
|
81 |
// if the controller isn't accelerating (otherwise there is no
|
82 |
// simple way to seperate orientation from acceleration - except
|
83 |
// perhaps using the IR reference and/or some clever assumptions).
|
84 |
// so for now the code only updates orientation if the controller
|
85 |
// appear to be stationary (by checking if the acceleration vector
|
86 |
// length is near 1G for several updates in a row).
|
87 |
// also note that there is no way to detect Yaw from the accelerometer
|
88 |
// alone when it's pointing at the screen (and I'm not curently
|
89 |
// processing IR):
|
90 |
struct orientation
|
91 |
{
|
92 |
float X, Y, Z;
|
93 |
unsigned UpdateAge; // how many acceleration updates ago the last
|
94 |
// orientation estimate was made (if this
|
95 |
// value is high, the values are out-of-date
|
96 |
// and probably shouldn't be used).
|
97 |
// Euler angle support (useful for some things).
|
98 |
// * note that decomposing to Euler angles is complex, not always reliable,
|
99 |
// and also depends on your assumptions about the order each component
|
100 |
// is applied in. you may need to handle this yourself for more
|
101 |
// complex scenarios *
|
102 |
float Pitch; // in degrees (-180 - +180)
|
103 |
float Roll; // "
|
104 |
// float Yaw;
|
105 |
} Orientation;
|
106 |
} Acceleration;
|
107 |
|
108 |
// IR camera state:
|
109 |
struct ir
|
110 |
{
|
111 |
// in theory the IR imager is 1024x768 and so should report raw coords
|
112 |
// 0-1023 x 0-767. in practice I have never seen them exceed the values
|
113 |
// below, so I'm using them instead to give the full 0-1 float range
|
114 |
// (it's possible that the edge pixels are used for processing, or masked
|
115 |
// out due to being unreliable). let me know if your wiimote reports
|
116 |
// a different range.
|
117 |
static const unsigned MAX_RAW_X = 1016;
|
118 |
static const unsigned MAX_RAW_Y = 760;
|
119 |
|
120 |
// data mode reported by the IR sensor
|
121 |
enum mode
|
122 |
{
|
123 |
OFF = 0x00,
|
124 |
BASIC = 0x01, // 10 bytes
|
125 |
EXTENDED = 0x03, // 12 bytes
|
126 |
FULL = 0x05, // 16 bytes * 2 (format unknown)
|
127 |
};
|
128 |
|
129 |
mode Mode; // read-only (depends on ReportType set)
|
130 |
|
131 |
struct dot
|
132 |
{
|
133 |
bool bVisible; // other values are not valid if == false
|
134 |
unsigned RawX;
|
135 |
unsigned RawY;
|
136 |
float X; // 0-1 (left-right)
|
137 |
float Y; // " (top -bottom)
|
138 |
int Size; // (not available in BASIC mode)
|
139 |
} Dot[4];
|
140 |
} IR;
|
141 |
|
142 |
struct leds
|
143 |
{
|
144 |
// all LEDs stored in bits 0-3 (1 = lit)
|
145 |
BYTE Bits;
|
146 |
|
147 |
// convenience accessors:
|
148 |
inline bool Lit (unsigned index)
|
149 |
{ _ASSERT(index < 4);
|
150 |
return (index >= 4)? false : ((Bits & (1<<index)) != 0); }
|
151 |
} LED;
|
152 |
|
153 |
BYTE BatteryRaw; // 0 - ~200 (it seems 200 *may* be the maximum charge)
|
154 |
BYTE BatteryPercent; // (using the above assumption, where 200 raw = 100%)
|
155 |
bool bBatteryDrained; // battery is nearly flat
|
156 |
bool bRumble;
|
157 |
bool bExtension; // an extension (eg. Nunchuk) is connected.
|
158 |
|
159 |
// speaker state:
|
160 |
struct speaker
|
161 |
{
|
162 |
bool bEnabled;
|
163 |
bool bMuted;
|
164 |
speaker_freq Freq;
|
165 |
BYTE Volume;
|
166 |
} Speaker;
|
167 |
|
168 |
// the extension plugged into the Wiimote (if any)
|
169 |
enum extension_type
|
170 |
{
|
171 |
NONE = 0,
|
172 |
NUNCHUK,
|
173 |
CLASSIC,
|
174 |
GH3_GHWT_GUITAR, // GH3 or GHWT Guitar (treated as Classic)
|
175 |
GHWT_DRUMS, // not yet used
|
176 |
BALANCE_BOARD,
|
177 |
MOTION_PLUS,
|
178 |
PARTIALLY_INSERTED,
|
179 |
};
|
180 |
extension_type ExtensionType;
|
181 |
|
182 |
// joystick struct (shared between Nunchuk & Classic Controller)
|
183 |
struct joystick
|
184 |
{
|
185 |
friend class wiimote;
|
186 |
|
187 |
// raw unprocessed coordinates:
|
188 |
float RawX, RawY;
|
189 |
|
190 |
// processed coordinates in approximately -1 - +1 range (includes calibration
|
191 |
// data and deadzones) - note that due to calibration inaccuracies, the
|
192 |
// extremes may be slightly over/under (+-)1.0.
|
193 |
float X, Y;
|
194 |
|
195 |
// a 'deadzone' is a user-defined range near the joystick center which
|
196 |
// is treated as zero (joysticks often drift a little even at the center
|
197 |
// position). you can set a deadzone for each axis at any time, range is
|
198 |
// 0.0 (off) to 1.0 (entire range - not useful :). try 0.03.
|
199 |
struct deadzone
|
200 |
{
|
201 |
float X, Y;
|
202 |
} DeadZone;
|
203 |
};
|
204 |
|
205 |
// Nunchuk state (if connected)
|
206 |
struct nunchuk
|
207 |
{
|
208 |
struct calibration_info
|
209 |
{
|
210 |
BYTE X0, Y0, Z0;
|
211 |
BYTE XG, YG, ZG;
|
212 |
BYTE MinX, MidX, MaxX;
|
213 |
BYTE MinY, MidY, MaxY;
|
214 |
} CalibrationInfo;
|
215 |
|
216 |
acceleration Acceleration;
|
217 |
joystick Joystick;
|
218 |
bool C;
|
219 |
bool Z;
|
220 |
} Nunchuk;
|
221 |
|
222 |
// Classic Controller state (if connected)
|
223 |
struct classic_controller
|
224 |
{
|
225 |
// calibration information (stored on the controller)
|
226 |
struct calibration_info
|
227 |
{
|
228 |
BYTE MinXL, MidXL, MaxXL;
|
229 |
BYTE MinYL, MidYL, MaxYL;
|
230 |
BYTE MinXR, MidXR, MaxXR;
|
231 |
BYTE MinYR, MidYR, MaxYR;
|
232 |
BYTE MinTriggerL, MaxTriggerL;
|
233 |
BYTE MinTriggerR, MaxTriggerR;
|
234 |
} CalibrationInfo;
|
235 |
|
236 |
// button state
|
237 |
struct buttons
|
238 |
{
|
239 |
// convenience accessors
|
240 |
inline bool A () const { return (Bits & _A) != 0; }
|
241 |
inline bool B () const { return (Bits & _B) != 0; }
|
242 |
inline bool Plus () const { return (Bits & PLUS) != 0; }
|
243 |
inline bool Minus () const { return (Bits & MINUS) != 0; }
|
244 |
inline bool Home () const { return (Bits & HOME) != 0; }
|
245 |
inline bool Up () const { return (Bits & UP) != 0; }
|
246 |
inline bool Down () const { return (Bits & DOWN) != 0; }
|
247 |
inline bool Left () const { return (Bits & LEFT) != 0; }
|
248 |
inline bool Right () const { return (Bits & RIGHT) != 0; }
|
249 |
inline bool X () const { return (Bits & _X) != 0; }
|
250 |
inline bool Y () const { return (Bits & _Y) != 0; }
|
251 |
inline bool ZL () const { return (Bits & _ZL) != 0; }
|
252 |
inline bool ZR () const { return (Bits & _ZR) != 0; }
|
253 |
inline bool TriggerL () const { return (Bits & TRIG_L) != 0; }
|
254 |
inline bool TriggerR () const { return (Bits & TRIG_R) != 0; }
|
255 |
|
256 |
// all 15 buttons stored as bits (set = pressed)
|
257 |
WORD Bits;
|
258 |
|
259 |
// button bitmasks (little-endian order)
|
260 |
enum mask
|
261 |
{
|
262 |
TRIG_R = 0x0002,
|
263 |
PLUS = 0x0004,
|
264 |
HOME = 0x0008,
|
265 |
MINUS = 0x0010,
|
266 |
TRIG_L = 0x0020,
|
267 |
DOWN = 0x0040,
|
268 |
RIGHT = 0x0080,
|
269 |
UP = 0x0100,
|
270 |
LEFT = 0x0200,
|
271 |
_ZR = 0x0400,
|
272 |
_X = 0x0800,
|
273 |
_A = 0x1000,
|
274 |
_Y = 0x2000,
|
275 |
_B = 0x4000,
|
276 |
_ZL = 0x8000,
|
277 |
//
|
278 |
ALL = TRIG_R|PLUS|HOME|MINUS|TRIG_L|DOWN|RIGHT|UP|LEFT|
|
279 |
_ZR|_X|_A|_Y|_B|_ZL,
|
280 |
};
|
281 |
} Button;
|
282 |
|
283 |
// joysticks
|
284 |
joystick JoystickL;
|
285 |
joystick JoystickR;
|
286 |
|
287 |
// triggers
|
288 |
BYTE RawTriggerL, RawTriggerR;
|
289 |
float TriggerL, TriggerR;
|
290 |
} ClassicController;
|
291 |
|
292 |
struct balance_board
|
293 |
{
|
294 |
// values for each of the board's 4 sensors:
|
295 |
// (these values are always exposed unmodifed)
|
296 |
struct sensors_raw
|
297 |
{
|
298 |
short TopR;
|
299 |
short TopL;
|
300 |
short BottomR;
|
301 |
short BottomL;
|
302 |
};
|
303 |
struct sensors_f
|
304 |
{
|
305 |
float TopL;
|
306 |
float TopR;
|
307 |
float BottomL;
|
308 |
float BottomR;
|
309 |
|
310 |
float Total; // sum of the 4 corner weights
|
311 |
};
|
312 |
|
313 |
// calibration info
|
314 |
struct calibration_info
|
315 |
{
|
316 |
sensors_raw Kg0; // calibration at 0 Kg
|
317 |
sensors_raw Kg17; // " 17 Kg
|
318 |
sensors_raw Kg34; // " 34 Kg
|
319 |
} CalibrationInfo;
|
320 |
|
321 |
// state:
|
322 |
sensors_raw Raw; // raw values (per sensor)
|
323 |
sensors_f AtRestKg; // set by Connect() and CalibrateAtRest()
|
324 |
// (the values below have their 'at-rest' offsets automatically removed)
|
325 |
sensors_f Kg; // kilograms (per sensor)
|
326 |
sensors_f Lb; // pounds (per sensor)
|
327 |
} BalanceBoard;
|
328 |
|
329 |
struct motion_plus
|
330 |
{
|
331 |
// (these values are always exposed unmodifed)
|
332 |
struct sensors_raw
|
333 |
{
|
334 |
short Yaw;
|
335 |
short Pitch;
|
336 |
short Roll;
|
337 |
};
|
338 |
struct sensors_f
|
339 |
{
|
340 |
float Yaw;
|
341 |
float Pitch;
|
342 |
float Roll;
|
343 |
};
|
344 |
|
345 |
// state:
|
346 |
sensors_raw Raw;
|
347 |
sensors_f Speed;
|
348 |
} MotionPlus;
|
349 |
|
350 |
// ---- internal use only ----
|
351 |
protected:
|
352 |
unsigned WiimoteNearGUpdates;
|
353 |
unsigned NunchukNearGUpdates;
|
354 |
|
355 |
void Clear (bool including_deadzones)
|
356 |
{
|
357 |
joystick::deadzone nunchuk_deadzone,
|
358 |
classic_joyl_deadzone,
|
359 |
classic_joyr_deadzone;
|
360 |
|
361 |
// preserve the deadzone settings?
|
362 |
if(!including_deadzones) {
|
363 |
nunchuk_deadzone = Nunchuk.Joystick.DeadZone;
|
364 |
classic_joyl_deadzone = ClassicController.JoystickL.DeadZone;
|
365 |
classic_joyr_deadzone = ClassicController.JoystickR.DeadZone;
|
366 |
}
|
367 |
|
368 |
memset(this, 0, sizeof(wiimote_state));
|
369 |
|
370 |
// restore the deadzones?
|
371 |
if(!including_deadzones) {
|
372 |
Nunchuk.Joystick.DeadZone = nunchuk_deadzone;
|
373 |
ClassicController.JoystickL.DeadZone = classic_joyl_deadzone;
|
374 |
ClassicController.JoystickR.DeadZone = classic_joyr_deadzone;
|
375 |
}
|
376 |
}
|
377 |
};
|
378 |
|
379 |
#endif // _WIIMOTE_STATE_H |