From af8690a7d8b6b13029b1d396ad46c8438c4fb668 Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Tue, 28 Feb 2012 21:02:49 -0800 Subject: [PATCH 1/3] Revert "Add Support for Wii Motion Plus INSIDE Wii Remotes on Mac OS X." This reverts commit c9dfcf8cf7d500d58cd8f2b375be123f5b99bb52. That commit attempted to support all Wii Remotes on Mac OS X, but the logic was incorrect, and as a result the original (non-TR) Wii Remotes were broken by that change. Future patches will address this problem in a better way. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 8 ++------ Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 10 ++++------ Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h | 1 - 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index a899dac201..0c2f742987 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -129,7 +129,7 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes) [bti setInquiryLength: 5]; [bti setSearchCriteria: kBluetoothServiceClassMajorAny majorDeviceClass: kBluetoothDeviceClassMajorPeripheral - minorDeviceClass: kBluetoothDeviceClassMinorAny + minorDeviceClass: kBluetoothDeviceClassMinorPeripheral2Joystick ]; [bti setUpdateNewDeviceNames: NO]; @@ -177,10 +177,6 @@ bool Wiimote::Connect() if (IsConnected()) return false; - if ([btd remoteNameRequest:nil] == kIOReturnSuccess) - m_motion_plus_inside = - static_cast([[btd getName] hasSuffix:@"-TR"]); - [btd openL2CAPChannelSync: &cchan withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt]; [btd openL2CAPChannelSync: &ichan @@ -248,7 +244,7 @@ int Wiimote::IOWrite(unsigned char *buf, int len) if (!IsConnected()) return 0; - ret = [ichan writeAsync: buf length: len refcon: nil]; + ret = [cchan writeAsync: buf length: len refcon: nil]; if (ret == kIOReturnSuccess) return len; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 1ac0823ebb..f5ded4125d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -50,7 +50,6 @@ Wiimote::Wiimote(const unsigned int _index) #endif , leds(0), m_last_data_report(Report((u8 *)NULL, 0)) , m_channel(0), m_connected(false) - , m_motion_plus_inside(false) { #if defined(__linux__) && HAVE_BLUEZ bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; @@ -143,16 +142,15 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const rpt.second = (u8)size; memcpy(rpt.first, (u8*)data, size); - // Convert output DATA packets to SET_REPORT packets for non-TR - // Wiimotes. Nintendo Wiimotes work without this translation, but 3rd + // Convert output DATA packets to SET_REPORT packets. + // Nintendo Wiimotes work without this translation, but 3rd // party ones don't. - u8 head = m_motion_plus_inside ? 0xa2 : 0x52; if (rpt.first[0] == 0xa2) { - rpt.first[0] = head; + rpt.first[0] = 0x52; } - if (rpt.first[0] == head && rpt.first[1] == 0x18 && rpt.second == 23) + if (rpt.first[0] == 0x52 && rpt.first[1] == 0x18 && rpt.second == 23) { m_audio_reports.Push(rpt); return; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 8229abee52..f3c5b884f8 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -95,7 +95,6 @@ private: void ThreadFunc(); bool m_connected; - bool m_motion_plus_inside; std::thread m_wiimote_thread; Common::FifoQueue m_read_reports; Common::FifoQueue m_write_reports; From 93b78d71397191d49e4f5c472049f6bac3912ed7 Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Thu, 22 Mar 2012 20:15:47 -0700 Subject: [PATCH 2/3] WiimoteReal for Mac: Send commands on interrupt channel. There are two ways to send commands to Wii Remotes: - On command channel, with a first byte of 0x52. This works on Nintendo RVL-CNT-01, but not Nintendo RVL-CNT-01-TR wiimotes. - On interrupt channel, with a first byte of 0xa2. This works on Nintendo RVL-CNT-01 and Nintendo RVL-CNT-01-TR wiimotes. This patch switches Mac from the former to the latter. Windows and Linux remain unchanged. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 2 +- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 5 +++-- Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h | 7 +++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 0c2f742987..7dbb45e6f1 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -244,7 +244,7 @@ int Wiimote::IOWrite(unsigned char *buf, int len) if (!IsConnected()) return 0; - ret = [cchan writeAsync: buf length: len refcon: nil]; + ret = [ichan writeAsync: buf length: len refcon: nil]; if (ret == kIOReturnSuccess) return len; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index f5ded4125d..8c7b01a72c 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -147,10 +147,11 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const // party ones don't. if (rpt.first[0] == 0xa2) { - rpt.first[0] = 0x52; + rpt.first[0] = WM_SET_REPORT | WM_BT_OUTPUT; } - if (rpt.first[0] == 0x52 && rpt.first[1] == 0x18 && rpt.second == 23) + if (rpt.first[0] == (WM_SET_REPORT | WM_BT_OUTPUT) && + rpt.first[1] == 0x18 && rpt.second == 23) { m_audio_reports.Push(rpt); return; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h index 6765748e58..4b66eb4930 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h @@ -32,7 +32,14 @@ #define WM_OUTPUT_CHANNEL 0x11 #define WM_INPUT_CHANNEL 0x13 +// The 4 most significant bits of the first byte of an outgoing command must be +// 0x50 if sending on the command channel and 0xA0 if sending on the interrupt +// channel. On Mac we use interrupt channel; on Windows/Linux, command. +#ifndef __APPLE__ #define WM_SET_REPORT 0x50 +#else +#define WM_SET_REPORT 0xA0 +#endif // Commands #define WM_CMD_RUMBLE 0x10 From d3361494cec1b03523311fdda37d24a8382e0ed8 Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Thu, 22 Mar 2012 20:55:41 -0700 Subject: [PATCH 3/3] WiiremoteReal for Mac: Find Wiimotes by name. The decided way to find Wii Remotes is by their bluetooth name, so this patch introduces common code to identify if a given string is a valid Wiimote name. On Mac, when scanning bluetooth, consult the function with all found bluetooth devices. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 10 ++++------ .../Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 15 +++++++++++++++ Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h | 2 ++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 7dbb45e6f1..8e3586f7d9 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -127,11 +127,6 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes) bti = [[IOBluetoothDeviceInquiry alloc] init]; [bti setDelegate: sbt]; [bti setInquiryLength: 5]; - [bti setSearchCriteria: kBluetoothServiceClassMajorAny - majorDeviceClass: kBluetoothDeviceClassMajorPeripheral - minorDeviceClass: kBluetoothDeviceClassMinorPeripheral2Joystick - ]; - [bti setUpdateNewDeviceNames: NO]; if ([bti start] == kIOReturnSuccess) [bti retain]; @@ -149,6 +144,9 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes) en = [[bti foundDevices] objectEnumerator]; for (int i = 0; i < found_devices; i++) { + IOBluetoothDevice *dev = [en nextObject]; + if (!IsValidBluetoothName([[dev name] UTF8String])) + continue; // Find an unused slot for (int k = 0; k < MAX_WIIMOTES; k++) { if (wm[k] != NULL || @@ -156,7 +154,7 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes) continue; wm[k] = new Wiimote(k); - wm[k]->btd = [en nextObject]; + wm[k]->btd = dev; found_wiimotes++; break; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 8c7b01a72c..5e03e36e68 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -512,4 +512,19 @@ void StateChange(EMUSTATE_CHANGE newState) // TODO: disable/enable auto reporting, maybe } +#define ARRAYSIZE(_arr) (sizeof(_arr)/(sizeof(_arr[0]))) + +bool IsValidBluetoothName(const char* name) { + static const char* kValidWiiRemoteBluetoothNames[] = { + "Nintendo RVL-CNT-01", + "Nintendo RVL-CNT-01-TR", + "Nintendo RVL-WBC-01", + }; + for (size_t i = 0; i < ARRAYSIZE(kValidWiiRemoteBluetoothNames); i++) + if (strcmp(name, kValidWiiRemoteBluetoothNames[i]) == 0) + return true; + return false; +} + + }; // end of namespace diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index f3c5b884f8..cd1080903f 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -113,6 +113,8 @@ void StateChange(EMUSTATE_CHANGE newState); int FindWiimotes(Wiimote** wm, int max_wiimotes); +bool IsValidBluetoothName(const char* name); + }; // WiimoteReal #endif