mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 08:49:20 +01:00
Merge pull request #3988 from leoetlino/scanning-block
WiimoteReal: Don't block on refresh
This commit is contained in:
commit
3a895f88bf
@ -533,7 +533,9 @@ void EmuThread()
|
|||||||
if (core_parameter.bWii)
|
if (core_parameter.bWii)
|
||||||
{
|
{
|
||||||
if (init_controllers)
|
if (init_controllers)
|
||||||
Wiimote::Initialize(s_window_handle, !s_state_filename.empty());
|
Wiimote::Initialize(s_window_handle, !s_state_filename.empty() ?
|
||||||
|
Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES :
|
||||||
|
Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
|
||||||
else
|
else
|
||||||
Wiimote::LoadConfig();
|
Wiimote::LoadConfig();
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ void Shutdown()
|
|||||||
g_controller_interface.Shutdown();
|
g_controller_interface.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(void* const hwnd, bool wait)
|
void Initialize(void* const hwnd, InitializeMode init_mode)
|
||||||
{
|
{
|
||||||
if (s_config.ControllersNeedToBeCreated())
|
if (s_config.ControllersNeedToBeCreated())
|
||||||
{
|
{
|
||||||
@ -40,7 +40,7 @@ void Initialize(void* const hwnd, bool wait)
|
|||||||
|
|
||||||
s_config.LoadConfig(false);
|
s_config.LoadConfig(false);
|
||||||
|
|
||||||
WiimoteReal::Initialize(wait);
|
WiimoteReal::Initialize(init_mode);
|
||||||
|
|
||||||
// Reload Wiimotes with our settings
|
// Reload Wiimotes with our settings
|
||||||
if (Movie::IsMovieActive())
|
if (Movie::IsMovieActive())
|
||||||
|
@ -35,8 +35,14 @@ extern unsigned int g_wiimote_sources[MAX_BBMOTES];
|
|||||||
|
|
||||||
namespace Wiimote
|
namespace Wiimote
|
||||||
{
|
{
|
||||||
|
enum class InitializeMode
|
||||||
|
{
|
||||||
|
DO_WAIT_FOR_WIIMOTES,
|
||||||
|
DO_NOT_WAIT_FOR_WIIMOTES,
|
||||||
|
};
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Initialize(void* const hwnd, bool wait = false);
|
void Initialize(void* const hwnd, InitializeMode init_mode);
|
||||||
void ResetAllWiimotes();
|
void ResetAllWiimotes();
|
||||||
void LoadConfig();
|
void LoadConfig();
|
||||||
void Resume();
|
void Resume();
|
||||||
@ -54,7 +60,7 @@ void Update(int _number, bool _connected);
|
|||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
{
|
{
|
||||||
void Initialize(bool wait = false);
|
void Initialize(::Wiimote::InitializeMode init_mode);
|
||||||
void Stop();
|
void Stop();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Resume();
|
void Resume();
|
||||||
|
@ -231,7 +231,7 @@ void Wiimote::RequestStatus(const wm_request_status* const rs)
|
|||||||
{
|
{
|
||||||
using namespace WiimoteReal;
|
using namespace WiimoteReal;
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
if (g_wiimotes[m_index])
|
if (g_wiimotes[m_index])
|
||||||
{
|
{
|
||||||
|
@ -662,7 +662,7 @@ void Wiimote::Update()
|
|||||||
{
|
{
|
||||||
using namespace WiimoteReal;
|
using namespace WiimoteReal;
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
if (g_wiimotes[m_index])
|
if (g_wiimotes[m_index])
|
||||||
{
|
{
|
||||||
const Report& rpt = g_wiimotes[m_index]->ProcessReadQueue();
|
const Report& rpt = g_wiimotes[m_index]->ProcessReadQueue();
|
||||||
|
@ -500,7 +500,7 @@ void WiimoteDarwinHid::RemoveCallback(void* context, IOReturn result, void*)
|
|||||||
IOBluetoothDevice* device = [l2capChannel device];
|
IOBluetoothDevice* device = [l2capChannel device];
|
||||||
WiimoteReal::WiimoteDarwin* wm = nullptr;
|
WiimoteReal::WiimoteDarwin* wm = nullptr;
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lk(WiimoteReal::g_refresh_lock);
|
std::lock_guard<std::mutex> lk(WiimoteReal::g_wiimotes_mutex);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_WIIMOTES; i++)
|
for (int i = 0; i < MAX_WIIMOTES; i++)
|
||||||
{
|
{
|
||||||
@ -541,7 +541,7 @@ void WiimoteDarwinHid::RemoveCallback(void* context, IOReturn result, void*)
|
|||||||
IOBluetoothDevice* device = [l2capChannel device];
|
IOBluetoothDevice* device = [l2capChannel device];
|
||||||
WiimoteReal::WiimoteDarwin* wm = nullptr;
|
WiimoteReal::WiimoteDarwin* wm = nullptr;
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lk(WiimoteReal::g_refresh_lock);
|
std::lock_guard<std::mutex> lk(WiimoteReal::g_wiimotes_mutex);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_WIIMOTES; i++)
|
for (int i = 0; i < MAX_WIIMOTES; i++)
|
||||||
{
|
{
|
||||||
|
@ -25,15 +25,13 @@ unsigned int g_wiimote_sources[MAX_BBMOTES];
|
|||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
{
|
{
|
||||||
void HandleFoundWiimotes(const std::vector<Wiimote*>&);
|
|
||||||
void TryToConnectBalanceBoard(Wiimote*);
|
void TryToConnectBalanceBoard(Wiimote*);
|
||||||
void TryToConnectWiimote(Wiimote*);
|
void TryToConnectWiimote(Wiimote*);
|
||||||
void HandleWiimoteDisconnect(int index);
|
void HandleWiimoteDisconnect(int index);
|
||||||
void DoneWithWiimote(int index);
|
|
||||||
|
|
||||||
static bool g_real_wiimotes_initialized = false;
|
static bool g_real_wiimotes_initialized = false;
|
||||||
|
|
||||||
std::recursive_mutex g_refresh_lock;
|
std::mutex g_wiimotes_mutex;
|
||||||
|
|
||||||
Wiimote* g_wiimotes[MAX_BBMOTES];
|
Wiimote* g_wiimotes[MAX_BBMOTES];
|
||||||
WiimoteScanner g_wiimote_scanner;
|
WiimoteScanner g_wiimote_scanner;
|
||||||
@ -402,6 +400,7 @@ void Wiimote::EmuPause()
|
|||||||
|
|
||||||
static unsigned int CalculateConnectedWiimotes()
|
static unsigned int CalculateConnectedWiimotes()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
unsigned int connected_wiimotes = 0;
|
unsigned int connected_wiimotes = 0;
|
||||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
if (g_wiimotes[i])
|
if (g_wiimotes[i])
|
||||||
@ -412,6 +411,7 @@ static unsigned int CalculateConnectedWiimotes()
|
|||||||
|
|
||||||
static unsigned int CalculateWantedWiimotes()
|
static unsigned int CalculateWantedWiimotes()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
// Figure out how many real Wiimotes are required
|
// Figure out how many real Wiimotes are required
|
||||||
unsigned int wanted_wiimotes = 0;
|
unsigned int wanted_wiimotes = 0;
|
||||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
@ -423,6 +423,7 @@ static unsigned int CalculateWantedWiimotes()
|
|||||||
|
|
||||||
static unsigned int CalculateWantedBB()
|
static unsigned int CalculateWantedBB()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
unsigned int wanted_bb = 0;
|
unsigned int wanted_bb = 0;
|
||||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD] &&
|
if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD] &&
|
||||||
!g_wiimotes[WIIMOTE_BALANCE_BOARD])
|
!g_wiimotes[WIIMOTE_BALANCE_BOARD])
|
||||||
@ -430,38 +431,32 @@ static unsigned int CalculateWantedBB()
|
|||||||
return wanted_bb;
|
return wanted_bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiimoteScanner::WantWiimotes(bool do_want)
|
void WiimoteScanner::StartThread()
|
||||||
{
|
{
|
||||||
m_want_wiimotes.store(do_want);
|
if (m_scan_thread_running.IsSet())
|
||||||
|
return;
|
||||||
|
m_scan_thread_running.Set();
|
||||||
|
m_scan_thread = std::thread(&WiimoteScanner::ThreadFunc, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiimoteScanner::WantBB(bool do_want)
|
void WiimoteScanner::StopThread()
|
||||||
{
|
{
|
||||||
m_want_bb.store(do_want);
|
if (m_scan_thread_running.TestAndClear())
|
||||||
}
|
|
||||||
|
|
||||||
void WiimoteScanner::StartScanning()
|
|
||||||
{
|
|
||||||
if (!m_run_thread.load())
|
|
||||||
{
|
|
||||||
m_run_thread.store(true);
|
|
||||||
m_scan_thread = std::thread(&WiimoteScanner::ThreadFunc, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WiimoteScanner::StopScanning()
|
|
||||||
{
|
|
||||||
m_run_thread.store(false);
|
|
||||||
if (m_scan_thread.joinable())
|
|
||||||
{
|
{
|
||||||
|
SetScanMode(WiimoteScanMode::DO_NOT_SCAN);
|
||||||
m_scan_thread.join();
|
m_scan_thread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WiimoteScanner::SetScanMode(WiimoteScanMode scan_mode)
|
||||||
|
{
|
||||||
|
m_scan_mode.store(scan_mode);
|
||||||
|
m_scan_mode_changed_event.Set();
|
||||||
|
}
|
||||||
|
|
||||||
static void CheckForDisconnectedWiimotes()
|
static void CheckForDisconnectedWiimotes()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
||||||
if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected())
|
if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected())
|
||||||
HandleWiimoteDisconnect(i);
|
HandleWiimoteDisconnect(i);
|
||||||
@ -471,41 +466,36 @@ void WiimoteScanner::ThreadFunc()
|
|||||||
{
|
{
|
||||||
Common::SetCurrentThreadName("Wiimote Scanning Thread");
|
Common::SetCurrentThreadName("Wiimote Scanning Thread");
|
||||||
|
|
||||||
NOTICE_LOG(WIIMOTE, "Wiimote scanning has started.");
|
NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has started.");
|
||||||
|
|
||||||
while (m_run_thread.load())
|
while (m_scan_thread_running.IsSet())
|
||||||
{
|
{
|
||||||
std::vector<Wiimote*> found_wiimotes;
|
m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500));
|
||||||
Wiimote* found_board = nullptr;
|
|
||||||
|
|
||||||
// NOTICE_LOG(WIIMOTE, "In loop");
|
Update(); // Does stuff needed to detect disconnects on Windows
|
||||||
|
|
||||||
if (m_want_wiimotes.load() || m_want_bb.load())
|
|
||||||
{
|
|
||||||
FindWiimotes(found_wiimotes, found_board);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Does stuff needed to detect disconnects on Windows
|
|
||||||
Update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTICE_LOG(WIIMOTE, "After update");
|
|
||||||
|
|
||||||
// TODO: this is a fairly lame place for this
|
|
||||||
CheckForDisconnectedWiimotes();
|
CheckForDisconnectedWiimotes();
|
||||||
|
|
||||||
if (m_want_wiimotes.load())
|
if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN)
|
||||||
HandleFoundWiimotes(found_wiimotes);
|
continue;
|
||||||
|
|
||||||
if (m_want_bb.load() && found_board)
|
if (CalculateWantedWiimotes() != 0 || CalculateWantedBB() != 0)
|
||||||
TryToConnectBalanceBoard(found_board);
|
{
|
||||||
|
std::vector<Wiimote*> found_wiimotes;
|
||||||
|
Wiimote* found_board = nullptr;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// std::this_thread::yield();
|
if (m_scan_mode.load() == WiimoteScanMode::SCAN_ONCE)
|
||||||
Common::SleepCurrentThread(500);
|
m_scan_mode.store(WiimoteScanMode::DO_NOT_SCAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
NOTICE_LOG(WIIMOTE, "Wiimote scanning has stopped.");
|
NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wiimote::Connect(int index)
|
bool Wiimote::Connect(int index)
|
||||||
@ -621,33 +611,25 @@ void LoadSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// config dialog calls this when some settings change
|
// config dialog calls this when some settings change
|
||||||
void Initialize(bool wait)
|
void Initialize(::Wiimote::InitializeMode init_mode)
|
||||||
{
|
{
|
||||||
|
if (!g_real_wiimotes_initialized)
|
||||||
|
g_wiimote_scanner.StartThread();
|
||||||
|
|
||||||
if (SConfig::GetInstance().m_WiimoteContinuousScanning)
|
if (SConfig::GetInstance().m_WiimoteContinuousScanning)
|
||||||
g_wiimote_scanner.StartScanning();
|
g_wiimote_scanner.SetScanMode(WiimoteScanMode::CONTINUOUSLY_SCAN);
|
||||||
else
|
else
|
||||||
g_wiimote_scanner.StopScanning();
|
g_wiimote_scanner.SetScanMode(WiimoteScanMode::DO_NOT_SCAN);
|
||||||
|
|
||||||
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
|
// wait for connection because it should exist before state load
|
||||||
if (wait)
|
if (init_mode == ::Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES)
|
||||||
{
|
{
|
||||||
int timeout = 100;
|
int timeout = 100;
|
||||||
std::vector<Wiimote*> found_wiimotes;
|
g_wiimote_scanner.SetScanMode(WiimoteScanMode::SCAN_ONCE);
|
||||||
Wiimote* found_board = nullptr;
|
while (CalculateWantedWiimotes() > CalculateConnectedWiimotes() && timeout)
|
||||||
g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board);
|
|
||||||
if (SConfig::GetInstance().m_WiimoteContinuousScanning)
|
|
||||||
{
|
{
|
||||||
while (CalculateWantedWiimotes() && CalculateConnectedWiimotes() < found_wiimotes.size() &&
|
Common::SleepCurrentThread(100);
|
||||||
timeout)
|
timeout--;
|
||||||
{
|
|
||||||
Common::SleepCurrentThread(100);
|
|
||||||
timeout--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,17 +652,11 @@ void Stop()
|
|||||||
// called when the Dolphin app exits
|
// called when the Dolphin app exits
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
g_wiimote_scanner.StopScanning();
|
g_wiimote_scanner.StopThread();
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
|
||||||
|
|
||||||
if (!g_real_wiimotes_initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NOTICE_LOG(WIIMOTE, "WiimoteReal::Shutdown");
|
NOTICE_LOG(WIIMOTE, "WiimoteReal::Shutdown");
|
||||||
|
|
||||||
g_real_wiimotes_initialized = false;
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
||||||
HandleWiimoteDisconnect(i);
|
HandleWiimoteDisconnect(i);
|
||||||
}
|
}
|
||||||
@ -701,13 +677,22 @@ void Pause()
|
|||||||
|
|
||||||
void ChangeWiimoteSource(unsigned int index, int source)
|
void ChangeWiimoteSource(unsigned int index, int source)
|
||||||
{
|
{
|
||||||
|
g_wiimote_sources[index] = 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)
|
// kill real connection (or swap to different slot)
|
||||||
DoneWithWiimote(index);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
|
Wiimote* wm = g_wiimotes[index];
|
||||||
|
|
||||||
|
if (wm)
|
||||||
|
{
|
||||||
|
g_wiimotes[index] = nullptr;
|
||||||
|
// First see if we can use this real Wiimote in another slot.
|
||||||
|
TryToConnectWiimote(wm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// else, just disconnect the Wiimote
|
||||||
|
HandleWiimoteDisconnect(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reconnect to the emulator
|
// reconnect to the emulator
|
||||||
@ -716,7 +701,7 @@ void ChangeWiimoteSource(unsigned int index, int source)
|
|||||||
Host_ConnectWiimote(index, true);
|
Host_ConnectWiimote(index, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TryToConnectWiimoteN(Wiimote* wm, unsigned int i)
|
static bool TryToConnectWiimoteToSlot(Wiimote* wm, unsigned int i)
|
||||||
{
|
{
|
||||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i])
|
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i])
|
||||||
{
|
{
|
||||||
@ -733,69 +718,30 @@ static bool TryToConnectWiimoteN(Wiimote* wm, unsigned int i)
|
|||||||
|
|
||||||
void TryToConnectWiimote(Wiimote* wm)
|
void TryToConnectWiimote(Wiimote* wm)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
{
|
{
|
||||||
if (TryToConnectWiimoteN(wm, i))
|
if (TryToConnectWiimoteToSlot(wm, i))
|
||||||
{
|
{
|
||||||
wm = nullptr;
|
wm = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
|
|
||||||
|
|
||||||
lk.unlock();
|
|
||||||
|
|
||||||
delete wm;
|
delete wm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryToConnectBalanceBoard(Wiimote* wm)
|
void TryToConnectBalanceBoard(Wiimote* wm)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
|
if (TryToConnectWiimoteToSlot(wm, WIIMOTE_BALANCE_BOARD))
|
||||||
|
|
||||||
if (TryToConnectWiimoteN(wm, WIIMOTE_BALANCE_BOARD))
|
|
||||||
{
|
{
|
||||||
wm = nullptr;
|
wm = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
|
|
||||||
|
|
||||||
lk.unlock();
|
|
||||||
|
|
||||||
delete wm;
|
delete wm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoneWithWiimote(int index)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
|
||||||
|
|
||||||
Wiimote* wm = g_wiimotes[index];
|
|
||||||
|
|
||||||
if (wm)
|
|
||||||
{
|
|
||||||
g_wiimotes[index] = nullptr;
|
|
||||||
// First see if we can use this real Wiimote in another slot.
|
|
||||||
TryToConnectWiimote(wm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// else, just disconnect the Wiimote
|
|
||||||
HandleWiimoteDisconnect(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleWiimoteDisconnect(int index)
|
void HandleWiimoteDisconnect(int index)
|
||||||
{
|
{
|
||||||
Wiimote* wm = nullptr;
|
Wiimote* wm = nullptr;
|
||||||
|
std::swap(wm, g_wiimotes[index]);
|
||||||
{
|
|
||||||
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)
|
if (wm)
|
||||||
{
|
{
|
||||||
delete wm;
|
delete wm;
|
||||||
@ -803,99 +749,60 @@ void HandleWiimoteDisconnect(int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleFoundWiimotes(const std::vector<Wiimote*>& wiimotes)
|
|
||||||
{
|
|
||||||
std::for_each(wiimotes.begin(), wiimotes.end(), TryToConnectWiimote);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is called from the GUI thread
|
// This is called from the GUI thread
|
||||||
void Refresh()
|
void Refresh()
|
||||||
{
|
{
|
||||||
g_wiimote_scanner.StopScanning();
|
if (!SConfig::GetInstance().m_WiimoteContinuousScanning)
|
||||||
|
g_wiimote_scanner.SetScanMode(WiimoteScanMode::SCAN_ONCE);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleFoundWiimotes(found_wiimotes);
|
|
||||||
if (found_board)
|
|
||||||
TryToConnectBalanceBoard(found_board);
|
|
||||||
}
|
|
||||||
|
|
||||||
Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
|
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
if (g_wiimotes[_WiimoteNumber])
|
if (g_wiimotes[_WiimoteNumber])
|
||||||
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size);
|
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
|
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
if (g_wiimotes[_WiimoteNumber])
|
if (g_wiimotes[_WiimoteNumber])
|
||||||
g_wiimotes[_WiimoteNumber]->ControlChannel(_channelID, _pData, _Size);
|
g_wiimotes[_WiimoteNumber]->ControlChannel(_channelID, _pData, _Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the Wiimote once
|
// Read the Wiimote once
|
||||||
void Update(int _WiimoteNumber)
|
void Update(int wiimote_number)
|
||||||
{
|
{
|
||||||
// Try to get a lock and return without doing anything if we fail
|
// Try to get a lock and return without doing anything if we fail
|
||||||
// This avoids deadlocks when adding a Wiimote during continuous scan
|
// This avoids blocking the CPU thread
|
||||||
if (!g_refresh_lock.try_lock())
|
if (!g_wiimotes_mutex.try_lock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_wiimotes[_WiimoteNumber])
|
if (g_wiimotes[wiimote_number])
|
||||||
g_wiimotes[_WiimoteNumber]->Update();
|
g_wiimotes[wiimote_number]->Update();
|
||||||
|
|
||||||
// Wiimote::Update() may remove the Wiimote if it was disconnected.
|
// Wiimote::Update() may remove the Wiimote if it was disconnected.
|
||||||
if (!g_wiimotes[_WiimoteNumber])
|
if (!g_wiimotes[wiimote_number])
|
||||||
{
|
{
|
||||||
Host_ConnectWiimote(_WiimoteNumber, false);
|
Host_ConnectWiimote(wiimote_number, false);
|
||||||
}
|
}
|
||||||
g_refresh_lock.unlock();
|
|
||||||
|
g_wiimotes_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectOnInput(int _WiimoteNumber)
|
void ConnectOnInput(int wiimote_number)
|
||||||
{
|
{
|
||||||
// see Update() above
|
if (!g_wiimotes_mutex.try_lock())
|
||||||
if (!g_refresh_lock.try_lock())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_wiimotes[_WiimoteNumber])
|
if (g_wiimotes[wiimote_number])
|
||||||
g_wiimotes[_WiimoteNumber]->ConnectOnInput();
|
g_wiimotes[wiimote_number]->ConnectOnInput();
|
||||||
|
|
||||||
g_refresh_lock.unlock();
|
g_wiimotes_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateChange(EMUSTATE_CHANGE newState)
|
void StateChange(EMUSTATE_CHANGE newState)
|
||||||
{
|
{
|
||||||
// std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
|
||||||
|
|
||||||
// TODO: disable/enable auto reporting, maybe
|
// TODO: disable/enable auto reporting, maybe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
|
#include "Common/Event.h"
|
||||||
#include "Common/FifoQueue.h"
|
#include "Common/FifoQueue.h"
|
||||||
|
#include "Common/Flag.h"
|
||||||
#include "Common/NonCopyable.h"
|
#include "Common/NonCopyable.h"
|
||||||
#include "Core/HW/Wiimote.h"
|
#include "Core/HW/Wiimote.h"
|
||||||
#include "Core/HW/WiimoteReal/WiimoteRealBase.h"
|
#include "Core/HW/WiimoteReal/WiimoteRealBase.h"
|
||||||
@ -112,6 +114,13 @@ private:
|
|||||||
Common::FifoQueue<Report> m_write_reports;
|
Common::FifoQueue<Report> m_write_reports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class WiimoteScanMode
|
||||||
|
{
|
||||||
|
DO_NOT_SCAN,
|
||||||
|
CONTINUOUSLY_SCAN,
|
||||||
|
SCAN_ONCE
|
||||||
|
};
|
||||||
|
|
||||||
class WiimoteScanner
|
class WiimoteScanner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -120,11 +129,9 @@ public:
|
|||||||
|
|
||||||
bool IsReady() const;
|
bool IsReady() const;
|
||||||
|
|
||||||
void WantWiimotes(bool do_want);
|
void StartThread();
|
||||||
void WantBB(bool do_want);
|
void StopThread();
|
||||||
|
void SetScanMode(WiimoteScanMode scan_mode);
|
||||||
void StartScanning();
|
|
||||||
void StopScanning();
|
|
||||||
|
|
||||||
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&);
|
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&);
|
||||||
|
|
||||||
@ -136,9 +143,9 @@ private:
|
|||||||
|
|
||||||
std::thread m_scan_thread;
|
std::thread m_scan_thread;
|
||||||
|
|
||||||
std::atomic<bool> m_run_thread{false};
|
Common::Event m_scan_mode_changed_event;
|
||||||
std::atomic<bool> m_want_wiimotes{false};
|
Common::Flag m_scan_thread_running;
|
||||||
std::atomic<bool> m_want_bb{false};
|
std::atomic<WiimoteScanMode> m_scan_mode{WiimoteScanMode::DO_NOT_SCAN};
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
void CheckDeviceType(std::basic_string<TCHAR>& devicepath, WinWriteMethod& write_method,
|
void CheckDeviceType(std::basic_string<TCHAR>& devicepath, WinWriteMethod& write_method,
|
||||||
@ -149,7 +156,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::recursive_mutex g_refresh_lock;
|
extern std::mutex g_wiimotes_mutex;
|
||||||
extern WiimoteScanner g_wiimote_scanner;
|
extern WiimoteScanner g_wiimote_scanner;
|
||||||
extern Wiimote* g_wiimotes[MAX_BBMOTES];
|
extern Wiimote* g_wiimotes[MAX_BBMOTES];
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ private:
|
|||||||
void OnContinuousScanning(wxCommandEvent& event)
|
void OnContinuousScanning(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_WiimoteContinuousScanning = event.IsChecked();
|
SConfig::GetInstance().m_WiimoteContinuousScanning = event.IsChecked();
|
||||||
WiimoteReal::Initialize();
|
WiimoteReal::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,12 +348,14 @@ bool CFrame::InitControllers()
|
|||||||
Window win = X11Utils::XWindowFromHandle(GetHandle());
|
Window win = X11Utils::XWindowFromHandle(GetHandle());
|
||||||
Pad::Initialize(reinterpret_cast<void*>(win));
|
Pad::Initialize(reinterpret_cast<void*>(win));
|
||||||
Keyboard::Initialize(reinterpret_cast<void*>(win));
|
Keyboard::Initialize(reinterpret_cast<void*>(win));
|
||||||
Wiimote::Initialize(reinterpret_cast<void*>(win));
|
Wiimote::Initialize(reinterpret_cast<void*>(win),
|
||||||
|
Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
|
||||||
HotkeyManagerEmu::Initialize(reinterpret_cast<void*>(win));
|
HotkeyManagerEmu::Initialize(reinterpret_cast<void*>(win));
|
||||||
#else
|
#else
|
||||||
Pad::Initialize(reinterpret_cast<void*>(GetHandle()));
|
Pad::Initialize(reinterpret_cast<void*>(GetHandle()));
|
||||||
Keyboard::Initialize(reinterpret_cast<void*>(GetHandle()));
|
Keyboard::Initialize(reinterpret_cast<void*>(GetHandle()));
|
||||||
Wiimote::Initialize(reinterpret_cast<void*>(GetHandle()));
|
Wiimote::Initialize(reinterpret_cast<void*>(GetHandle()),
|
||||||
|
Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
|
||||||
HotkeyManagerEmu::Initialize(reinterpret_cast<void*>(GetHandle()));
|
HotkeyManagerEmu::Initialize(reinterpret_cast<void*>(GetHandle()));
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user