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
This commit is contained in:
OatmealDome 2021-08-09 18:48:58 -04:00
parent 942545b7fc
commit e9a11cdbfd
5 changed files with 0 additions and 447 deletions

View File

@ -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)

View File

@ -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 <IOBluetooth/IOBluetooth.h>
#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*>&, 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

View File

@ -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<Wiimote*>& 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*>((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::WiimoteDarwin*>(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::WiimoteDarwin*>(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

View File

@ -1,41 +0,0 @@
// Copyright 2016 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#import <IOBluetooth/IOBluetooth.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#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

View File

@ -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<WiimoteScannerLinux>());
m_backends.emplace_back(std::make_unique<WiimoteScannerAndroid>());
m_backends.emplace_back(std::make_unique<WiimoteScannerWindows>());
m_backends.emplace_back(std::make_unique<WiimoteScannerDarwin>());
m_backends.emplace_back(std::make_unique<WiimoteScannerHidapi>());
}