mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-14 00:09:24 +01:00
Added a callback option instead of using a thread to read the GC adapter.
This commit is contained in:
parent
8e9ff68352
commit
519970c003
@ -343,6 +343,7 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
|||||||
core->Set("GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend);
|
core->Set("GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend);
|
||||||
core->Set("GPUDeterminismMode", m_LocalCoreStartupParameter.m_strGPUDeterminismMode);
|
core->Set("GPUDeterminismMode", m_LocalCoreStartupParameter.m_strGPUDeterminismMode);
|
||||||
core->Set("GameCubeAdapter", m_GameCubeAdapter);
|
core->Set("GameCubeAdapter", m_GameCubeAdapter);
|
||||||
|
core->Set("GameCubeAdapterThread", m_GameCubeAdapterThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConfig::SaveMovieSettings(IniFile& ini)
|
void SConfig::SaveMovieSettings(IniFile& ini)
|
||||||
@ -578,6 +579,7 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
|||||||
core->Get("GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, "");
|
core->Get("GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, "");
|
||||||
core->Get("GPUDeterminismMode", &m_LocalCoreStartupParameter.m_strGPUDeterminismMode, "auto");
|
core->Get("GPUDeterminismMode", &m_LocalCoreStartupParameter.m_strGPUDeterminismMode, "auto");
|
||||||
core->Get("GameCubeAdapter", &m_GameCubeAdapter, true);
|
core->Get("GameCubeAdapter", &m_GameCubeAdapter, true);
|
||||||
|
core->Get("GameCubeAdapterThread", &m_GameCubeAdapterThread, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SConfig::LoadMovieSettings(IniFile& ini)
|
void SConfig::LoadMovieSettings(IniFile& ini)
|
||||||
|
@ -108,6 +108,7 @@ struct SConfig : NonCopyable
|
|||||||
// Input settings
|
// Input settings
|
||||||
bool m_BackgroundInput;
|
bool m_BackgroundInput;
|
||||||
bool m_GameCubeAdapter;
|
bool m_GameCubeAdapter;
|
||||||
|
bool m_GameCubeAdapterThread;
|
||||||
|
|
||||||
SysConf* m_SYSCONF;
|
SysConf* m_SYSCONF;
|
||||||
|
|
||||||
|
@ -21,11 +21,15 @@ enum ControllerTypes
|
|||||||
|
|
||||||
static bool s_detected = false;
|
static bool s_detected = false;
|
||||||
static libusb_device_handle* s_handle = nullptr;
|
static libusb_device_handle* s_handle = nullptr;
|
||||||
|
static libusb_transfer* s_irq_transfer_read = nullptr;
|
||||||
|
static libusb_transfer* s_irq_transfer_write = nullptr;
|
||||||
static u8 s_controller_type[MAX_SI_CHANNELS] = { CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE };
|
static u8 s_controller_type[MAX_SI_CHANNELS] = { CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE };
|
||||||
static u8 s_controller_rumble[4];
|
static u8 s_controller_rumble[4];
|
||||||
|
|
||||||
static std::mutex s_mutex;
|
static std::mutex s_mutex;
|
||||||
static u8 s_controller_payload[37];
|
static u8 s_controller_payload[37];
|
||||||
|
static u8 s_controller_payload_swap[37];
|
||||||
|
|
||||||
static int s_controller_payload_size = 0;
|
static int s_controller_payload_size = 0;
|
||||||
|
|
||||||
static std::thread s_adapter_thread;
|
static std::thread s_adapter_thread;
|
||||||
@ -39,17 +43,34 @@ static u8 s_endpoint_out = 0;
|
|||||||
|
|
||||||
static u64 s_last_init = 0;
|
static u64 s_last_init = 0;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define LIBUSB_CALL WINAPI
|
||||||
|
#else
|
||||||
|
#define LIBUSB_CALL
|
||||||
|
#endif
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
void LIBUSB_CALL read_callback(libusb_transfer* transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleEvents()
|
||||||
|
{
|
||||||
|
while (s_adapter_thread_running.IsSet())
|
||||||
|
{
|
||||||
|
libusb_handle_events(NULL);
|
||||||
|
Common::YieldCPU();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void Read()
|
static void Read()
|
||||||
{
|
{
|
||||||
while (s_adapter_thread_running.IsSet())
|
while (s_adapter_thread_running.IsSet())
|
||||||
{
|
{
|
||||||
u8 controller_payload_swap[37];
|
libusb_interrupt_transfer(s_handle, s_endpoint_in, s_controller_payload_swap, sizeof(s_controller_payload_swap), &s_controller_payload_size, 16);
|
||||||
|
|
||||||
libusb_interrupt_transfer(s_handle, s_endpoint_in, controller_payload_swap, sizeof(controller_payload_swap), &s_controller_payload_size, 0);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_mutex);
|
std::lock_guard<std::mutex> lk(s_mutex);
|
||||||
std::swap(controller_payload_swap, s_controller_payload);
|
std::swap(s_controller_payload_swap, s_controller_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
@ -177,10 +198,24 @@ void Init()
|
|||||||
|
|
||||||
int tmp = 0;
|
int tmp = 0;
|
||||||
unsigned char payload = 0x13;
|
unsigned char payload = 0x13;
|
||||||
libusb_interrupt_transfer(s_handle, s_endpoint_out, &payload, sizeof(payload), &tmp, 0);
|
libusb_interrupt_transfer(s_handle, s_endpoint_out, &payload, sizeof(payload), &tmp, 16);
|
||||||
|
|
||||||
|
if (SConfig::GetInstance().m_GameCubeAdapterThread)
|
||||||
|
{
|
||||||
|
s_adapter_thread_running.Set(true);
|
||||||
|
s_adapter_thread = std::thread(Read);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_irq_transfer_read = libusb_alloc_transfer(0);
|
||||||
|
s_irq_transfer_write = libusb_alloc_transfer(0);
|
||||||
|
libusb_fill_interrupt_transfer(s_irq_transfer_read, s_handle, s_endpoint_in, s_controller_payload_swap, sizeof(s_controller_payload_swap), read_callback, NULL, 16);
|
||||||
|
libusb_submit_transfer(s_irq_transfer_read);
|
||||||
|
|
||||||
|
s_adapter_thread_running.Set(true);
|
||||||
|
s_adapter_thread = std::thread(HandleEvents);
|
||||||
|
}
|
||||||
|
|
||||||
s_adapter_thread_running.Set(true);
|
|
||||||
s_adapter_thread = std::thread(Read);
|
|
||||||
s_detected = true;
|
s_detected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,8 +235,16 @@ void Shutdown()
|
|||||||
s_adapter_thread.join();
|
s_adapter_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SConfig::GetInstance().m_GameCubeAdapterThread)
|
||||||
|
{
|
||||||
|
libusb_free_transfer(s_irq_transfer_read);
|
||||||
|
libusb_free_transfer(s_irq_transfer_write);
|
||||||
|
}
|
||||||
|
|
||||||
if (s_handle)
|
if (s_handle)
|
||||||
{
|
{
|
||||||
|
libusb_release_interface(s_handle, 0);
|
||||||
|
libusb_reset_device(s_handle);
|
||||||
libusb_close(s_handle);
|
libusb_close(s_handle);
|
||||||
s_handle = nullptr;
|
s_handle = nullptr;
|
||||||
}
|
}
|
||||||
@ -293,12 +336,20 @@ void Output(int chan, u8 rumble_command)
|
|||||||
|
|
||||||
unsigned char rumble[5] = { 0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3] };
|
unsigned char rumble[5] = { 0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3] };
|
||||||
int size = 0;
|
int size = 0;
|
||||||
libusb_interrupt_transfer(s_handle, s_endpoint_out, rumble, sizeof(rumble), &size, 0);
|
|
||||||
|
|
||||||
if (size != 0x05)
|
if (SConfig::GetInstance().m_GameCubeAdapterThread)
|
||||||
{
|
{
|
||||||
INFO_LOG(SERIALINTERFACE, "error writing rumble (size: %d)", size);
|
libusb_interrupt_transfer(s_handle, s_endpoint_out, rumble, sizeof(rumble), &size, 16);
|
||||||
Shutdown();
|
if (size != 0x05)
|
||||||
|
{
|
||||||
|
INFO_LOG(SERIALINTERFACE, "error writing rumble (size: %d)", size);
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
libusb_fill_interrupt_transfer(s_irq_transfer_write, s_handle, s_endpoint_out, rumble, sizeof(rumble), NULL, &size, 16);
|
||||||
|
libusb_submit_transfer(s_irq_transfer_write);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,4 +364,17 @@ bool IsDriverDetected()
|
|||||||
return !s_libusb_driver_not_supported;
|
return !s_libusb_driver_not_supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LIBUSB_CALL read_callback(libusb_transfer *transfer)
|
||||||
|
{
|
||||||
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(s_mutex);
|
||||||
|
s_controller_payload_size = transfer->actual_length;
|
||||||
|
memcpy(s_controller_payload, s_controller_payload_swap, s_controller_payload_size);
|
||||||
|
}
|
||||||
|
libusb_submit_transfer(s_irq_transfer_read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace SI_GCAdapter
|
} // end of namespace SI_GCAdapter
|
||||||
|
@ -146,7 +146,11 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
|
|||||||
wxCheckBox* const gamecube_adapter = new wxCheckBox(this, wxID_ANY, _("Direct Connect"));
|
wxCheckBox* const gamecube_adapter = new wxCheckBox(this, wxID_ANY, _("Direct Connect"));
|
||||||
gamecube_adapter->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnGameCubeAdapter, this);
|
gamecube_adapter->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnGameCubeAdapter, this);
|
||||||
|
|
||||||
|
wxCheckBox* const gamecube_adapter_thread = new wxCheckBox(this, wxID_ANY, _("Use Thread"));
|
||||||
|
gamecube_adapter_thread->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnGameCubeAdapterThread, this);
|
||||||
|
|
||||||
gamecube_adapter_sizer->Add(gamecube_adapter, 0, wxEXPAND);
|
gamecube_adapter_sizer->Add(gamecube_adapter, 0, wxEXPAND);
|
||||||
|
gamecube_adapter_sizer->Add(gamecube_adapter_thread, 0, wxEXPAND);
|
||||||
gamecube_adapter_group->Add(gamecube_adapter_sizer, 0, wxEXPAND);
|
gamecube_adapter_group->Add(gamecube_adapter_sizer, 0, wxEXPAND);
|
||||||
gamecube_static_sizer->Add(gamecube_adapter_group, 0, wxEXPAND);
|
gamecube_static_sizer->Add(gamecube_adapter_group, 0, wxEXPAND);
|
||||||
|
|
||||||
@ -159,12 +163,18 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
|
|||||||
gamecube_adapter->SetLabelText(_("Adapter Not Detected"));
|
gamecube_adapter->SetLabelText(_("Adapter Not Detected"));
|
||||||
gamecube_adapter->SetValue(false);
|
gamecube_adapter->SetValue(false);
|
||||||
gamecube_adapter->Disable();
|
gamecube_adapter->Disable();
|
||||||
|
gamecube_adapter_thread->SetValue(false);
|
||||||
|
gamecube_adapter_thread->Disable();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gamecube_adapter->SetValue(SConfig::GetInstance().m_GameCubeAdapter);
|
gamecube_adapter->SetValue(SConfig::GetInstance().m_GameCubeAdapter);
|
||||||
|
gamecube_adapter_thread->SetValue(SConfig::GetInstance().m_GameCubeAdapterThread);
|
||||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||||
|
{
|
||||||
gamecube_adapter->Disable();
|
gamecube_adapter->Disable();
|
||||||
|
gamecube_adapter_thread->Disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -64,6 +64,11 @@ public:
|
|||||||
SConfig::GetInstance().m_GameCubeAdapter = event.IsChecked();
|
SConfig::GetInstance().m_GameCubeAdapter = event.IsChecked();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
void OnGameCubeAdapterThread(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
SConfig::GetInstance().m_GameCubeAdapterThread = event.IsChecked();
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxStaticBoxSizer* CreateGamecubeSizer();
|
wxStaticBoxSizer* CreateGamecubeSizer();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user