Merge pull request #8548 from jordan-woyak/wiimote-source-cleanup
Core/WiimoteReal: Wii remote connection pool and source change cleanup.
This commit is contained in:
commit
5dfc9196ab
|
@ -98,7 +98,7 @@ private:
|
||||||
std::string strBackend;
|
std::string strBackend;
|
||||||
std::string sBackend;
|
std::string sBackend;
|
||||||
std::string m_strGPUDeterminismMode;
|
std::string m_strGPUDeterminismMode;
|
||||||
std::array<int, MAX_BBMOTES> iWiimoteSource;
|
std::array<WiimoteSource, MAX_BBMOTES> iWiimoteSource;
|
||||||
std::array<SerialInterface::SIDevices, SerialInterface::MAX_SI_CHANNELS> Pads;
|
std::array<SerialInterface::SIDevices, SerialInterface::MAX_SI_CHANNELS> Pads;
|
||||||
std::array<ExpansionInterface::TEXIDevices, ExpansionInterface::MAX_EXI_CHANNELS> m_EXIDevice;
|
std::array<ExpansionInterface::TEXIDevices, ExpansionInterface::MAX_EXI_CHANNELS> m_EXIDevice;
|
||||||
};
|
};
|
||||||
|
@ -133,7 +133,9 @@ void ConfigCache::SaveConfig(const SConfig& config)
|
||||||
m_OCEnable = config.m_OCEnable;
|
m_OCEnable = config.m_OCEnable;
|
||||||
m_bt_passthrough_enabled = config.m_bt_passthrough_enabled;
|
m_bt_passthrough_enabled = config.m_bt_passthrough_enabled;
|
||||||
|
|
||||||
std::copy(std::begin(g_wiimote_sources), std::end(g_wiimote_sources), std::begin(iWiimoteSource));
|
for (int i = 0; i != MAX_BBMOTES; ++i)
|
||||||
|
iWiimoteSource[i] = WiimoteCommon::GetSource(i);
|
||||||
|
|
||||||
std::copy(std::begin(config.m_SIDevice), std::end(config.m_SIDevice), std::begin(Pads));
|
std::copy(std::begin(config.m_SIDevice), std::end(config.m_SIDevice), std::begin(Pads));
|
||||||
std::copy(std::begin(config.m_EXIDevice), std::end(config.m_EXIDevice), std::begin(m_EXIDevice));
|
std::copy(std::begin(config.m_EXIDevice), std::end(config.m_EXIDevice), std::begin(m_EXIDevice));
|
||||||
|
|
||||||
|
@ -180,10 +182,7 @@ void ConfigCache::RestoreConfig(SConfig* config)
|
||||||
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
||||||
{
|
{
|
||||||
if (bSetWiimoteSource[i])
|
if (bSetWiimoteSource[i])
|
||||||
{
|
WiimoteCommon::SetSource(i, iWiimoteSource[i]);
|
||||||
g_wiimote_sources[i] = iWiimoteSource[i];
|
|
||||||
WiimoteReal::ChangeWiimoteSource(i, iWiimoteSource[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,21 +303,22 @@ bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
|
||||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
{
|
{
|
||||||
controls_section->Get(fmt::format("WiimoteSource{}", i), &source, -1);
|
controls_section->Get(fmt::format("WiimoteSource{}", i), &source, -1);
|
||||||
if (source != -1 && g_wiimote_sources[i] != (unsigned)source &&
|
if (source != -1 && WiimoteCommon::GetSource(i) != WiimoteSource(source) &&
|
||||||
source >= WIIMOTE_SRC_NONE && source <= WIIMOTE_SRC_REAL)
|
WiimoteSource(source) >= WiimoteSource::None &&
|
||||||
|
WiimoteSource(source) <= WiimoteSource::Real)
|
||||||
{
|
{
|
||||||
config_cache.bSetWiimoteSource[i] = true;
|
config_cache.bSetWiimoteSource[i] = true;
|
||||||
g_wiimote_sources[i] = source;
|
WiimoteCommon::SetSource(i, WiimoteSource(source));
|
||||||
WiimoteReal::ChangeWiimoteSource(i, source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controls_section->Get("WiimoteSourceBB", &source, -1);
|
controls_section->Get("WiimoteSourceBB", &source, -1);
|
||||||
if (source != -1 && g_wiimote_sources[WIIMOTE_BALANCE_BOARD] != (unsigned)source &&
|
if (source != -1 &&
|
||||||
(source == WIIMOTE_SRC_NONE || source == WIIMOTE_SRC_REAL))
|
WiimoteCommon::GetSource(WIIMOTE_BALANCE_BOARD) != WiimoteSource(source) &&
|
||||||
|
(WiimoteSource(source) == WiimoteSource::None ||
|
||||||
|
WiimoteSource(source) == WiimoteSource::Real))
|
||||||
{
|
{
|
||||||
config_cache.bSetWiimoteSource[WIIMOTE_BALANCE_BOARD] = true;
|
config_cache.bSetWiimoteSource[WIIMOTE_BALANCE_BOARD] = true;
|
||||||
g_wiimote_sources[WIIMOTE_BALANCE_BOARD] = source;
|
WiimoteCommon::SetSource(WIIMOTE_BALANCE_BOARD, WiimoteSource(source));
|
||||||
WiimoteReal::ChangeWiimoteSource(WIIMOTE_BALANCE_BOARD, source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,38 @@
|
||||||
// Limit the amount of wiimote connect requests, when a button is pressed in disconnected state
|
// Limit the amount of wiimote connect requests, when a button is pressed in disconnected state
|
||||||
static std::array<u8, MAX_BBMOTES> s_last_connect_request_counter;
|
static std::array<u8, MAX_BBMOTES> s_last_connect_request_counter;
|
||||||
|
|
||||||
|
namespace WiimoteCommon
|
||||||
|
{
|
||||||
|
static std::array<std::atomic<WiimoteSource>, MAX_BBMOTES> s_wiimote_sources;
|
||||||
|
|
||||||
|
WiimoteSource GetSource(unsigned int index)
|
||||||
|
{
|
||||||
|
return s_wiimote_sources[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSource(unsigned int index, WiimoteSource source)
|
||||||
|
{
|
||||||
|
const WiimoteSource previous_source = s_wiimote_sources[index].exchange(source);
|
||||||
|
|
||||||
|
if (previous_source == source)
|
||||||
|
{
|
||||||
|
// No change. Do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiimoteReal::HandleWiimoteSourceChange(index);
|
||||||
|
|
||||||
|
// Reconnect to the emulator.
|
||||||
|
Core::RunAsCPUThread([index, previous_source, source] {
|
||||||
|
if (previous_source != WiimoteSource::None)
|
||||||
|
::Wiimote::Connect(index, false);
|
||||||
|
|
||||||
|
if (source == WiimoteSource::Emulated)
|
||||||
|
::Wiimote::Connect(index, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} // namespace WiimoteCommon
|
||||||
|
|
||||||
namespace Wiimote
|
namespace Wiimote
|
||||||
{
|
{
|
||||||
static InputConfig s_config(WIIMOTE_INI_NAME, _trans("Wii Remote"), "Wiimote");
|
static InputConfig s_config(WIIMOTE_INI_NAME, _trans("Wii Remote"), "Wiimote");
|
||||||
|
@ -155,7 +187,7 @@ void Pause()
|
||||||
// An L2CAP packet is passed from the Core to the Wiimote on the HID CONTROL channel.
|
// An L2CAP packet is passed from the Core to the Wiimote on the HID CONTROL channel.
|
||||||
void ControlChannel(int number, u16 channel_id, const void* data, u32 size)
|
void ControlChannel(int number, u16 channel_id, const void* data, u32 size)
|
||||||
{
|
{
|
||||||
if (WIIMOTE_SRC_EMU == g_wiimote_sources[number])
|
if (WiimoteCommon::GetSource(number) == WiimoteSource::Emulated)
|
||||||
{
|
{
|
||||||
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
||||||
->ControlChannel(channel_id, data, size);
|
->ControlChannel(channel_id, data, size);
|
||||||
|
@ -169,7 +201,7 @@ void ControlChannel(int number, u16 channel_id, const void* data, u32 size)
|
||||||
// An L2CAP packet is passed from the Core to the Wiimote on the HID INTERRUPT channel.
|
// An L2CAP packet is passed from the Core to the Wiimote on the HID INTERRUPT channel.
|
||||||
void InterruptChannel(int number, u16 channel_id, const void* data, u32 size)
|
void InterruptChannel(int number, u16 channel_id, const void* data, u32 size)
|
||||||
{
|
{
|
||||||
if (WIIMOTE_SRC_EMU == g_wiimote_sources[number])
|
if (WiimoteCommon::GetSource(number) == WiimoteSource::Emulated)
|
||||||
{
|
{
|
||||||
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))
|
||||||
->InterruptChannel(channel_id, data, size);
|
->InterruptChannel(channel_id, data, size);
|
||||||
|
@ -182,24 +214,26 @@ void InterruptChannel(int number, u16 channel_id, const void* data, u32 size)
|
||||||
|
|
||||||
bool ButtonPressed(int number)
|
bool ButtonPressed(int number)
|
||||||
{
|
{
|
||||||
|
const WiimoteSource source = WiimoteCommon::GetSource(number);
|
||||||
|
|
||||||
if (s_last_connect_request_counter[number] > 0)
|
if (s_last_connect_request_counter[number] > 0)
|
||||||
{
|
{
|
||||||
--s_last_connect_request_counter[number];
|
--s_last_connect_request_counter[number];
|
||||||
if (g_wiimote_sources[number] && NetPlay::IsNetPlayRunning())
|
if (source != WiimoteSource::None && NetPlay::IsNetPlayRunning())
|
||||||
Wiimote::NetPlay_GetButtonPress(number, false);
|
Wiimote::NetPlay_GetButtonPress(number, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool button_pressed = false;
|
bool button_pressed = false;
|
||||||
|
|
||||||
if (WIIMOTE_SRC_EMU & g_wiimote_sources[number])
|
if (source == WiimoteSource::Emulated)
|
||||||
button_pressed =
|
button_pressed =
|
||||||
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->CheckForButtonPress();
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->CheckForButtonPress();
|
||||||
|
|
||||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[number])
|
if (source == WiimoteSource::Real)
|
||||||
button_pressed = WiimoteReal::CheckForButtonPress(number);
|
button_pressed = WiimoteReal::CheckForButtonPress(number);
|
||||||
|
|
||||||
if (g_wiimote_sources[number] && NetPlay::IsNetPlayRunning())
|
if (source != WiimoteSource::None && NetPlay::IsNetPlayRunning())
|
||||||
button_pressed = Wiimote::NetPlay_GetButtonPress(number, button_pressed);
|
button_pressed = Wiimote::NetPlay_GetButtonPress(number, button_pressed);
|
||||||
|
|
||||||
return button_pressed;
|
return button_pressed;
|
||||||
|
@ -210,7 +244,7 @@ void Update(int number, bool connected)
|
||||||
{
|
{
|
||||||
if (connected)
|
if (connected)
|
||||||
{
|
{
|
||||||
if (WIIMOTE_SRC_EMU & g_wiimote_sources[number])
|
if (WiimoteCommon::GetSource(number) == WiimoteSource::Emulated)
|
||||||
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->Update();
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(number))->Update();
|
||||||
else
|
else
|
||||||
WiimoteReal::Update(number);
|
WiimoteReal::Update(number);
|
||||||
|
@ -227,25 +261,16 @@ void Update(int number, bool connected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a mask of attached the pads (eg: controller 1 & 4 -> 0x9)
|
|
||||||
unsigned int GetAttached()
|
|
||||||
{
|
|
||||||
unsigned int attached = 0;
|
|
||||||
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
|
||||||
if (g_wiimote_sources[i])
|
|
||||||
attached |= (1 << i);
|
|
||||||
return attached;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save/Load state
|
// Save/Load state
|
||||||
void DoState(PointerWrap& p)
|
void DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_BBMOTES; ++i)
|
for (int i = 0; i < MAX_BBMOTES; ++i)
|
||||||
{
|
{
|
||||||
auto state_wiimote_source = u8(g_wiimote_sources[i]);
|
const WiimoteSource source = WiimoteCommon::GetSource(i);
|
||||||
|
auto state_wiimote_source = u8(source);
|
||||||
p.Do(state_wiimote_source);
|
p.Do(state_wiimote_source);
|
||||||
|
|
||||||
if (WIIMOTE_SRC_EMU == state_wiimote_source)
|
if (WiimoteSource(state_wiimote_source) == WiimoteSource::Emulated)
|
||||||
{
|
{
|
||||||
// Sync complete state of emulated wiimotes.
|
// Sync complete state of emulated wiimotes.
|
||||||
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(i))->DoState(p);
|
static_cast<WiimoteEmu::Wiimote*>(s_config.GetController(i))->DoState(p);
|
||||||
|
@ -255,7 +280,7 @@ void DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
// If using a real wiimote or the save-state source does not match the current source,
|
// If using a real wiimote or the save-state source does not match the current source,
|
||||||
// then force a reconnection on load.
|
// then force a reconnection on load.
|
||||||
if (WIIMOTE_SRC_REAL == g_wiimote_sources[i] || state_wiimote_source != g_wiimote_sources[i])
|
if (source == WiimoteSource::Real || source != WiimoteSource(state_wiimote_source))
|
||||||
{
|
{
|
||||||
Connect(i, false);
|
Connect(i, false);
|
||||||
Connect(i, true);
|
Connect(i, true);
|
||||||
|
|
|
@ -44,14 +44,18 @@ enum
|
||||||
|
|
||||||
#define WIIMOTE_INI_NAME "WiimoteNew"
|
#define WIIMOTE_INI_NAME "WiimoteNew"
|
||||||
|
|
||||||
enum
|
enum class WiimoteSource
|
||||||
{
|
{
|
||||||
WIIMOTE_SRC_NONE = 0,
|
None = 0,
|
||||||
WIIMOTE_SRC_EMU = 1,
|
Emulated = 1,
|
||||||
WIIMOTE_SRC_REAL = 2,
|
Real = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::array<std::atomic<u32>, MAX_BBMOTES> g_wiimote_sources;
|
namespace WiimoteCommon
|
||||||
|
{
|
||||||
|
WiimoteSource GetSource(unsigned int index);
|
||||||
|
void SetSource(unsigned int index, WiimoteSource source);
|
||||||
|
} // namespace WiimoteCommon
|
||||||
|
|
||||||
namespace Wiimote
|
namespace Wiimote
|
||||||
{
|
{
|
||||||
|
@ -74,7 +78,6 @@ void LoadConfig();
|
||||||
void Resume();
|
void Resume();
|
||||||
void Pause();
|
void Pause();
|
||||||
|
|
||||||
unsigned int GetAttached();
|
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
InputConfig* GetConfig();
|
InputConfig* GetConfig();
|
||||||
ControllerEmu::ControlGroup* GetWiimoteGroup(int number, WiimoteEmu::WiimoteGroup group);
|
ControllerEmu::ControlGroup* GetWiimoteGroup(int number, WiimoteEmu::WiimoteGroup group);
|
||||||
|
@ -105,4 +108,5 @@ void Pause();
|
||||||
void Refresh();
|
void Refresh();
|
||||||
|
|
||||||
void LoadSettings();
|
void LoadSettings();
|
||||||
|
|
||||||
} // namespace WiimoteReal
|
} // namespace WiimoteReal
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
#include "SFML/Network.hpp"
|
#include "SFML/Network.hpp"
|
||||||
|
|
||||||
std::array<std::atomic<u32>, MAX_BBMOTES> g_wiimote_sources;
|
|
||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
{
|
{
|
||||||
using namespace WiimoteCommon;
|
using namespace WiimoteCommon;
|
||||||
|
@ -49,9 +47,49 @@ static std::mutex s_known_ids_mutex;
|
||||||
|
|
||||||
std::mutex g_wiimotes_mutex;
|
std::mutex g_wiimotes_mutex;
|
||||||
|
|
||||||
|
// Real wii remotes assigned to a particular slot.
|
||||||
std::unique_ptr<Wiimote> g_wiimotes[MAX_BBMOTES];
|
std::unique_ptr<Wiimote> g_wiimotes[MAX_BBMOTES];
|
||||||
|
|
||||||
|
struct WiimotePoolEntry
|
||||||
|
{
|
||||||
|
using Clock = std::chrono::steady_clock;
|
||||||
|
|
||||||
|
std::unique_ptr<Wiimote> wiimote;
|
||||||
|
Clock::time_point entry_time = Clock::now();
|
||||||
|
|
||||||
|
bool IsExpired() const
|
||||||
|
{
|
||||||
|
// Keep wii remotes in the pool for a bit before disconnecting them.
|
||||||
|
constexpr auto POOL_TIME = std::chrono::seconds{5};
|
||||||
|
|
||||||
|
return (Clock::now() - entry_time) > POOL_TIME;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Connected wii remotes are placed here when no open slot is set to "Real".
|
||||||
|
// They are then automatically disconnected after some time.
|
||||||
|
std::vector<WiimotePoolEntry> g_wiimote_pool;
|
||||||
|
|
||||||
WiimoteScanner g_wiimote_scanner;
|
WiimoteScanner g_wiimote_scanner;
|
||||||
|
|
||||||
|
static void ProcessWiimotePool()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> wm_lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
|
for (auto it = g_wiimote_pool.begin(); it != g_wiimote_pool.end();)
|
||||||
|
{
|
||||||
|
if (it->IsExpired())
|
||||||
|
{
|
||||||
|
INFO_LOG(WIIMOTE, "Removing expired wiimote pool entry.");
|
||||||
|
it = g_wiimote_pool.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Wiimote::Wiimote() = default;
|
Wiimote::Wiimote() = default;
|
||||||
|
|
||||||
void Wiimote::Shutdown()
|
void Wiimote::Shutdown()
|
||||||
|
@ -478,7 +516,7 @@ static unsigned int CalculateWantedWiimotes()
|
||||||
// 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)
|
||||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i])
|
if (WiimoteCommon::GetSource(i) == WiimoteSource::Real && !g_wiimotes[i])
|
||||||
++wanted_wiimotes;
|
++wanted_wiimotes;
|
||||||
|
|
||||||
return wanted_wiimotes;
|
return wanted_wiimotes;
|
||||||
|
@ -488,7 +526,7 @@ static unsigned int CalculateWantedBB()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
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 (WiimoteCommon::GetSource(WIIMOTE_BALANCE_BOARD) == WiimoteSource::Real &&
|
||||||
!g_wiimotes[WIIMOTE_BALANCE_BOARD])
|
!g_wiimotes[WIIMOTE_BALANCE_BOARD])
|
||||||
++wanted_bb;
|
++wanted_bb;
|
||||||
return wanted_bb;
|
return wanted_bb;
|
||||||
|
@ -556,6 +594,8 @@ void WiimoteScanner::ThreadFunc()
|
||||||
{
|
{
|
||||||
m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500));
|
m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500));
|
||||||
|
|
||||||
|
ProcessWiimotePool();
|
||||||
|
|
||||||
CheckForDisconnectedWiimotes();
|
CheckForDisconnectedWiimotes();
|
||||||
|
|
||||||
if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN)
|
if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN)
|
||||||
|
@ -619,9 +659,15 @@ bool Wiimote::Connect(int index)
|
||||||
|
|
||||||
if (!m_run_thread.IsSet())
|
if (!m_run_thread.IsSet())
|
||||||
{
|
{
|
||||||
|
m_run_thread.Set();
|
||||||
StartThread();
|
StartThread();
|
||||||
m_thread_ready_event.Wait();
|
m_thread_ready_event.Wait();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IOWakeup();
|
||||||
|
}
|
||||||
|
|
||||||
return IsConnected();
|
return IsConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,7 +698,6 @@ void Wiimote::ThreadFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
m_thread_ready_event.Set();
|
m_thread_ready_event.Set();
|
||||||
m_run_thread.Set();
|
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
|
@ -698,16 +743,16 @@ void LoadSettings()
|
||||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
||||||
|
|
||||||
unsigned int source = 0;
|
unsigned int source = 0;
|
||||||
sec.Get("Source", &source, i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU);
|
sec.Get("Source", &source, i ? int(WiimoteSource::None) : int(WiimoteSource::Emulated));
|
||||||
g_wiimote_sources[i] = source;
|
WiimoteCommon::SetSource(i, WiimoteSource(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string secname("BalanceBoard");
|
std::string secname("BalanceBoard");
|
||||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
||||||
|
|
||||||
unsigned int bb_source = 0;
|
unsigned int bb_source = 0;
|
||||||
sec.Get("Source", &bb_source, WIIMOTE_SRC_NONE);
|
sec.Get("Source", &bb_source, int(WiimoteSource::None));
|
||||||
g_wiimote_sources[WIIMOTE_BALANCE_BOARD] = bb_source;
|
WiimoteCommon::SetSource(WIIMOTE_BALANCE_BOARD, WiimoteSource(bb_source));
|
||||||
}
|
}
|
||||||
|
|
||||||
// config dialog calls this when some settings change
|
// config dialog calls this when some settings change
|
||||||
|
@ -779,43 +824,10 @@ void Pause()
|
||||||
wiimote->EmuPause();
|
wiimote->EmuPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChangeWiimoteSource(unsigned int index, int source)
|
|
||||||
{
|
|
||||||
const int previous_source = g_wiimote_sources[index];
|
|
||||||
|
|
||||||
if (previous_source == source)
|
|
||||||
{
|
|
||||||
// No change. Do nothing.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_wiimote_sources[index] = source;
|
|
||||||
|
|
||||||
{
|
|
||||||
// Kill real wiimote connection (if any) (or swap to different slot)
|
|
||||||
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
|
||||||
if (auto removed_wiimote = std::move(g_wiimotes[index]))
|
|
||||||
{
|
|
||||||
// See if we can use this real Wiimote in another slot.
|
|
||||||
// Otherwise it will be disconnected.
|
|
||||||
TryToConnectWiimote(std::move(removed_wiimote));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reconnect to the emulator.
|
|
||||||
Core::RunAsCPUThread([index, previous_source, source] {
|
|
||||||
if (previous_source != WIIMOTE_SRC_NONE)
|
|
||||||
::Wiimote::Connect(index, false);
|
|
||||||
|
|
||||||
if (source == WIIMOTE_SRC_EMU)
|
|
||||||
::Wiimote::Connect(index, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from the Wiimote scanner thread (or UI thread on source change)
|
// Called from the Wiimote scanner thread (or UI thread on source change)
|
||||||
static bool TryToConnectWiimoteToSlot(std::unique_ptr<Wiimote>& wm, unsigned int i)
|
static bool TryToConnectWiimoteToSlot(std::unique_ptr<Wiimote>& wm, unsigned int i)
|
||||||
{
|
{
|
||||||
if (WIIMOTE_SRC_REAL != g_wiimote_sources[i] || g_wiimotes[i])
|
if (WiimoteCommon::GetSource(i) != WiimoteSource::Real || g_wiimotes[i])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!wm->Connect(i))
|
if (!wm->Connect(i))
|
||||||
|
@ -840,7 +852,12 @@ static void TryToConnectWiimote(std::unique_ptr<Wiimote> wm)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NOTICE_LOG(WIIMOTE, "No open slot for real wiimote.");
|
INFO_LOG(WIIMOTE, "No open slot for real wiimote, adding it to the pool.");
|
||||||
|
wm->Connect(0);
|
||||||
|
// Turn on LED 1 and 4 to make it apparant this remote is in the pool.
|
||||||
|
const u8 led_value = u8(LED::LED_1) | u8(LED::LED_4);
|
||||||
|
wm->QueueReport(OutputReportID::LED, &led_value, 1);
|
||||||
|
g_wiimote_pool.emplace_back(WiimotePoolEntry{std::move(wm)});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TryToConnectBalanceBoard(std::unique_ptr<Wiimote> wm)
|
static void TryToConnectBalanceBoard(std::unique_ptr<Wiimote> wm)
|
||||||
|
@ -927,4 +944,27 @@ bool IsNewWiimote(const std::string& identifier)
|
||||||
return s_known_ids.count(identifier) == 0;
|
return s_known_ids.count(identifier) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleWiimoteSourceChange(unsigned int index)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> wm_lk(g_wiimotes_mutex);
|
||||||
|
|
||||||
|
if (WiimoteCommon::GetSource(index) != WiimoteSource::Real)
|
||||||
|
{
|
||||||
|
if (auto removed_wiimote = std::move(g_wiimotes[index]))
|
||||||
|
{
|
||||||
|
removed_wiimote->EmuStop();
|
||||||
|
// Try to use this removed wiimote in another slot.
|
||||||
|
TryToConnectWiimote(std::move(removed_wiimote));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (WiimoteCommon::GetSource(index) == WiimoteSource::Real)
|
||||||
|
{
|
||||||
|
// Try to fill this slot from the pool.
|
||||||
|
if (!g_wiimote_pool.empty())
|
||||||
|
{
|
||||||
|
if (TryToConnectWiimoteToSlot(g_wiimote_pool.front().wiimote, index))
|
||||||
|
g_wiimote_pool.erase(g_wiimote_pool.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}; // namespace WiimoteReal
|
}; // namespace WiimoteReal
|
||||||
|
|
|
@ -192,12 +192,12 @@ void ControlChannel(int wiimote_number, u16 channel_id, const void* data, u32 si
|
||||||
void Update(int wiimote_number);
|
void Update(int wiimote_number);
|
||||||
bool CheckForButtonPress(int wiimote_number);
|
bool CheckForButtonPress(int wiimote_number);
|
||||||
|
|
||||||
void ChangeWiimoteSource(unsigned int index, int source);
|
|
||||||
|
|
||||||
bool IsValidDeviceName(const std::string& name);
|
bool IsValidDeviceName(const std::string& name);
|
||||||
bool IsBalanceBoardName(const std::string& name);
|
bool IsBalanceBoardName(const std::string& name);
|
||||||
bool IsNewWiimote(const std::string& identifier);
|
bool IsNewWiimote(const std::string& identifier);
|
||||||
|
|
||||||
|
void HandleWiimoteSourceChange(unsigned int wiimote_number);
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
void InitAdapterClass();
|
void InitAdapterClass();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -67,7 +67,7 @@ BluetoothEmu::BluetoothEmu(Kernel& ios, const std::string& device_name)
|
||||||
|
|
||||||
DEBUG_LOG(IOS_WIIMOTE, "Wii Remote %d BT ID %x,%x,%x,%x,%x,%x", i, tmp_bd[0], tmp_bd[1],
|
DEBUG_LOG(IOS_WIIMOTE, "Wii Remote %d BT ID %x,%x,%x,%x,%x,%x", i, tmp_bd[0], tmp_bd[1],
|
||||||
tmp_bd[2], tmp_bd[3], tmp_bd[4], tmp_bd[5]);
|
tmp_bd[2], tmp_bd[3], tmp_bd[4], tmp_bd[5]);
|
||||||
m_wiimotes.emplace_back(this, i, tmp_bd, g_wiimote_sources[i] != WIIMOTE_SRC_NONE);
|
m_wiimotes.emplace_back(this, i, tmp_bd, WiimoteCommon::GetSource(i) != WiimoteSource::None);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ std::string GetInputDisplay()
|
||||||
{
|
{
|
||||||
if (SerialInterface::GetDeviceType(i) != SerialInterface::SIDEVICE_NONE)
|
if (SerialInterface::GetDeviceType(i) != SerialInterface::SIDEVICE_NONE)
|
||||||
s_controllers |= (1 << i);
|
s_controllers |= (1 << i);
|
||||||
if (g_wiimote_sources[i] != WIIMOTE_SRC_NONE)
|
if (WiimoteCommon::GetSource(i) != WiimoteSource::None)
|
||||||
s_controllers |= (1 << (i + 4));
|
s_controllers |= (1 << (i + 4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,7 @@ void ChangeWiiPads(bool instantly)
|
||||||
int controllers = 0;
|
int controllers = 0;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_WIIMOTES; ++i)
|
for (int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
if (g_wiimote_sources[i] != WIIMOTE_SRC_NONE)
|
if (WiimoteCommon::GetSource(i) != WiimoteSource::None)
|
||||||
controllers |= (1 << i);
|
controllers |= (1 << i);
|
||||||
|
|
||||||
// This is important for Wiimotes, because they can desync easily if they get re-activated
|
// This is important for Wiimotes, because they can desync easily if they get re-activated
|
||||||
|
@ -478,7 +478,7 @@ void ChangeWiiPads(bool instantly)
|
||||||
{
|
{
|
||||||
const bool is_using_wiimote = IsUsingWiimote(i);
|
const bool is_using_wiimote = IsUsingWiimote(i);
|
||||||
|
|
||||||
g_wiimote_sources[i] = is_using_wiimote ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE;
|
WiimoteCommon::SetSource(i, is_using_wiimote ? WiimoteSource::Emulated : WiimoteSource::None);
|
||||||
if (!SConfig::GetInstance().m_bt_passthrough_enabled && bt)
|
if (!SConfig::GetInstance().m_bt_passthrough_enabled && bt)
|
||||||
bt->AccessWiimoteByIndex(i)->Activate(is_using_wiimote);
|
bt->AccessWiimoteByIndex(i)->Activate(is_using_wiimote);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1510,7 +1510,10 @@ bool NetPlayClient::StartGame(const std::string& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 4; ++i)
|
for (unsigned int i = 0; i < 4; ++i)
|
||||||
WiimoteReal::ChangeWiimoteSource(i, m_wiimote_map[i] > 0 ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE);
|
{
|
||||||
|
WiimoteCommon::SetSource(i,
|
||||||
|
m_wiimote_map[i] > 0 ? WiimoteSource::Emulated : WiimoteSource::None);
|
||||||
|
}
|
||||||
|
|
||||||
// boot game
|
// boot game
|
||||||
m_dialog->BootGame(path);
|
m_dialog->BootGame(path);
|
||||||
|
|
|
@ -489,11 +489,13 @@ void ControllersWindow::LoadSettings()
|
||||||
m_gc_controller_boxes[i]->setCurrentIndex(*gc_index);
|
m_gc_controller_boxes[i]->setCurrentIndex(*gc_index);
|
||||||
m_gc_buttons[i]->setEnabled(*gc_index != 0 && *gc_index != 6);
|
m_gc_buttons[i]->setEnabled(*gc_index != 0 && *gc_index != 6);
|
||||||
}
|
}
|
||||||
m_wiimote_boxes[i]->setCurrentIndex(g_wiimote_sources[i]);
|
|
||||||
m_wiimote_buttons[i]->setEnabled(g_wiimote_sources[i] != 0 && g_wiimote_sources[i] != 2);
|
const WiimoteSource source = WiimoteCommon::GetSource(int(i));
|
||||||
|
m_wiimote_boxes[i]->setCurrentIndex(int(source));
|
||||||
|
m_wiimote_buttons[i]->setEnabled(source == WiimoteSource::Emulated);
|
||||||
}
|
}
|
||||||
m_wiimote_real_balance_board->setChecked(g_wiimote_sources[WIIMOTE_BALANCE_BOARD] ==
|
m_wiimote_real_balance_board->setChecked(WiimoteCommon::GetSource(WIIMOTE_BALANCE_BOARD) ==
|
||||||
WIIMOTE_SRC_REAL);
|
WiimoteSource::Real);
|
||||||
m_wiimote_speaker_data->setChecked(SConfig::GetInstance().m_WiimoteEnableSpeaker);
|
m_wiimote_speaker_data->setChecked(SConfig::GetInstance().m_WiimoteEnableSpeaker);
|
||||||
m_wiimote_continuous_scanning->setChecked(SConfig::GetInstance().m_WiimoteContinuousScanning);
|
m_wiimote_continuous_scanning->setChecked(SConfig::GetInstance().m_WiimoteContinuousScanning);
|
||||||
|
|
||||||
|
@ -514,15 +516,15 @@ void ControllersWindow::SaveSettings()
|
||||||
SConfig::GetInstance().m_bt_passthrough_enabled = m_wiimote_passthrough->isChecked();
|
SConfig::GetInstance().m_bt_passthrough_enabled = m_wiimote_passthrough->isChecked();
|
||||||
SConfig::GetInstance().m_BackgroundInput = m_common_bg_input->isChecked();
|
SConfig::GetInstance().m_BackgroundInput = m_common_bg_input->isChecked();
|
||||||
|
|
||||||
WiimoteReal::ChangeWiimoteSource(WIIMOTE_BALANCE_BOARD,
|
WiimoteCommon::SetSource(WIIMOTE_BALANCE_BOARD, m_wiimote_real_balance_board->isChecked() ?
|
||||||
m_wiimote_real_balance_board->isChecked() ? WIIMOTE_SRC_REAL :
|
WiimoteSource::Real :
|
||||||
WIIMOTE_SRC_NONE);
|
WiimoteSource::None);
|
||||||
|
|
||||||
for (size_t i = 0; i < m_wiimote_groups.size(); i++)
|
for (size_t i = 0; i < m_wiimote_groups.size(); i++)
|
||||||
{
|
{
|
||||||
const int index = m_wiimote_boxes[i]->currentIndex();
|
const auto source = WiimoteSource(m_wiimote_boxes[i]->currentIndex());
|
||||||
m_wiimote_buttons[i]->setEnabled(index != 0 && index != 2);
|
m_wiimote_buttons[i]->setEnabled(source == WiimoteSource::Emulated);
|
||||||
WiimoteReal::ChangeWiimoteSource(static_cast<u32>(i), index);
|
WiimoteCommon::SetSource(static_cast<u32>(i), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
UICommon::SaveWiimoteSources();
|
UICommon::SaveWiimoteSources();
|
||||||
|
|
|
@ -115,6 +115,8 @@
|
||||||
|
|
||||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||||
#include "UICommon/X11Utils.h"
|
#include "UICommon/X11Utils.h"
|
||||||
|
// This #define within X11/X.h conflicts with our WiimoteSource enum.
|
||||||
|
#undef None
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__unix) || defined(__APPLE__)
|
#if defined(__unix__) || defined(__unix) || defined(__APPLE__)
|
||||||
|
@ -1593,7 +1595,7 @@ void MainWindow::OnStartRecording()
|
||||||
if (SerialInterface::SIDevice_IsGCController(SConfig::GetInstance().m_SIDevice[i]))
|
if (SerialInterface::SIDevice_IsGCController(SConfig::GetInstance().m_SIDevice[i]))
|
||||||
controllers |= (1 << i);
|
controllers |= (1 << i);
|
||||||
|
|
||||||
if (g_wiimote_sources[i] != WIIMOTE_SRC_NONE)
|
if (WiimoteCommon::GetSource(i) != WiimoteSource::None)
|
||||||
controllers |= (1 << (i + 4));
|
controllers |= (1 << (i + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1660,7 +1662,7 @@ void MainWindow::ShowTASInput()
|
||||||
|
|
||||||
for (int i = 0; i < num_wii_controllers; i++)
|
for (int i = 0; i < num_wii_controllers; i++)
|
||||||
{
|
{
|
||||||
if (g_wiimote_sources[i] == WIIMOTE_SRC_EMU &&
|
if (WiimoteCommon::GetSource(i) == WiimoteSource::Emulated &&
|
||||||
(!Core::IsRunning() || SConfig::GetInstance().bWii))
|
(!Core::IsRunning() || SConfig::GetInstance().bWii))
|
||||||
{
|
{
|
||||||
m_wii_tas_input_windows[i]->show();
|
m_wii_tas_input_windows[i]->show();
|
||||||
|
|
|
@ -367,12 +367,12 @@ void SaveWiimoteSources()
|
||||||
secname += (char)('1' + i);
|
secname += (char)('1' + i);
|
||||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
||||||
|
|
||||||
sec.Set("Source", (int)g_wiimote_sources[i]);
|
sec.Set("Source", int(WiimoteCommon::GetSource(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string secname("BalanceBoard");
|
std::string secname("BalanceBoard");
|
||||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
|
||||||
sec.Set("Source", (int)g_wiimote_sources[WIIMOTE_BALANCE_BOARD]);
|
sec.Set("Source", int(WiimoteCommon::GetSource(WIIMOTE_BALANCE_BOARD)));
|
||||||
|
|
||||||
inifile.Save(ini_filename);
|
inifile.Save(ini_filename);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue