diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 5ce8447946..9fe3f9a9db 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -176,6 +176,8 @@ bool Wiimote::Connect() // Set LEDs SetLEDs(WIIMOTE_LED_1 << index); + m_wiimote_thread = std::thread(StartThread, this); + return true; } @@ -189,6 +191,9 @@ void Wiimote::RealDisconnect() m_connected = false; + if (m_wiimote_thread.joinable()) + m_wiimote_thread.join(); + close(out_sock); close(in_sock); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 9922139ca3..e08911fa97 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -237,6 +237,8 @@ bool Wiimote::Connect() // Set LEDs SetLEDs(WIIMOTE_LED_1 << index); + m_wiimote_thread = std::thread(StartThread, this); + NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1); return true; @@ -249,6 +251,9 @@ void Wiimote::RealDisconnect() m_connected = false; + if (m_wiimote_thread.joinable()) + m_wiimote_thread.join(); + CloseHandle(dev_handle); dev_handle = 0; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 654b71e2a8..111b7b0177 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -198,6 +198,8 @@ bool Wiimote::Connect() Handshake(); SetLEDs(WIIMOTE_LED_1 << index); + m_wiimote_thread = std::thread(StartThread, this); + [cbt release]; return true; @@ -213,6 +215,9 @@ void Wiimote::RealDisconnect() m_connected = false; + if (m_wiimote_thread.joinable()) + m_wiimote_thread.join(); + [btd closeConnection]; btd = NULL; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 6727194714..bc47775849 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -40,14 +40,8 @@ namespace WiimoteReal bool g_real_wiimotes_initialized = false; unsigned int g_wiimotes_found = 0; -volatile bool g_run_wiimote_thread = false; -std::thread g_wiimote_threads[MAX_WIIMOTES] = {}; Common::CriticalSection g_refresh_critsec; -void WiimoteThreadFunc(Wiimote* arg); -void StartWiimoteThreads(); -void StopWiimoteThreads(); - Wiimote *g_wiimotes[MAX_WIIMOTES]; Wiimote::Wiimote(const unsigned int _index) @@ -307,6 +301,46 @@ bool Wiimote::SendRequest(unsigned char report_type, unsigned char* data, int le return (IOWrite(buffer, length + 2) != 0); } +void Wiimote::StartThread(Wiimote *wiimote) +{ + wiimote->ThreadFunc(); +} + +void Wiimote::ThreadFunc() +{ +#ifdef __APPLE__ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; +#endif + + char thname[] = "Wiimote # Thread"; + thname[8] = (char)('1' + index); + Common::SetCurrentThreadName(thname); + + // rumble briefly + Rumble(); + + Host_ConnectWiimote(index, true); + + // main loop + while (IsConnected()) + { + // hopefully this is alright + while (Write()) {} + +#ifndef __APPLE__ + // sleep if there was nothing to read + if (false == Read()) +#endif + Common::SleepCurrentThread(1); + } + + Host_ConnectWiimote(index, false); + +#ifdef __APPLE__ + [pool release]; +#endif +} + #ifndef _WIN32 // Connect all discovered wiimotes // Return the number of wiimotes that successfully connected. @@ -385,8 +419,6 @@ unsigned int Initialize() DEBUG_LOG(WIIMOTE, "Connected to %i Real Wiimotes", g_wiimotes_found); - StartWiimoteThreads(); - return g_wiimotes_found; } @@ -398,8 +430,6 @@ void Shutdown(void) // Uninitialized g_real_wiimotes_initialized = false; - StopWiimoteThreads(); - // Delete wiimotes for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) if (g_wiimotes[i]) @@ -412,6 +442,12 @@ void Shutdown(void) // This is called from the GUI thread void Refresh() { +#ifdef _WIN32 + g_refresh_critsec.Enter(); + Shutdown(); + Initialize(); + g_refresh_critsec.Leave(); +#else // Make sure real wiimotes have been initialized if (!g_real_wiimotes_initialized) { @@ -425,8 +461,6 @@ void Refresh() if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]) ++wanted_wiimotes; - StopWiimoteThreads(); - g_refresh_critsec.Enter(); // Remove wiimotes that are paired with slots no longer configured for a @@ -448,19 +482,16 @@ void Refresh() DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", num_wiimotes, wanted_wiimotes); -#ifndef _WIN32 // Connect newly found wiimotes. int num_new_wiimotes = ConnectWiimotes(g_wiimotes); DEBUG_LOG(WIIMOTE, "Connected to %i additional Real Wiimotes", num_new_wiimotes); -#endif g_wiimotes_found = num_wiimotes; } g_refresh_critsec.Leave(); - - StartWiimoteThreads(); +#endif } void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) @@ -504,55 +535,4 @@ void StateChange(PLUGIN_EMUSTATE newState) //g_refresh_critsec.Leave(); // leave } -void StartWiimoteThreads() -{ - g_run_wiimote_thread = true; - for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) - if (g_wiimotes[i] && !g_wiimote_threads[i].joinable()) - g_wiimote_threads[i] = std::thread(WiimoteThreadFunc, g_wiimotes[i]); -} - -void StopWiimoteThreads() -{ - g_run_wiimote_thread = false; - for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) - if (g_wiimote_threads[i].joinable()) - g_wiimote_threads[i].join(); -} - -void WiimoteThreadFunc(Wiimote* wiimote) -{ -#ifdef __APPLE__ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -#endif - - char thname[] = "Wiimote # Thread"; - thname[8] = (char)('1' + wiimote->index); - Common::SetCurrentThreadName(thname); - - // rumble briefly - wiimote->Rumble(); - - Host_ConnectWiimote(wiimote->index, true); - - // main loop - while (g_run_wiimote_thread && wiimote->IsConnected()) - { - // hopefully this is alright - while (wiimote->Write()) {} - -#ifndef __APPLE__ - // sleep if there was nothing to read - if (false == wiimote->Read()) -#endif - Common::SleepCurrentThread(1); - } - - Host_ConnectWiimote(wiimote->index, false); - -#ifdef __APPLE__ - [pool release]; -#endif -} - }; // end of namespace diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 038aa70ca8..7cbdacd5b7 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -90,8 +90,11 @@ private: void SetLEDs(int leds); int IORead(unsigned char* buf); int IOWrite(unsigned char* buf, int len); + static void StartThread(Wiimote *wiimote); + void ThreadFunc(); bool m_connected; + std::thread m_wiimote_thread; Common::FifoQueue m_read_reports; Common::FifoQueue m_write_reports; };