WiimoteReal: Split WiimoteScannerDarwin

This moves out the HID code into a separate scanner.
This commit is contained in:
Léo Lam 2016-07-23 20:00:54 +02:00
parent 3305a923e1
commit 9c02e327b7
3 changed files with 100 additions and 87 deletions

View File

@ -84,6 +84,16 @@ public:
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override{}; // not needed
};
class WiimoteScannerDarwinHID final : public WiimoteScannerBackend
{
public:
WiimoteScannerDarwinHID() = default;
~WiimoteScannerDarwinHID() override = default;
bool IsReady() const override;
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override{}; // not needed
};
}
#else
@ -91,5 +101,6 @@ public:
namespace WiimoteReal
{
using WiimoteScannerDarwin = WiimoteScannerDummy;
using WiimoteScannerDarwinHID = WiimoteScannerDummy;
}
#endif

View File

@ -26,111 +26,63 @@ void WiimoteScannerDarwin::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
// TODO: find the device in the constructor and save it for later
IOBluetoothHostController* bth;
IOBluetoothDeviceInquiry* bti;
IOHIDManagerRef hid;
SearchBT* sbt;
NSEnumerator* en;
found_board = nullptr;
bool btFailed = false;
bool hidFailed = false;
bth = [[IOBluetoothHostController alloc] init];
btFailed = [bth addressAsString] == nil;
bool btFailed = [bth addressAsString] == nil;
if (btFailed)
WARN_LOG(WIIMOTE, "No Bluetooth host controller");
hid = IOHIDManagerCreate(NULL, kIOHIDOptionsTypeNone);
hidFailed = CFGetTypeID(hid) != IOHIDManagerGetTypeID();
if (hidFailed)
WARN_LOG(WIIMOTE, "No HID manager");
if (hidFailed && btFailed)
{
CFRelease(hid);
WARN_LOG(WIIMOTE, "No Bluetooth host controller");
[bth release];
return;
}
if (!btFailed)
SearchBT* sbt = [[SearchBT alloc] init];
sbt->maxDevices = 32;
bti = [[IOBluetoothDeviceInquiry alloc] init];
[bti setDelegate:sbt];
[bti setInquiryLength:2];
if ([bti start] != kIOReturnSuccess)
{
sbt = [[SearchBT alloc] init];
sbt->maxDevices = 32;
bti = [[IOBluetoothDeviceInquiry alloc] init];
[bti setDelegate:sbt];
[bti setInquiryLength:2];
if ([bti start] != kIOReturnSuccess)
{
ERROR_LOG(WIIMOTE, "Unable to do Bluetooth discovery");
[bth release];
[sbt release];
btFailed = true;
}
do
{
CFRunLoopRun();
} while (!sbt->done);
int found_devices = [[bti foundDevices] count];
if (found_devices)
NOTICE_LOG(WIIMOTE, "Found %i Bluetooth devices", found_devices);
en = [[bti foundDevices] objectEnumerator];
for (int i = 0; i < found_devices; i++)
{
IOBluetoothDevice* dev = [en nextObject];
if (!IsValidBluetoothName([[dev name] UTF8String]))
continue;
Wiimote* wm = new WiimoteDarwin([dev retain]);
if (IsBalanceBoardName([[dev name] UTF8String]))
{
found_board = wm;
}
else
{
found_wiimotes.push_back(wm);
}
}
ERROR_LOG(WIIMOTE, "Unable to do Bluetooth discovery");
[bth release];
[bti release];
[sbt release];
btFailed = true;
}
if (!hidFailed)
do
{
NSArray* criteria = @[
@{ @kIOHIDVendorIDKey : @0x057e,
@kIOHIDProductIDKey : @0x0306 },
@{ @kIOHIDVendorIDKey : @0x057e,
@kIOHIDProductIDKey : @0x0330 },
];
IOHIDManagerSetDeviceMatchingMultiple(hid, (CFArrayRef)criteria);
if (IOHIDManagerOpen(hid, kIOHIDOptionsTypeNone) != kIOReturnSuccess)
WARN_LOG(WIIMOTE, "Failed to open HID Manager");
CFSetRef devices = IOHIDManagerCopyDevices(hid);
if (devices)
{
int found_devices = CFSetGetCount(devices);
if (found_devices)
{
NOTICE_LOG(WIIMOTE, "Found %i HID devices", found_devices);
CFRunLoopRun();
} while (!sbt->done);
IOHIDDeviceRef values[found_devices];
CFSetGetValues(devices, reinterpret_cast<const void**>(&values));
for (int i = 0; i < found_devices; i++)
{
Wiimote* wm = new WiimoteDarwinHid(values[i]);
found_wiimotes.push_back(wm);
}
}
int found_devices = [[bti foundDevices] count];
if (found_devices)
NOTICE_LOG(WIIMOTE, "Found %i Bluetooth devices", found_devices);
NSEnumerator* en = [[bti foundDevices] objectEnumerator];
for (int i = 0; i < found_devices; i++)
{
IOBluetoothDevice* dev = [en nextObject];
if (!IsValidBluetoothName([[dev name] UTF8String]))
continue;
Wiimote* wm = new WiimoteDarwin([dev retain]);
if (IsBalanceBoardName([[dev name] UTF8String]))
{
found_board = wm;
}
else
{
found_wiimotes.push_back(wm);
}
CFRelease(hid);
}
[bth release];
[bti release];
[sbt release];
}
bool WiimoteScannerDarwin::IsReady() const
@ -139,6 +91,55 @@ bool WiimoteScannerDarwin::IsReady() const
return true;
}
void WiimoteScannerDarwinHID::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
Wiimote*& found_board)
{
found_board = nullptr;
IOHIDManagerRef hid = IOHIDManagerCreate(NULL, kIOHIDOptionsTypeNone);
bool hidFailed = CFGetTypeID(hid) != IOHIDManagerGetTypeID();
if (hidFailed)
{
CFRelease(hid);
WARN_LOG(WIIMOTE, "No HID manager");
return;
}
NSArray* criteria = @[
@{ @kIOHIDVendorIDKey : @0x057e,
@kIOHIDProductIDKey : @0x0306 },
@{ @kIOHIDVendorIDKey : @0x057e,
@kIOHIDProductIDKey : @0x0330 },
];
IOHIDManagerSetDeviceMatchingMultiple(hid, (CFArrayRef)criteria);
if (IOHIDManagerOpen(hid, kIOHIDOptionsTypeNone) != kIOReturnSuccess)
WARN_LOG(WIIMOTE, "Failed to open HID Manager");
CFSetRef devices = IOHIDManagerCopyDevices(hid);
if (devices)
{
int found_devices = CFSetGetCount(devices);
if (found_devices)
{
NOTICE_LOG(WIIMOTE, "Found %i HID devices", found_devices);
IOHIDDeviceRef values[found_devices];
CFSetGetValues(devices, reinterpret_cast<const void**>(&values));
for (int i = 0; i < found_devices; i++)
{
Wiimote* wm = new WiimoteDarwinHid(values[i]);
found_wiimotes.push_back(wm);
}
}
}
CFRelease(hid);
}
bool WiimoteScannerDarwinHID::IsReady() const
{
// TODO: only return true when !hidFailed
return true;
}
WiimoteDarwin::WiimoteDarwin(IOBluetoothDevice* device) : m_btd(device)
{
m_inputlen = 0;

View File

@ -639,6 +639,7 @@ void Initialize(::Wiimote::InitializeMode init_mode)
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerAndroid>());
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerWindows>());
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerDarwin>());
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerDarwinHID>());
g_wiimote_scanner.StartThread();
}