void TryToConnectBalanceBoard(Wiimote* wm) { std::unique_lock<std::recursive_mutex> lk(g_refresh_lock); if (TryToConnectWiimoteN(wm, WIIMOTE_BALANCE_BOARD)) { wm = nullptr; } g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); lk.unlock(); delete wm; }
void ChangeWiimoteSource(unsigned int index, int source) { { std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); g_wiimote_sources[index] = source; g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); // kill real connection (or swap to different slot) DoneWithWiimote(index); } // reconnect to the emulator Host_ConnectWiimote(index, false); if (WIIMOTE_SRC_EMU & source) Host_ConnectWiimote(index, true); }
void HandleWiimoteDisconnect(int index) { Wiimote* wm = nullptr; { std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::swap(wm, g_wiimotes[index]); g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); } if (wm) { delete wm; NOTICE_LOG(WIIMOTE, "Disconnected Wiimote %i.", index + 1); } }
void WiimoteScanner::ThreadFunc() { Common::SetCurrentThreadName("Wiimote Scanning Thread"); NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has started."); while (m_scan_thread_running.IsSet()) { m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500)); CheckForDisconnectedWiimotes(); if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN) continue; for (const auto& backend : m_scanner_backends) { if (CalculateWantedWiimotes() != 0 || CalculateWantedBB() != 0) { std::vector<Wiimote*> found_wiimotes; Wiimote* found_board = nullptr; backend->FindWiimotes(found_wiimotes, found_board); { std::lock_guard<std::mutex> lk(g_wiimotes_mutex); std::for_each(found_wiimotes.begin(), found_wiimotes.end(), TryToConnectWiimote); if (found_board) TryToConnectBalanceBoard(found_board); } } else { backend->Update(); // Does stuff needed to detect disconnects on Windows } } if (m_scan_mode.load() == WiimoteScanMode::SCAN_ONCE) m_scan_mode.store(WiimoteScanMode::DO_NOT_SCAN); } NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has stopped."); }
// This is called from the GUI thread void Refresh() { g_wiimote_scanner.StopScanning(); { std::unique_lock<std::recursive_mutex> lk(g_refresh_lock); std::vector<Wiimote*> found_wiimotes; Wiimote* found_board = nullptr; if (0 != CalculateWantedWiimotes() || 0 != CalculateWantedBB()) { // Don't hang Dolphin when searching lk.unlock(); g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board); lk.lock(); } CheckForDisconnectedWiimotes(); // Brief rumble for already connected Wiimotes. // Don't do this for Balance Board as it doesn't have rumble anyway. for (int i = 0; i < MAX_WIIMOTES; ++i) { if (g_wiimotes[i]) { g_wiimotes[i]->Prepare(i); } } HandleFoundWiimotes(found_wiimotes); if (found_board) TryToConnectBalanceBoard(found_board); } Initialize(); }
// config dialog calls this when some settings change void Initialize(bool wait) { if (SConfig::GetInstance().m_WiimoteContinuousScanning) g_wiimote_scanner.StartScanning(); else g_wiimote_scanner.StopScanning(); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.WantBB(0 != CalculateWantedBB()); // wait for connection because it should exist before state load if (wait) { int timeout = 100; std::vector<Wiimote*> found_wiimotes; Wiimote* found_board = nullptr; g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board); if (SConfig::GetInstance().m_WiimoteContinuousScanning) { while (CalculateWantedWiimotes() && CalculateConnectedWiimotes() < found_wiimotes.size() && timeout) { Common::SleepCurrentThread(100); timeout--; } } } if (g_real_wiimotes_initialized) return; NOTICE_LOG(WIIMOTE, "WiimoteReal::Initialize"); g_real_wiimotes_initialized = true; }