From 8d9a30b370069912d05911efd1f17ef10a0059bd Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Fri, 5 Dec 2014 00:16:41 +0100 Subject: [PATCH] WiimoteReal: use inheritance instead of #ifdef --- Source/Core/Core/HW/WiimoteReal/IODummy.cpp | 43 +----------- Source/Core/Core/HW/WiimoteReal/IONix.cpp | 48 ++++++++----- Source/Core/Core/HW/WiimoteReal/IOWin.cpp | 49 ++++++++----- Source/Core/Core/HW/WiimoteReal/IOdarwin.mm | 69 ++++++++++++++----- .../Core/Core/HW/WiimoteReal/WiimoteReal.cpp | 15 +--- Source/Core/Core/HW/WiimoteReal/WiimoteReal.h | 48 ++++--------- 6 files changed, 131 insertions(+), 141 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/HW/WiimoteReal/IODummy.cpp index 5b14f9012b..090c7141e5 100644 --- a/Source/Core/Core/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IODummy.cpp @@ -9,9 +9,7 @@ namespace WiimoteReal { WiimoteScanner::WiimoteScanner() -{ - return; -} +{} WiimoteScanner::~WiimoteScanner() {} @@ -30,43 +28,4 @@ bool WiimoteScanner::IsReady() const return false; } -void Wiimote::InitInternal() -{} - -void Wiimote::TeardownInternal() -{} - -bool Wiimote::ConnectInternal() -{ - return 0; -} - -void Wiimote::DisconnectInternal() -{ - return; -} - -bool Wiimote::IsConnected() const -{ - return false; -} - -void Wiimote::IOWakeup() -{} - -int Wiimote::IORead(u8* buf) -{ - return 0; -} - -int Wiimote::IOWrite(const u8* buf, size_t len) -{ - return 0; -} - -void Wiimote::EnablePowerAssertionInternal() -{} -void Wiimote::DisablePowerAssertionInternal() -{} - }; diff --git a/Source/Core/Core/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/HW/WiimoteReal/IONix.cpp index 9131bf12a7..adcf9ab62b 100644 --- a/Source/Core/Core/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IONix.cpp @@ -13,6 +13,28 @@ namespace WiimoteReal { +class WiimoteLinux final : public Wiimote +{ +public: + WiimoteLinux(bdaddr_t bdaddr); + ~WiimoteLinux() override; + +protected: + bool ConnectInternal() override; + void DisconnectInternal() override; + bool IsConnected() const override; + void IOWakeup() override; + int IORead(u8* buf) override; + int IOWrite(u8 const* buf, size_t len) override; + +private: + bdaddr_t m_bdaddr; // Bluetooth address + int m_cmd_sock; // Command socket + int m_int_sock; // Interrupt socket + int m_wakeup_pipe_w; + int m_wakeup_pipe_r; +}; + WiimoteScanner::WiimoteScanner() : m_want_wiimotes() , device_id(-1) @@ -102,8 +124,7 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot char bdaddr_str[18] = {}; ba2str(&scan_infos[i].bdaddr, bdaddr_str); - auto* const wm = new Wiimote; - wm->bdaddr = scan_infos[i].bdaddr; + Wiimote* wm = new WiimoteLinux(scan_infos[i].bdaddr); if (IsBalanceBoardName(name)) { found_board = wm; @@ -120,7 +141,7 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot } -void Wiimote::InitInternal() +WiimoteLinux::WiimoteLinux(bdaddr_t bdaddr) : Wiimote(), m_bdaddr(bdaddr) { m_cmd_sock = -1; m_int_sock = -1; @@ -133,17 +154,17 @@ void Wiimote::InitInternal() } m_wakeup_pipe_w = fds[1]; m_wakeup_pipe_r = fds[0]; - m_bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; } -void Wiimote::TeardownInternal() +WiimoteLinux::~WiimoteLinux() { + Shutdown(); close(m_wakeup_pipe_w); close(m_wakeup_pipe_r); } // Connect to a wiimote with a known address. -bool Wiimote::ConnectInternal() +bool WiimoteLinux::ConnectInternal() { sockaddr_l2 addr; addr.l2_family = AF_BLUETOOTH; @@ -176,7 +197,7 @@ bool Wiimote::ConnectInternal() return true; } -void Wiimote::DisconnectInternal() +void WiimoteLinux::DisconnectInternal() { close(m_cmd_sock); close(m_int_sock); @@ -185,12 +206,12 @@ void Wiimote::DisconnectInternal() m_int_sock = -1; } -bool Wiimote::IsConnected() const +bool WiimoteLinux::IsConnected() const { return m_cmd_sock != -1;// && int_sock != -1; } -void Wiimote::IOWakeup() +void WiimoteLinux::IOWakeup() { char c = 0; if (write(m_wakeup_pipe_w, &c, 1) != 1) @@ -202,7 +223,7 @@ void Wiimote::IOWakeup() // positive = read packet // negative = didn't read packet // zero = error -int Wiimote::IORead(u8* buf) +int WiimoteLinux::IORead(u8* buf) { // Block select for 1/2000th of a second @@ -250,14 +271,9 @@ int Wiimote::IORead(u8* buf) return r; } -int Wiimote::IOWrite(u8 const* buf, size_t len) +int WiimoteLinux::IOWrite(u8 const* buf, size_t len) { return write(m_int_sock, buf, (int)len); } -void Wiimote::EnablePowerAssertionInternal() -{} -void Wiimote::DisablePowerAssertionInternal() -{} - }; // WiimoteReal diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp index ae3aae3ca9..65edcc9326 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp @@ -187,6 +187,27 @@ inline void init_lib() namespace WiimoteReal { +class WiimoteWindows final : public Wiimote +{ +public: + WiimoteWindows(const std::basic_string& path); + ~WiimoteWindows() override; + +protected: + bool ConnectInternal() override; + void DisconnectInternal() override; + bool IsConnected() const override; + void IOWakeup() override; + int IORead(u8* buf) override; + int IOWrite(u8 const* buf, size_t len) override; + +private: + std::basic_string m_devicepath; // Unique wiimote reference + HANDLE m_dev_handle; // HID handle + OVERLAPPED m_hid_overlap_read; // Overlap handles + OVERLAPPED m_hid_overlap_write; + enum win_bt_stack_t m_stack; // Type of bluetooth stack to use +}; int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written); int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index); @@ -271,11 +292,11 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot // Query the data for this device if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, nullptr, nullptr)) { - auto const wm = new Wiimote; - wm->m_devicepath = detail_data->DevicePath; + std::basic_string device_path(detail_data->DevicePath); + Wiimote* wm = new WiimoteWindows(device_path); bool real_wiimote = false, is_bb = false; - CheckDeviceType(wm->m_devicepath, real_wiimote, is_bb); + CheckDeviceType(device_path, real_wiimote, is_bb); if (is_bb) { found_board = wm; @@ -499,7 +520,7 @@ bool WiimoteScanner::IsReady() const } // Connect to a wiimote with a known device path. -bool Wiimote::ConnectInternal() +bool WiimoteWindows::ConnectInternal() { if (IsConnected()) return false; @@ -569,7 +590,7 @@ bool Wiimote::ConnectInternal() return true; } -void Wiimote::DisconnectInternal() +void WiimoteWindows::DisconnectInternal() { if (!IsConnected()) return; @@ -583,7 +604,7 @@ void Wiimote::DisconnectInternal() #endif } -void Wiimote::InitInternal() +WiimoteWindows::WiimoteWindows(const std::basic_string& path) : m_devicepath(path) { m_dev_handle = 0; m_stack = MSBT_STACK_UNKNOWN; @@ -595,13 +616,14 @@ void Wiimote::InitInternal() m_hid_overlap_write.hEvent = CreateEvent(nullptr, true, false, nullptr); } -void Wiimote::TeardownInternal() +WiimoteWindows::~WiimoteWindows() { + Shutdown(); CloseHandle(m_hid_overlap_read.hEvent); CloseHandle(m_hid_overlap_write.hEvent); } -bool Wiimote::IsConnected() const +bool WiimoteWindows::IsConnected() const { return m_dev_handle != 0; } @@ -660,7 +682,7 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index return bytes + 1; } -void Wiimote::IOWakeup() +void WiimoteWindows::IOWakeup() { SetEvent(m_hid_overlap_read.hEvent); } @@ -669,7 +691,7 @@ void Wiimote::IOWakeup() // positive = read packet // negative = didn't read packet // zero = error -int Wiimote::IORead(u8* buf) +int WiimoteWindows::IORead(u8* buf) { return _IORead(m_dev_handle, m_hid_overlap_read, buf, m_index); } @@ -772,16 +794,11 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac return 0; } -int Wiimote::IOWrite(const u8* buf, size_t len) +int WiimoteWindows::IOWrite(const u8* buf, size_t len) { return _IOWrite(m_dev_handle, m_hid_overlap_write, m_stack, buf, len, nullptr); } -void Wiimote::EnablePowerAssertionInternal() -{} -void Wiimote::DisablePowerAssertionInternal() -{} - // invokes callback for each found wiimote bluetooth device template void ProcessWiimotes(bool new_scan, T& callback) diff --git a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm index 78c13734ba..9e00d946c8 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/HW/WiimoteReal/IOdarwin.mm @@ -16,6 +16,35 @@ namespace WiimoteReal { +class WiimoteDarwin final : public Wiimote +{ +public: + WiimoteDarwin(IOBluetoothDevice* device); + ~WiimoteDarwin() override; + + // 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; +}; + WiimoteScanner::WiimoteScanner() : m_run_thread() , m_want_wiimotes() @@ -76,8 +105,7 @@ void WiimoteScanner::FindWiimotes(std::vector & found_wiimotes, Wiimot if (!IsValidBluetoothName([[dev name] UTF8String])) continue; - Wiimote *wm = new Wiimote(); - wm->m_btd = [dev retain]; + Wiimote* wm = new WiimoteDarwin([dev retain]); if (IsBalanceBoardName([[dev name] UTF8String])) { @@ -100,17 +128,17 @@ bool WiimoteScanner::IsReady() const return true; } -void Wiimote::InitInternal() +WiimoteDarwin::WiimoteDarwin(IOBluetoothDevice* device) : m_btd(device) { m_inputlen = 0; m_connected = false; m_wiimote_thread_run_loop = nullptr; - m_btd = nil; m_pm_assertion = kIOPMNullAssertionID; } -void Wiimote::TeardownInternal() +WiimoteDarwin::~WiimoteDarwin() { + Shutdown(); if (m_wiimote_thread_run_loop) { CFRelease(m_wiimote_thread_run_loop); @@ -118,10 +146,11 @@ void Wiimote::TeardownInternal() } [m_btd release]; m_btd = nil; + DisablePowerAssertionInternal(); } // Connect to a wiimote with a known address. -bool Wiimote::ConnectInternal() +bool WiimoteDarwin::ConnectInternal() { if (IsConnected()) return false; @@ -182,7 +211,7 @@ bad: } // Disconnect a wiimote. -void Wiimote::DisconnectInternal() +void WiimoteDarwin::DisconnectInternal() { [m_ichan closeChannel]; [m_ichan release]; @@ -202,12 +231,12 @@ void Wiimote::DisconnectInternal() m_connected = false; } -bool Wiimote::IsConnected() const +bool WiimoteDarwin::IsConnected() const { return m_connected; } -void Wiimote::IOWakeup() +void WiimoteDarwin::IOWakeup() { if (m_wiimote_thread_run_loop) { @@ -215,7 +244,7 @@ void Wiimote::IOWakeup() } } -int Wiimote::IORead(unsigned char *buf) +int WiimoteDarwin::IORead(unsigned char *buf) { m_input = buf; m_inputlen = -1; @@ -225,7 +254,7 @@ int Wiimote::IORead(unsigned char *buf) return m_inputlen; } -int Wiimote::IOWrite(const unsigned char *buf, size_t len) +int WiimoteDarwin::IOWrite(const unsigned char *buf, size_t len) { IOReturn ret; @@ -240,7 +269,7 @@ int Wiimote::IOWrite(const unsigned char *buf, size_t len) return 0; } -void Wiimote::EnablePowerAssertionInternal() +void WiimoteDarwin::EnablePowerAssertionInternal() { if (m_pm_assertion == kIOPMNullAssertionID) { @@ -249,7 +278,7 @@ void Wiimote::EnablePowerAssertionInternal() } } -void Wiimote::DisablePowerAssertionInternal() +void WiimoteDarwin::DisablePowerAssertionInternal() { if (m_pm_assertion != kIOPMNullAssertionID) { @@ -287,7 +316,7 @@ void Wiimote::DisablePowerAssertionInternal() length: (NSUInteger) length { IOBluetoothDevice *device = [l2capChannel device]; - WiimoteReal::Wiimote *wm = nullptr; + WiimoteReal::WiimoteDarwin *wm = nullptr; std::lock_guard lk(WiimoteReal::g_refresh_lock); @@ -295,8 +324,9 @@ void Wiimote::DisablePowerAssertionInternal() { if (WiimoteReal::g_wiimotes[i] == nullptr) continue; - if ([device isEqual: WiimoteReal::g_wiimotes[i]->m_btd] == TRUE) - wm = WiimoteReal::g_wiimotes[i]; + wm = static_cast(WiimoteReal::g_wiimotes[i]); + if ([device isEqual: wm->m_btd] != TRUE) + wm = nullptr; } if (wm == nullptr) { @@ -325,7 +355,7 @@ void Wiimote::DisablePowerAssertionInternal() - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel { IOBluetoothDevice *device = [l2capChannel device]; - WiimoteReal::Wiimote *wm = nullptr; + WiimoteReal::WiimoteDarwin *wm = nullptr; std::lock_guard lk(WiimoteReal::g_refresh_lock); @@ -333,8 +363,9 @@ void Wiimote::DisablePowerAssertionInternal() { if (WiimoteReal::g_wiimotes[i] == nullptr) continue; - if ([device isEqual: WiimoteReal::g_wiimotes[i]->m_btd] == TRUE) - wm = WiimoteReal::g_wiimotes[i]; + wm = static_cast(WiimoteReal::g_wiimotes[i]); + if ([device isEqual: wm->m_btd] != TRUE) + wm = nullptr; } if (wm == nullptr) { diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp index cd16caddc3..36b797f697 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp @@ -42,17 +42,13 @@ Wiimote::Wiimote() , m_channel(0) , m_rumble_state() , m_need_prepare() -{ - InitInternal(); -} +{} -Wiimote::~Wiimote() +void Wiimote::Shutdown() { - DisablePowerAssertionInternal(); StopThread(); ClearReadQueue(); m_write_reports.Clear(); - TeardownInternal(); } // to be called from CPU thread @@ -62,12 +58,9 @@ void Wiimote::WriteReport(Report rpt) { bool const new_rumble_state = (rpt[2] & 0x1) != 0; + // If this is a rumble report and the rumble state didn't change, ignore. if (WM_RUMBLE == rpt[1] && new_rumble_state == m_rumble_state) - { - // If this is a rumble report and the rumble state didn't change, ignore - //ERROR_LOG(WIIMOTE, "Ignoring rumble report."); return; - } m_rumble_state = new_rumble_state; } @@ -508,8 +501,6 @@ void Wiimote::StopThread() IOWakeup(); if (m_wiimote_thread.joinable()) m_wiimote_thread.join(); -#if defined(__APPLE__) -#endif } void Wiimote::SetReady() diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h index f79067feb7..b7edb53d72 100644 --- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.h @@ -26,8 +26,9 @@ class Wiimote : NonCopyable { friend class WiimoteEmu::Wiimote; public: - Wiimote(); - ~Wiimote(); + virtual ~Wiimote() {} + // This needs to be called in derived destructors! + void Shutdown(); void ControlChannel(const u16 channel, const void* const data, const u32 size); void InterruptChannel(const u16 channel, const void* const data, const u32 size); @@ -47,22 +48,19 @@ public: void EmuResume(); void EmuPause(); - void EnablePowerAssertionInternal(); - void DisablePowerAssertionInternal(); + virtual void EnablePowerAssertionInternal() {} + virtual void DisablePowerAssertionInternal() {} // connecting and disconnecting from physical devices // (using address inserted by FindWiimotes) // these are called from the wiimote's thread. - bool ConnectInternal(); - void DisconnectInternal(); - - void InitInternal(); - void TeardownInternal(); + virtual bool ConnectInternal() = 0; + virtual void DisconnectInternal() = 0; bool Connect(); // TODO: change to something like IsRelevant - bool IsConnected() const; + virtual bool IsConnected() const = 0; void Prepare(int index); bool PrepareOnThread(); @@ -75,30 +73,8 @@ public: int m_index; -#if defined(__APPLE__) - IOBluetoothDevice *m_btd; - IOBluetoothL2CAPChannel *m_ichan; - IOBluetoothL2CAPChannel *m_cchan; - unsigned char* m_input; - int m_inputlen; - bool m_connected; - CFRunLoopRef m_wiimote_thread_run_loop; - IOPMAssertionID m_pm_assertion; -#elif defined(__linux__) && HAVE_BLUEZ - bdaddr_t m_bdaddr; // Bluetooth address - int m_cmd_sock; // Command socket - int m_int_sock; // Interrupt socket - int m_wakeup_pipe_w, m_wakeup_pipe_r; - -#elif defined(_WIN32) - std::basic_string m_devicepath; // Unique wiimote reference - //ULONGLONG btaddr; // Bluetooth address - HANDLE m_dev_handle; // HID handle - OVERLAPPED m_hid_overlap_read, m_hid_overlap_write; // Overlap handle - enum win_bt_stack_t m_stack; // Type of bluetooth stack to use -#endif - protected: + Wiimote(); Report m_last_input_report; u16 m_channel; @@ -106,9 +82,9 @@ private: void ClearReadQueue(); void WriteReport(Report rpt); - int IORead(u8* buf); - int IOWrite(u8 const* buf, size_t len); - void IOWakeup(); + virtual int IORead(u8* buf) = 0; + virtual int IOWrite(u8 const* buf, size_t len) = 0; + virtual void IOWakeup() = 0; void ThreadFunc(); void SetReady();