Skip to content

Commit 2a28e9b

Browse files
committed
Added callbacks for more features. Added initial posix port code
1 parent 0df6382 commit 2a28e9b

17 files changed

+664
-392
lines changed

src/Wiimote.cpp

+170-53
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <iostream>
55

66
#define CHECK_MASK(val, mask) ((val & mask) != 0x00)
7+
#define SET_FLAG(flags, flag) flags |= flag
8+
#define UNSET_FLAG(flags, flag) flags &= ~flag
79

810
static const int64_t ID_ActiveMotionPlus = 0x0000A4200405;
911
static const int64_t ID_ActiveMotionPlus_Nunchuck = 0x0000A4200505;
@@ -121,7 +123,21 @@ void parseReadData(const u8* data, DataCallback callback, RegisterType reg)
121123
callback(data + 6);
122124
}
123125

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)
125141
{
126142
if (_running)
127143
{
@@ -133,17 +149,16 @@ void Wiimote::start(int featureFlags)
133149

134150
updateStatus();
135151
updateWiimoteCalibration();
136-
identifyMotionPlus();
152+
//identifyMotionPlus();
137153

138-
_device->startReader();
154+
startReader();
139155
}
140156

141-
void Wiimote::stop()
157+
void Wiimote::stop()
142158
{
143-
if (!_running)
159+
if (_running)
144160
{
145-
_device->stopReader();
146-
_running = false;
161+
stopReader();
147162
}
148163
}
149164

@@ -154,7 +169,7 @@ bool Wiimote::setLeds(LedState state)
154169
u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00);
155170
_lock.unlock();
156171

157-
return _device->write(DataBuffer({ OutputReportType::LEDs, s }));
172+
return _device->write(buffer(OutputReportTypes::LEDs, s), 2);
158173
}
159174

160175
bool Wiimote::setRumble(bool rumble)
@@ -164,13 +179,13 @@ bool Wiimote::setRumble(bool rumble)
164179
u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00);
165180
_lock.unlock();
166181

167-
return _device->write(DataBuffer({ OutputReportType::LEDs, s }));
182+
return _device->write(buffer(OutputReportTypes::LEDs, s), 2);
168183
}
169184

170185
bool Wiimote::updateStatus()
171186
{
172187
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);
174189
}
175190

176191
void Wiimote::updateWiimoteCalibration()
@@ -204,15 +219,13 @@ void Wiimote::updateNunchuckCalibration()
204219
});
205220
}
206221

207-
#define SET_FLAG(flags, flag) flags |= flag
208-
#define UNSET_FLAG(flags, flag) flags &= ~flag
209-
210222
bool Wiimote::updateReportMode()
211223
{
212-
_state.reportMode = ReportModes::Unknown;
213-
224+
u8 s = _state.leds | (_state.rumble == true ? 0x01 : 0x00);
214225
int features = _features;
215226

227+
_state.reportMode = ReportModes::Unknown;
228+
216229
if (!_state.extensionActive)
217230
{
218231
UNSET_FLAG(features, WiimoteFeatures::Extension);
@@ -258,7 +271,9 @@ bool Wiimote::updateReportMode()
258271

259272
std::cout << "Setting report mode: " << ReportModes::toString(_state.reportMode) << std::endl;
260273

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);
262277
}
263278

264279
void Wiimote::updateExtension()
@@ -331,6 +346,7 @@ void Wiimote::identifyExtension()
331346
case ExtensionTypes::MotionPlus_TR:
332347
if (!_state.motionPlusActive)
333348
{
349+
_state.motionPlusAvailable = true;
334350
_state.motionPlusActive = true;
335351
updateReportMode();
336352
std::cout << "Motion plus active" << std::endl;
@@ -369,46 +385,49 @@ void Wiimote::identifyMotionPlus()
369385
}
370386

371387
_state.motionPlusAvailable = true;
372-
}
388+
}
389+
390+
if (_state.motionPlusAvailable && !_state.motionPlusActive && (_features | WiimoteFeatures::MotionPlus))
391+
{
392+
activateMotionPlus();
393+
}
373394
});
374395
}
375396

