From e9a11cdbfd45b876372f676a66dd84bf15f4cef5 Mon Sep 17 00:00:00 2001 From: OatmealDome Date: Mon, 9 Aug 2021 18:48:58 -0400 Subject: [PATCH] WiimoteReal: Remove WiimoteScannerDarwin For several reasons: - It pegs the CPU at 95% for scanning even when Dolphin is idle - WiimoteScannerHidapi works fine on macOS - Less macOS code to maintain --- Source/Core/Core/CMakeLists.txt | 3 - Source/Core/Core/HW/WiimoteReal/IOdarwin.h | 40 -- Source/Core/Core/HW/WiimoteReal/IOdarwin.mm | 361 ------------------ .../Core/HW/WiimoteReal/IOdarwin_private.h | 41 -- .../Core/Core/HW/WiimoteReal/WiimoteReal.cpp | 2 - 5 files changed, 447 deletions(-) delete mode 100644 Source/Core/Core/HW/WiimoteReal/IOdarwin.h delete mode 100644 Source/Core/Core/HW/WiimoteReal/IOdarwin.mm delete mode 100644 Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 062a59d93b..7f6e6cc838 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -649,9 +649,6 @@ elseif(APPLE) HW/EXI/BBA/TAP_Apple.cpp HW/EXI/BBA/TAPServer_Apple.cpp HW/EXI/BBA/XLINK_KAI_BBA.cpp - HW/WiimoteReal/IOdarwin.h - HW/WiimoteReal/IOdarwin_private.h - HW/WiimoteReal/IOdarwin.mm ) target_link_libraries(core PUBLIC ${IOB_LIBRARY}) elseif(UNIX) diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin.h b/Source/Core/Core/HW/WiimoteReal/IOdarwin.h deleted file mode 100644 index 6fe1c3b6eb..0000000000 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2016 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#ifdef __APPLE__ -#include "Core/HW/WiimoteReal/WiimoteReal.h" - -#ifdef __OBJC__ -#import -#else -// IOBluetooth's types won't be defined in pure C++ mode. -typedef void IOBluetoothHostController; -#endif - -namespace WiimoteReal -{ -class WiimoteScannerDarwin final : public WiimoteScannerBackend -{ -public: - WiimoteScannerDarwin(); - ~WiimoteScannerDarwin() override; - bool IsReady() const override; - void FindWiimotes(std::vector&, Wiimote*&) override; - void Update() override {} // not needed - void RequestStopSearching() override { m_stop_scanning = true; } - -private: - IOBluetoothHostController* m_host_controller; - bool m_stop_scanning = false; -}; -} // namespace WiimoteReal - -#else -#include "Core/HW/WiimoteReal/IODummy.h" -namespace WiimoteReal -{ -using WiimoteScannerDarwin = WiimoteScannerDummy; -} -#endif diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm deleted file mode 100644 index 34d10b083d..0000000000 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm +++ /dev/null @@ -1,361 +0,0 @@ -#define BLUETOOTH_VERSION_USE_CURRENT - -#include "Core/HW/WiimoteReal/IOdarwin.h" -#include "Common/Common.h" -#include "Common/Logging/Log.h" -#include "Core/HW/WiimoteCommon/WiimoteHid.h" -#include "Core/HW/WiimoteReal/IOdarwin_private.h" - -@interface SearchBT : NSObject -{ -@public - unsigned int maxDevices; - bool done; -} -@end - -@interface ConnectBT : NSObject -{ -} -@end - -namespace WiimoteReal -{ -WiimoteScannerDarwin::WiimoteScannerDarwin() -{ - m_host_controller = [IOBluetoothHostController defaultController]; - if (![m_host_controller addressAsString]) - { - WARN_LOG_FMT(WIIMOTE, "No Bluetooth host controller"); - - [m_host_controller release]; - m_host_controller = nil; - - return; - } - - [m_host_controller retain]; -} - -WiimoteScannerDarwin::~WiimoteScannerDarwin() -{ - [m_host_controller release]; - m_host_controller = nil; - - m_stop_scanning = true; -} - -void WiimoteScannerDarwin::FindWiimotes(std::vector& found_wiimotes, - Wiimote*& found_board) -{ - if (!m_host_controller) - { - return; - } - - IOBluetoothDeviceInquiry* bti; - found_board = nullptr; - - SearchBT* sbt = [[SearchBT alloc] init]; - sbt->maxDevices = 32; - bti = [[IOBluetoothDeviceInquiry alloc] init]; - [bti setDelegate:sbt]; - [bti setInquiryLength:2]; - - if ([bti start] != kIOReturnSuccess) - { - ERROR_LOG_FMT(WIIMOTE, "Unable to do Bluetooth discovery"); - [sbt release]; - - return; - } - - do - { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); - } while (!sbt->done && !m_stop_scanning); - - int found_devices = [[bti foundDevices] count]; - - if (found_devices) - NOTICE_LOG_FMT(WIIMOTE, "Found {} Bluetooth devices", found_devices); - - NSEnumerator* en = [[bti foundDevices] objectEnumerator]; - for (int i = 0; i < found_devices; i++) - { - IOBluetoothDevice* dev = [en nextObject]; - if (!IsValidDeviceName([[dev name] UTF8String])) - continue; - - Wiimote* wm = new WiimoteDarwin([dev retain]); - - if (IsBalanceBoardName([[dev name] UTF8String])) - { - found_board = wm; - } - else - { - found_wiimotes.push_back(wm); - } - } - - [bti release]; - [sbt release]; -} - -bool WiimoteScannerDarwin::IsReady() const -{ - return m_host_controller != nil; -} - -WiimoteDarwin::WiimoteDarwin(IOBluetoothDevice* device) : m_btd(device) -{ - m_inputlen = 0; - m_connected = false; - m_wiimote_thread_run_loop = nullptr; - m_pm_assertion = kIOPMNullAssertionID; -} - -WiimoteDarwin::~WiimoteDarwin() -{ - Shutdown(); - if (m_wiimote_thread_run_loop) - { - CFRelease(m_wiimote_thread_run_loop); - m_wiimote_thread_run_loop = nullptr; - } - [m_btd release]; - m_btd = nil; - DisablePowerAssertionInternal(); -} - -// Connect to a Wiimote with a known address. -bool WiimoteDarwin::ConnectInternal() -{ - if (IsConnected()) - return false; - - ConnectBT* cbt = [[ConnectBT alloc] init]; - - m_cchan = m_ichan = nil; - - IOReturn ret = [m_btd openConnection]; - if (ret) - { - ERROR_LOG_FMT(WIIMOTE, "Unable to open Bluetooth connection to Wiimote {}: {:x}", m_index + 1, - ret); - [cbt release]; - return false; - } - - ret = [m_btd openL2CAPChannelSync:&m_cchan withPSM:kBluetoothL2CAPPSMHIDControl delegate:cbt]; - if (ret) - { - ERROR_LOG_FMT(WIIMOTE, "Unable to open control channel for Wiimote {}: {:x}", m_index + 1, ret); - goto bad; - } - // Apple docs claim: - // "The L2CAP channel object is already retained when this function returns - // success; the channel must be released when the caller is done with it." - // But without this, the channels get over-autoreleased, even though the - // refcounting behavior here is clearly correct. - [m_cchan retain]; - - ret = [m_btd openL2CAPChannelSync:&m_ichan withPSM:kBluetoothL2CAPPSMHIDInterrupt delegate:cbt]; - if (ret) - { - WARN_LOG_FMT(WIIMOTE, "Unable to open interrupt channel for Wiimote {}: {:x}", m_index + 1, - ret); - goto bad; - } - [m_ichan retain]; - - NOTICE_LOG_FMT(WIIMOTE, "Connected to Wiimote {} at {}", m_index + 1, - [[m_btd addressString] UTF8String]); - - m_connected = true; - - [cbt release]; - - m_wiimote_thread_run_loop = (CFRunLoopRef)CFRetain(CFRunLoopGetCurrent()); - - return true; - -bad: - DisconnectInternal(); - [cbt release]; - return false; -} - -// Disconnect a Wiimote. -void WiimoteDarwin::DisconnectInternal() -{ - [m_ichan closeChannel]; - [m_ichan release]; - m_ichan = nil; - - [m_cchan closeChannel]; - [m_cchan release]; - m_cchan = nil; - - [m_btd closeConnection]; - - if (!IsConnected()) - return; - - NOTICE_LOG_FMT(WIIMOTE, "Disconnecting Wiimote {}", m_index + 1); - - m_connected = false; -} - -bool WiimoteDarwin::IsConnected() const -{ - return m_connected; -} - -void WiimoteDarwin::IOWakeup() -{ - if (m_wiimote_thread_run_loop) - { - CFRunLoopStop(m_wiimote_thread_run_loop); - } -} - -int WiimoteDarwin::IORead(unsigned char* buf) -{ - m_input = buf; - m_inputlen = -1; - - CFRunLoopRun(); - - return m_inputlen; -} - -int WiimoteDarwin::IOWrite(const unsigned char* buf, size_t len) -{ - IOReturn ret; - - if (!IsConnected()) - return 0; - - ret = [m_ichan writeAsync:const_cast((void*)buf) length:(int)len refcon:nil]; - - if (ret == kIOReturnSuccess) - return len; - else - return 0; -} - -void WiimoteDarwin::EnablePowerAssertionInternal() -{ - if (m_pm_assertion == kIOPMNullAssertionID) - { - if (IOReturn ret = IOPMAssertionCreateWithName( - kIOPMAssertPreventUserIdleDisplaySleep, kIOPMAssertionLevelOn, - CFSTR("Dolphin Wiimote activity"), &m_pm_assertion)) - { - ERROR_LOG_FMT(WIIMOTE, "Could not create power management assertion: {:08x}", ret); - } - } -} - -void WiimoteDarwin::DisablePowerAssertionInternal() -{ - if (m_pm_assertion != kIOPMNullAssertionID) - { - if (IOReturn ret = IOPMAssertionRelease(m_pm_assertion)) - ERROR_LOG_FMT(WIIMOTE, "Could not release power management assertion: {:08x}", ret); - } -} -} // namespace - -@implementation SearchBT -- (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender - error:(IOReturn)error - aborted:(BOOL)aborted -{ - done = true; -} - -- (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender device:(IOBluetoothDevice*)device -{ - NOTICE_LOG_FMT(WIIMOTE, "Discovered Bluetooth device at {}: {}", - [[device addressString] UTF8String], [[device name] UTF8String]); - - if ([[sender foundDevices] count] == maxDevices) - [sender stop]; -} -@end - -@implementation ConnectBT -- (void)l2capChannelData:(IOBluetoothL2CAPChannel*)l2capChannel - data:(unsigned char*)data - length:(NSUInteger)length -{ - IOBluetoothDevice* device = [l2capChannel device]; - WiimoteReal::WiimoteDarwin* wm = nullptr; - - std::lock_guard lk(WiimoteReal::g_wiimotes_mutex); - - for (int i = 0; i < MAX_WIIMOTES; i++) - { - wm = static_cast(WiimoteReal::g_wiimotes[i].get()); - if (!wm) - continue; - if ([device isEqual:wm->m_btd]) - break; - wm = nullptr; - } - - if (wm == nullptr) - { - ERROR_LOG_FMT(WIIMOTE, "Received packet for unknown Wiimote"); - return; - } - - if (length > WiimoteCommon::MAX_PAYLOAD) - { - WARN_LOG_FMT(WIIMOTE, "Dropping packet for Wiimote {}, too large", wm->GetIndex() + 1); - return; - } - - if (wm->m_inputlen != -1) - { - WARN_LOG_FMT(WIIMOTE, "Dropping packet for Wiimote {}, queue full", wm->GetIndex() + 1); - return; - } - - memcpy(wm->m_input, data, length); - wm->m_inputlen = length; - - CFRunLoopStop(CFRunLoopGetCurrent()); -} - -- (void)l2capChannelClosed:(IOBluetoothL2CAPChannel*)l2capChannel -{ - IOBluetoothDevice* device = [l2capChannel device]; - WiimoteReal::WiimoteDarwin* wm = nullptr; - - std::lock_guard lk(WiimoteReal::g_wiimotes_mutex); - - for (int i = 0; i < MAX_WIIMOTES; i++) - { - wm = static_cast(WiimoteReal::g_wiimotes[i].get()); - if (!wm) - continue; - if ([device isEqual:wm->m_btd]) - break; - wm = nullptr; - } - - if (wm == nullptr) - { - ERROR_LOG_FMT(WIIMOTE, "Channel for unknown Wiimote was closed"); - return; - } - - WARN_LOG_FMT(WIIMOTE, "Lost channel to Wiimote {}", wm->GetIndex() + 1); - - wm->DisconnectInternal(); -} -@end diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h b/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h deleted file mode 100644 index b4096c08fa..0000000000 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin_private.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2016 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#import -#include - -#include "Core/HW/WiimoteReal/WiimoteReal.h" - -namespace WiimoteReal -{ -class WiimoteDarwin final : public Wiimote -{ -public: - WiimoteDarwin(IOBluetoothDevice* device); - ~WiimoteDarwin() override; - std::string GetId() const override { return [[m_btd addressString] UTF8String]; } - // These are not protected/private because ConnectBT needs them. - void DisconnectInternal() override; - IOBluetoothDevice* m_btd; - unsigned char* m_input; - int m_inputlen; - -protected: - bool ConnectInternal() override; - bool IsConnected() const override; - void IOWakeup() override; - int IORead(u8* buf) override; - int IOWrite(u8 const* buf, size_t len) override; - void EnablePowerAssertionInternal() override; - void DisablePowerAssertionInternal() override; - -private: - IOBluetoothL2CAPChannel* m_ichan; - IOBluetoothL2CAPChannel* m_cchan; - bool m_connected; - CFRunLoopRef m_wiimote_thread_run_loop; - IOPMAssertionID m_pm_assertion; -}; -} // namespace WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp index 92dbaeeef0..b0b03f81ab 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp @@ -24,7 +24,6 @@ #include "Core/HW/WiimoteReal/IOAndroid.h" #include "Core/HW/WiimoteReal/IOLinux.h" #include "Core/HW/WiimoteReal/IOWin.h" -#include "Core/HW/WiimoteReal/IOdarwin.h" #include "Core/HW/WiimoteReal/IOhidapi.h" #include "InputCommon/ControllerInterface/Wiimote/WiimoteController.h" #include "InputCommon/InputConfig.h" @@ -653,7 +652,6 @@ void WiimoteScanner::ThreadFunc() m_backends.emplace_back(std::make_unique()); m_backends.emplace_back(std::make_unique()); m_backends.emplace_back(std::make_unique()); - m_backends.emplace_back(std::make_unique()); m_backends.emplace_back(std::make_unique()); }