4
4
#include < iostream>
5
5
6
6
#define CHECK_MASK (val, mask ) ((val & mask) != 0x00 )
7
+ #define SET_FLAG (flags, flag ) flags |= flag
8
+ #define UNSET_FLAG (flags, flag ) flags &= ~flag
7
9
8
10
static const int64_t ID_ActiveMotionPlus = 0x0000A4200405 ;
9
11
static const int64_t ID_ActiveMotionPlus_Nunchuck = 0x0000A4200505 ;
@@ -121,7 +123,21 @@ void parseReadData(const u8* data, DataCallback callback, RegisterType reg)
121
123
callback (data + 6 );
122
124
}
123
125
124
- void Wiimote::start (int featureFlags)
126
+ void Wiimote::setID (int id)
127
+ {
128
+ _id = id;
129
+
130
+ _state.leds = LedStates::Off;
131
+ switch (id % 4 )
132
+ {
133
+ case 0 : _state.leds = LedStates::One; break ;
134
+ case 1 : _state.leds = LedStates::Two; break ;
135
+ case 2 : _state.leds = LedStates::Three; break ;
136
+ case 3 : _state.leds = LedStates::Four; break ;
137
+ }
138
+ }
139
+
140
+ void Wiimote::start (int featureFlags)
125
141
{
126
142
if (_running)
127
143
{
@@ -133,17 +149,16 @@ void Wiimote::start(int featureFlags)
133
149
134
150
updateStatus ();
135
151
updateWiimoteCalibration ();
136
- identifyMotionPlus ();
152
+ // identifyMotionPlus();
137
153
138
- _device-> startReader ();
154
+ startReader ();
139
155
}
140
156
141
- void Wiimote::stop ()
157
+ void Wiimote::stop ()
142
158
{
143
- if (! _running)
159
+ if (_running)
144
160
{
145
- _device->stopReader ();
146
- _running = false ;
161
+ stopReader ();
147
162
}
148
163
}
149
164
@@ -154,7 +169,7 @@ bool Wiimote::setLeds(LedState state)
154
169
u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00 );
155
170
_lock.unlock ();
156
171
157
- return _device->write (DataBuffer ({ OutputReportType ::LEDs, s }) );
172
+ return _device->write (buffer (OutputReportTypes ::LEDs, s), 2 );
158
173
}
159
174
160
175
bool Wiimote::setRumble (bool rumble)
@@ -164,13 +179,13 @@ bool Wiimote::setRumble(bool rumble)
164
179
u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00 );
165
180
_lock.unlock ();
166
181
167
- return _device->write (DataBuffer ({ OutputReportType ::LEDs, s }) );
182
+ return _device->write (buffer (OutputReportTypes ::LEDs, s), 2 );
168
183
}
169
184
170
185
bool Wiimote::updateStatus ()
171
186
{
172
187
u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00 );
173
- return _device->write (DataBuffer ({ OutputReportType ::Status, s }) );
188
+ return _device->write (buffer (OutputReportTypes ::Status, s), 2 );
174
189
}
175
190
176
191
void Wiimote::updateWiimoteCalibration ()
@@ -204,15 +219,13 @@ void Wiimote::updateNunchuckCalibration()
204
219
});
205
220
}
206
221
207
- #define SET_FLAG (flags, flag ) flags |= flag
208
- #define UNSET_FLAG (flags, flag ) flags &= ~flag
209
-
210
222
bool Wiimote::updateReportMode ()
211
223
{
212
- _state.reportMode = ReportModes::Unknown;
213
-
224
+ u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00 );
214
225
int features = _features;
215
226
227
+ _state.reportMode = ReportModes::Unknown;
228
+
216
229
if (!_state.extensionActive )
217
230
{
218
231
UNSET_FLAG (features, WiimoteFeatures::Extension);
@@ -258,7 +271,9 @@ bool Wiimote::updateReportMode()
258
271
259
272
std::cout << " Setting report mode: " << ReportModes::toString (_state.reportMode ) << std::endl;
260
273
261
- return _device->write (DataBuffer ({ OutputReportType::DataReportMode, 0x00 , _state.reportMode }));
274
+ u8* b = buffer (OutputReportTypes::DataReportMode, s);
275
+ b[2 ] = _state.reportMode ;
276
+ return _device->write (b, 3 );
262
277
}
263
278
264
279
void Wiimote::updateExtension ()
@@ -331,6 +346,7 @@ void Wiimote::identifyExtension()
331
346
case ExtensionTypes::MotionPlus_TR:
332
347
if (!_state.motionPlusActive )
333
348
{
349
+ _state.motionPlusAvailable = true ;
334
350
_state.motionPlusActive = true ;
335
351
updateReportMode ();
336
352
std::cout << " Motion plus active" << std::endl;
@@ -369,46 +385,49 @@ void Wiimote::identifyMotionPlus()
369
385
}
370
386
371
387
_state.motionPlusAvailable = true ;
372
- }
388
+ }
389
+
390
+ if (_state.motionPlusAvailable && !_state.motionPlusActive && (_features | WiimoteFeatures::MotionPlus))
391
+ {
392
+ activateMotionPlus ();
393
+ }
373
394
});
374
395
}
375
396
376
397
void Wiimote::readRegister (RegisterType type, short size, DataCallback callback)
377
398
{
378
- _pendingReads.push ({
379
- DataBuffer ({
380
- OutputReportTypes::Read,
381
- (u8)(((type & 0xff000000 ) >> 24 ) | (_state.rumble ? 0x01 : 0x00 )),
382
- (u8)((type & 0x00ff0000 ) >> 16 ),
383
- (u8)((type & 0x0000ff00 ) >> 8 ),
384
- (u8)(type & 0x000000ff ),
385
- (u8)((size & 0xff00 ) >> 8 ),
386
- (u8)(size & 0xff )
387
- }),
388
- callback,
389
- type
390
- });
391
- }
392
-
393
- bool Wiimote::writeRegister (RegisterType type, const DataBuffer& buffer)
394
- {
395
- DataBuffer data ({
396
- OutputReportTypes::write ,
399
+ PendingRead r = { {
400
+ OutputReportTypes::Read,
397
401
(u8)(((type & 0xff000000 ) >> 24 ) | (_state.rumble ? 0x01 : 0x00 )),
398
402
(u8)((type & 0x00ff0000 ) >> 16 ),
399
403
(u8)((type & 0x0000ff00 ) >> 8 ),
400
404
(u8)(type & 0x000000ff ),
401
- (u8)buffer.size ()
402
- });
405
+ (u8)((size & 0xff00 ) >> 8 ),
406
+ (u8)(size & 0xff ),
407
+ }, 7 , callback, type };
403
408
404
- for (size_t i = 0 ; i < buffer.size (); ++i)
405
- {
406
- data.push_back (buffer[i]);
407
- }
409
+ _pendingReads.push (r);
410
+ }
411
+
412
+ bool Wiimote::writeRegister (RegisterType type, u8* buffer, size_t size)
413
+ {
414
+ u8 b[22 ] = { 0 };
408
415
409
- data.resize (22 , 0 );
416
+ b[0 ] = OutputReportTypes::write ;
417
+ b[1 ] = (u8)(((type & 0xff000000 ) >> 24 ) | (_state.rumble ? 0x01 : 0x00 ));
418
+ b[2 ] = (u8)((type & 0x00ff0000 ) >> 16 );
419
+ b[3 ] = (u8)((type & 0x0000ff00 ) >> 8 );
420
+ b[4 ] = (u8)(type & 0x000000ff );
421
+ b[5 ] = (u8)size;
410
422
411
- return _device->write (data);
423
+ memcpy (b + 6 , buffer, size);
424
+
425
+ return _device->write (b, 22 );
426
+ }
427
+
428
+ bool Wiimote::writeRegister (RegisterType type, u8 val)
429
+ {
430
+ return writeRegister (type, &val, 1 );
412
431
}
413
432
414
433
void Wiimote::onMessage (const u8* b)
@@ -452,12 +471,11 @@ void Wiimote::onMessage(const u8* b)
452
471
break ;
453
472
454
473
case InputReportTypes::Status:
455
- {
456
474
parseButtons (b, _state);
457
475
parseStatus (b, _state);
458
476
updateExtension ();
459
477
updateReportMode ();
460
- }
478
+ break ;
461
479
}
462
480
463
481
if (_state.motionPlusActive && _state.motionPlus .extensionConnected != motionPlusExtension)
@@ -477,13 +495,61 @@ void Wiimote::onMessage(const u8* b)
477
495
PendingRead& r = _pendingReads.front ();
478
496
_currentRead = r.callback ;
479
497
_currentReadRegister = r.reg ;
480
- _device->write (r.buffer );
498
+ _device->write (r.buffer , r. size );
481
499
_pendingReads.pop ();
482
500
}
483
501
484
502
_lock.unlock ();
485
503
}
486
504
505
+ void Wiimote::startReader ()
506
+ {
507
+ _running = true ;
508
+ _thread = std::thread (&Wiimote::continuousReader, this );
509
+ }
510
+
511
+ void Wiimote::stopReader ()
512
+ {
513
+ if (_running)
514
+ {
515
+ _running = false ;
516
+ /* do {
517
+ SetEvent(_readIo.hEvent);
518
+ } while (WaitForSingleObject(_readThread, 100) == WAIT_TIMEOUT);*/
519
+ }
520
+
521
+ /* if (_readIo.hEvent != INVALID_HANDLE_VALUE)
522
+ {
523
+ CloseHandle(_readIo.hEvent);
524
+ _readIo.hEvent = INVALID_HANDLE_VALUE;
525
+ }*/
526
+ }
527
+
528
+ void Wiimote::continuousReader ()
529
+ {
530
+ u8 data[256 ];
531
+ size_t bytesRead;
532
+ size_t inputReportSize = _device->inputReportSize ();
533
+
534
+ while (_running)
535
+ {
536
+ if (_device->read (data, 256 , bytesRead))
537
+ {
538
+ if (bytesRead % inputReportSize != 0 )
539
+ {
540
+ std::cout << " WARNING: input report size of " << inputReportSize << " is invalid" << std::endl;
541
+ continue ;
542
+ }
543
+
544
+ for (size_t i = 0 ; i < bytesRead / inputReportSize; i++)
545
+ {
546
+ unsigned char * b = data + i * inputReportSize;
547
+ onMessage (b);
548
+ }
549
+ }
550
+ }
551
+ }
552
+
487
553
void Wiimote::update ()
488
554
{
489
555
const WiimoteState& old = _outState[_outStateIdx];
@@ -493,7 +559,7 @@ void Wiimote::update()
493
559
memcpy (&next, &_state, sizeof (WiimoteState));
494
560
_lock.unlock ();
495
561
496
- if (_buttonCallback != nullptr )
562
+ if (_buttonCallback != nullptr && (_features | WiimoteFeatures::Buttons) )
497
563
{
498
564
for (int i = 0 ; i < c_WiimoteButtonCount; ++i)
499
565
{
@@ -504,9 +570,60 @@ void Wiimote::update()
504
570
}
505
571
}
506
572
573
+ if (_accelerometerCallback != nullptr && (_features | WiimoteFeatures::Accelerometer))
574
+ {
575
+ if (!_filterAccelerometer || next.accelerometer != old.accelerometer )
576
+ {
577
+ _accelerometerCallback (next.accelerometer );
578
+ }
579
+ }
580
+
581
+ if ((next.extensionType == ExtensionTypes::Nunchuck || next.extensionType == ExtensionTypes::Nunchuck_TR) && (_features | WiimoteFeatures::Extension))
582
+ {
583
+ if (_nunchuckButtonCallback != nullptr )
584
+ {
585
+ for (int i = 0 ; i < c_NunchuckButtonCount; ++i)
586
+ {
587
+ if (next.nunchuck .buttons [i] != old.nunchuck .buttons [i])
588
+ {
589
+ _nunchuckButtonCallback ((NunchuckButton)i, next.nunchuck .buttons [i]);
590
+ }
591
+ }
592
+ }
593
+
594
+ if (_nunchuckAccelerometerCallback != nullptr )
595
+ {
596
+ if (!_filterNunchuckAccelerometer || next.nunchuck .accelerometer != old.nunchuck .accelerometer )
597
+ {
598
+ _nunchuckAccelerometerCallback (next.nunchuck .accelerometer );
599
+ }
600
+ }
601
+ }
602
+
603
+ if (_motionPlusCallback!= nullptr && next.motionPlusActive == true && (_features | WiimoteFeatures::MotionPlus))
604
+ {
605
+ if (!_filterMotionPlus || next.motionPlus .speed != old.motionPlus .speed )
606
+ {
607
+ _motionPlusCallback (next.motionPlus .speed );
608
+ }
609
+ }
610
+
507
611
_outStateIdx = 1 - _outStateIdx;
508
612
}
509
613
614
+ void Wiimote::clearEvents ()
615
+ {
616
+ _buttonCallback = nullptr ;
617
+ _nunchuckButtonCallback = nullptr ;
618
+ _accelerometerCallback = nullptr ;
619
+ _nunchuckAccelerometerCallback = nullptr ;
620
+ _motionPlusCallback = nullptr ;
621
+
622
+ _filterAccelerometer = false ;
623
+ _filterNunchuckAccelerometer = false ;
624
+ _filterMotionPlus = false ;
625
+ }
626
+
510
627
bool Wiimote::activateExtension ()
511
628
{
512
629
if (!_state.extensionConnected )
@@ -516,8 +633,8 @@ bool Wiimote::activateExtension()
516
633
517
634
std::cout << " Activating extension..." << std::endl;
518
635
519
- return writeRegister (RegisterTypes::ExtensionInit1, DataBuffer ({ 0x55 }) ) &&
520
- writeRegister (RegisterTypes::ExtensionInit2, DataBuffer ({ 0x00 }) );
636
+ return writeRegister (RegisterTypes::ExtensionInit1, 0x55 ) &&
637
+ writeRegister (RegisterTypes::ExtensionInit2, 0x00 );
521
638
}
522
639
523
640
bool Wiimote::activateMotionPlus ()
@@ -529,8 +646,8 @@ bool Wiimote::activateMotionPlus()
529
646
530
647
std::cout << " Activating motion plus..." << std::endl;
531
648
532
- return writeRegister (RegisterTypes::MotionPlusInit1, DataBuffer ({ 0x55 }) ) &&
533
- writeRegister (RegisterTypes::MotionPlusInit2, DataBuffer ({ 0x04 }) );
649
+ return writeRegister (RegisterTypes::MotionPlusInit1, 0x55 ) &&
650
+ writeRegister (RegisterTypes::MotionPlusInit2, 0x04 );
534
651
}
535
652
536
653
bool Wiimote::deactivateMotionPlus ()
@@ -542,7 +659,7 @@ bool Wiimote::deactivateMotionPlus()
542
659
543
660
std::cout << " Deactivating motion plus..." << std::endl;
544
661
545
- if (writeRegister (RegisterTypes::ExtensionInit1, DataBuffer ({ 0x55 }) ))
662
+ if (writeRegister (RegisterTypes::ExtensionInit1, 0x55 ))
546
663
{
547
664
_state.motionPlusActive = false ;
548
665
return true ;
0 commit comments