376397
void Wiimote::readRegister(RegisterType type, short size, DataCallback callback)
377398
{
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,
397401
(u8)(((type & 0xff000000) >> 24) | (_state.rumble ? 0x01 : 0x00)),
398402
(u8)((type & 0x00ff0000) >> 16),
399403
(u8)((type & 0x0000ff00) >> 8),
400404
(u8)(type & 0x000000ff),
401-
(u8)buffer.size()
402-
});
405+
(u8)((size & 0xff00) >> 8),
406+
(u8)(size & 0xff),
407+
}, 7, callback, type };
403408

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 };
408415

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;
410422

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);
412431
}
413432

414433
void Wiimote::onMessage(const u8* b)
@@ -452,12 +471,11 @@ void Wiimote::onMessage(const u8* b)
452471
break;
453472

454473
case InputReportTypes::Status:
455-
{
456474
parseButtons(b, _state);
457475
parseStatus(b, _state);
458476
updateExtension();
459477
updateReportMode();
460-
}
478+
break;
461479
}
462480

463481
if (_state.motionPlusActive && _state.motionPlus.extensionConnected != motionPlusExtension)
@@ -477,13 +495,61 @@ void Wiimote::onMessage(const u8* b)
477495
PendingRead& r = _pendingReads.front();
478496
_currentRead = r.callback;
479497
_currentReadRegister = r.reg;
480-
_device->write(r.buffer);
498+
_device->write(r.buffer, r.size);
481499
_pendingReads.pop();
482500
}
483501

484502
_lock.unlock();
485503
}
486504

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+
487553
void Wiimote::update()
488554
{
489555
const WiimoteState& old = _outState[_outStateIdx];
@@ -493,7 +559,7 @@ void Wiimote::update()
493559
memcpy(&next, &_state, sizeof(WiimoteState));
494560
_lock.unlock();
495561

496-
if (_buttonCallback != nullptr)
562+
if (_buttonCallback != nullptr && (_features | WiimoteFeatures::Buttons))
497563
{
498564
for (int i = 0; i < c_WiimoteButtonCount; ++i)
499565
{
@@ -504,9 +570,60 @@ void Wiimote::update()
504570
}
505571
}
506572

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+
507611
_outStateIdx = 1 - _outStateIdx;
508612
}
509613

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+
510627
bool Wiimote::activateExtension()
511628
{
512629
if (!_state.extensionConnected)
@@ -516,8 +633,8 @@ bool Wiimote::activateExtension()
516633

517634
std::cout << "Activating extension..." << std::endl;
518635

519-
return writeRegister(RegisterTypes::ExtensionInit1, DataBuffer({ 0x55 })) &&
520-
writeRegister(RegisterTypes::ExtensionInit2, DataBuffer({ 0x00 }));
636+
return writeRegister(RegisterTypes::ExtensionInit1, 0x55) &&
637+
writeRegister(RegisterTypes::ExtensionInit2, 0x00);
521638
}
522639

523640
bool Wiimote::activateMotionPlus()
@@ -529,8 +646,8 @@ bool Wiimote::activateMotionPlus()
529646

530647
std::cout << "Activating motion plus..." << std::endl;
531648

532-
return writeRegister(RegisterTypes::MotionPlusInit1, DataBuffer({ 0x55 })) &&
533-
writeRegister(RegisterTypes::MotionPlusInit2, DataBuffer({ 0x04 }));
649+
return writeRegister(RegisterTypes::MotionPlusInit1, 0x55) &&
650+
writeRegister(RegisterTypes::MotionPlusInit2, 0x04);
534651
}
535652

536653
bool Wiimote::deactivateMotionPlus()
@@ -542,7 +659,7 @@ bool Wiimote::deactivateMotionPlus()
542659

543660
std::cout << "Deactivating motion plus..." << std::endl;
544661

545-
if (writeRegister(RegisterTypes::ExtensionInit1, DataBuffer({ 0x55 })))
662+
if (writeRegister(RegisterTypes::ExtensionInit1, 0x55))
546663
{
547664
_state.motionPlusActive = false;
548665
return true;

0 commit comments

Comments
 (0)