@@ -121,30 +121,30 @@ void parseReadData(const u8* data, DataCallback callback, RegisterType reg)
121
121
callback (data + 6 );
122
122
}
123
123
124
- bool Wiimote::setReportMode (ReportMode mode)
125
- {
126
- _lock.lock ();
127
- _state.reportMode = mode;
128
- _lock.unlock ();
124
+ void Wiimote::start (int featureFlags)
125
+ {
126
+ if (_running)
127
+ {
128
+ std::cout << " Already running" << std::endl;
129
+ return ;
130
+ }
129
131
130
- return _device->write (DataBuffer ({ OutputReportType::DataReportMode, 0x00 , mode }));
131
- }
132
+ _features = featureFlags;
132
133
133
- bool Wiimote::resetReportMode ()
134
- {
135
- _lock.lock ();
136
- ReportMode mode = _state.reportMode ;
137
- _lock.unlock ();
134
+ updateStatus ();
135
+ updateWiimoteCalibration ();
136
+ identifyMotionPlus ();
138
137
139
- return _device->write ( DataBuffer ({ OutputReportType::DataReportMode, 0x00 , mode }) );
138
+ _device->startReader ( );
140
139
}
141
140
142
- void Wiimote::start (ReportMode mode )
141
+ void Wiimote::stop ( )
143
142
{
144
- setReportMode (mode);
145
- updateWiimoteCalibration ();
146
- identifyMotionPlus ();
147
- _device->startReader ();
143
+ if (!_running)
144
+ {
145
+ _device->stopReader ();
146
+ _running = false ;
147
+ }
148
148
}
149
149
150
150
bool Wiimote::setLeds (LedState state)
@@ -169,16 +169,8 @@ bool Wiimote::setRumble(bool rumble)
169
169
170
170
bool Wiimote::updateStatus ()
171
171
{
172
- _expectingStatusUpdate = true ;
173
- u8 s = (_state.rumble == true ? 0x01 : 0x00 );
174
-
175
- if (!_device->write (DataBuffer ({ OutputReportType::Status, s })))
176
- {
177
- _expectingStatusUpdate = false ;
178
- return false ;
179
- }
180
-
181
- return true ;
172
+ u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00 );
173
+ return _device->write (DataBuffer ({ OutputReportType::Status, s }));
182
174
}
183
175
184
176
void Wiimote::updateWiimoteCalibration ()
@@ -212,8 +204,70 @@ void Wiimote::updateNunchuckCalibration()
212
204
});
213
205
}
214
206
207
+ #define SET_FLAG (flags, flag ) flags |= flag
208
+ #define UNSET_FLAG (flags, flag ) flags &= ~flag
209
+
210
+ bool Wiimote::updateReportMode ()
211
+ {
212
+ _state.reportMode = ReportModes::Unknown;
213
+
214
+ int features = _features;
215
+
216
+ if (!_state.extensionActive )
217
+ {
218
+ UNSET_FLAG (features, WiimoteFeatures::Extension);
219
+ }
220
+
221
+ if (_features | WiimoteFeatures::MotionPlus && _state.motionPlusActive )
222
+ {
223
+ SET_FLAG (features, WiimoteFeatures::Extension);
224
+ }
225
+
226
+ UNSET_FLAG (features, WiimoteFeatures::MotionPlus);
227
+
228
+ switch (features)
229
+ {
230
+ case WiimoteFeatures::Buttons:
231
+ _state.reportMode = ReportModes::Buttons;
232
+ break ;
233
+ case WiimoteFeatures::Buttons | WiimoteFeatures::Accelerometer:
234
+ _state.reportMode = ReportModes::ButtonsAccel;
235
+ break ;
236
+ case WiimoteFeatures::Buttons | WiimoteFeatures::Extension:
237
+ _state.reportMode = ReportModes::ButtonsExtension19;
238
+ break ;
239
+ case WiimoteFeatures::Buttons | WiimoteFeatures::Accelerometer | WiimoteFeatures::IR:
240
+ _state.reportMode = ReportModes::ButtonsAccelIR;
241
+ break ;
242
+ case WiimoteFeatures::Buttons | WiimoteFeatures::Accelerometer | WiimoteFeatures::Extension:
243
+ _state.reportMode = ReportModes::ButtonsAccelExtension;
244
+ break ;
245
+ case WiimoteFeatures::Buttons | WiimoteFeatures::IR | WiimoteFeatures::Extension:
246
+ _state.reportMode = ReportModes::ButtonsIRExtension;
247
+ break ;
248
+ case WiimoteFeatures::Buttons | WiimoteFeatures::Accelerometer | WiimoteFeatures::IR | WiimoteFeatures::Extension:
249
+ _state.reportMode = ReportModes::ButtonsAccelIRExtension;
250
+ break ;
251
+ case WiimoteFeatures::Extension:
252
+ _state.reportMode = ReportModes::Extension;
253
+ break ;
254
+ default :
255
+ _state.reportMode = ReportModes::ButtonsAccelExtension;
256
+ std::cout << " Unable to find an appropriate report mode, defaulting to ButtonsAccelExtension" << std::endl;
257
+ }
258
+
259
+ std::cout << " Setting report mode: " << ReportModes::toString (_state.reportMode ) << std::endl;
260
+
261
+ return _device->write (DataBuffer ({ OutputReportType::DataReportMode, 0x00 , _state.reportMode }));
262
+ }
263
+
215
264
void Wiimote::updateExtension ()
216
265
{
266
+ if (_state.extensionConnected == false )
267
+ {
268
+ _state.extensionActive = false ;
269
+ }
270
+
217
271
readRegister (RegisterTypes::ExtensionType2, 1 , [this ](const u8* d) {
218
272
bool motionPlus = d[0 ] == 0x04 ;
219
273
@@ -228,6 +282,7 @@ void Wiimote::updateExtension()
228
282
} else {
229
283
if (_state.extensionType != ExtensionTypes::None)
230
284
{
285
+ _state.extensionActive = false ;
231
286
std::cout << ExtensionTypes::toString (_state.extensionType ) << " disconnected" << std::endl;
232
287
}
233
288
@@ -265,18 +320,19 @@ void Wiimote::identifyExtension()
265
320
case ExtensionTypes::Drums:
266
321
case ExtensionTypes::TaikoDrum:
267
322
_state.extensionConnected = true ;
323
+ _state.extensionActive = true ;
268
324
_state.extensionType = (ExtensionType)type;
269
325
270
326
std::cout << ExtensionTypes::toString (_state.extensionType ) << " connected" << std::endl;
271
- writeReportMode (ReportModes::ButtonsAccelExtension );
327
+ updateReportMode ( );
272
328
273
329
break ;
274
330
case ExtensionTypes::MotionPlus:
275
331
case ExtensionTypes::MotionPlus_TR:
276
332
if (!_state.motionPlusActive )
277
333
{
278
334
_state.motionPlusActive = true ;
279
- writeReportMode (ReportModes::ButtonsExtension19 );
335
+ updateReportMode ( );
280
336
std::cout << " Motion plus active" << std::endl;
281
337
}
282
338
@@ -301,18 +357,18 @@ void Wiimote::identifyMotionPlus()
301
357
if (d[0 ] == 0x01 )
302
358
{
303
359
_state.wiimoteType = WiimoteTypes::WiimotePlus;
304
- _state.motionPlusAttached = true ;
360
+ _state.motionPlusAvailable = true ;
305
361
} else {
306
362
for (int x = 0 ; x < 6 ; x++)
307
363
{
308
364
if (x != 4 && x != 0 && d[x] != ID_InactiveMotionPlus[x])
309
365
{
310
- _state.motionPlusAttached = false ;
366
+ _state.motionPlusAvailable = false ;
311
367
return ;
312
368
}
313
369
}
314
370
315
- _state.motionPlusAttached = true ;
371
+ _state.motionPlusAvailable = true ;
316
372
}
317
373
});
318
374
}
@@ -397,12 +453,10 @@ void Wiimote::onMessage(const u8* b)
397
453
398
454
case InputReportTypes::Status:
399
455
{
400
- if (!_expectingStatusUpdate) writeReportMode (_state.reportMode );
401
- _expectingStatusUpdate = false ;
402
-
403
456
parseButtons (b, _state);
404
457
parseStatus (b, _state);
405
458
updateExtension ();
459
+ updateReportMode ();
406
460
}
407
461
}
408
462
@@ -411,11 +465,11 @@ void Wiimote::onMessage(const u8* b)
411
465
if (_state.motionPlus .extensionConnected )
412
466
{
413
467
std::cout << " Extension connected" << std::endl;
414
- updateExtension ();
415
468
} else {
416
469
std::cout << " Extension disconnected" << std::endl;
417
- updateExtension ();
418
470
}
471
+
472
+ updateExtension ();
419
473
}
420
474
421
475
if (_currentRead == nullptr && !_pendingReads.empty ())
@@ -430,10 +484,27 @@ void Wiimote::onMessage(const u8* b)
430
484
_lock.unlock ();
431
485
}
432
486
433
- bool Wiimote::writeReportMode (ReportMode mode )
487
+ void Wiimote::update ( )
434
488
{
435
- _state.reportMode = mode;
436
- return _device->write (DataBuffer ({ OutputReportType::DataReportMode, 0x00 , mode }));
489
+ const WiimoteState& old = _outState[_outStateIdx];
490
+ WiimoteState& next = _outState[1 - _outStateIdx];
491
+
492
+ _lock.lock ();
493
+ memcpy (&next, &_state, sizeof (WiimoteState));
494
+ _lock.unlock ();
495
+
496
+ if (_buttonCallback != nullptr )
497
+ {
498
+ for (int i = 0 ; i < c_WiimoteButtonCount; ++i)
499
+ {
500
+ if (next.buttons [i] != old.buttons [i])
501
+ {
502
+ _buttonCallback ((WiimoteButton)i, next.buttons [i]);
503
+ }
504
+ }
505
+ }
506
+
507
+ _outStateIdx = 1 - _outStateIdx;
437
508
}
438
509
439
510
bool Wiimote::activateExtension ()
@@ -451,7 +522,7 @@ bool Wiimote::activateExtension()
451
522
452
523
bool Wiimote::activateMotionPlus ()
453
524
{
454
- if (!_state.motionPlusAttached )
525
+ if (!_state.motionPlusAvailable )
455
526
{
456
527
std::cout << " There is a request to activate the Wii Motion Plus even though it has not been confirmed to exist! Trying anyway..." << std::endl;
457
528
}
0 commit comments