From 49410576e945ba7bf762b83a474005f1babc5b54 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 31 Dec 2015 11:09:47 -0600 Subject: [PATCH] Make the Wii U Gamecube adapter work with less magic. The Wii U Gamecube controller adapter setup has always been a bit weird. It tries to be as automatic as possible to make the user experience as easy as possible. The problem with this approach is that it brings a large disconnect in the user experience because you have the Gamecube controller setup with regular gamepads and then for some reason below that you have a "direct connect" option which will cause the Gamecube Adapter to overwrite the regular inputs if something was connected. While this works and allows the user to only click one checkbox to get the device working, it breaks the user's experience because they don't really know what "direct connect" means and won't look it up to figure out what it is. Just expecting the device to work (At least one occurence of this in the IRC channel in the last week). This way around also had the terrible nature of making the code more filthy than it needed to be. The GCAdapter namespace was parasitic and hooked in to the regular GC Controller SI class to overwrite the data that it was getting from the default configuration. Now instead we have a specific SIDevice class for the Wii U Gamecube adapter. This class is fairly simple and is a child of the regular SI Gamecube Pad device and only reimplements what it needs to. This also gives the ability to configure controllers individually, which allows the user to configure rumble individually per pad input. Overall the code is cleaner, and it fits more in line with how the rest of Dolphin works. --- Source/Core/Core/CMakeLists.txt | 1 + Source/Core/Core/ConfigManager.cpp | 6 +- Source/Core/Core/ConfigManager.h | 3 +- Source/Core/Core/Core.vcxproj | 2 + Source/Core/Core/Core.vcxproj.filters | 6 + Source/Core/Core/HW/SI_Device.cpp | 4 + Source/Core/Core/HW/SI_Device.h | 3 +- Source/Core/Core/HW/SI_DeviceGCAdapter.cpp | 147 ++++++++++++++++++ Source/Core/Core/HW/SI_DeviceGCAdapter.h | 20 +++ Source/Core/Core/HW/SI_DeviceGCController.cpp | 62 +++----- Source/Core/DolphinWX/CMakeLists.txt | 1 + .../DolphinWX/Config/GCAdapterConfigDiag.cpp | 78 ++++++++++ .../DolphinWX/Config/GCAdapterConfigDiag.h | 35 +++++ .../Core/DolphinWX/ControllerConfigDiag.cpp | 112 ++++--------- Source/Core/DolphinWX/ControllerConfigDiag.h | 23 +-- Source/Core/DolphinWX/DolphinWX.vcxproj | 4 +- .../Core/DolphinWX/DolphinWX.vcxproj.filters | 8 +- Source/Core/InputCommon/GCAdapter.cpp | 48 +++++- Source/Core/InputCommon/GCAdapter.h | 6 +- 19 files changed, 412 insertions(+), 157 deletions(-) create mode 100644 Source/Core/Core/HW/SI_DeviceGCAdapter.cpp create mode 100644 Source/Core/Core/HW/SI_DeviceGCAdapter.h create mode 100644 Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp create mode 100644 Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index b37c78e309..b035b64859 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -113,6 +113,7 @@ set(SRCS ActionReplay.cpp HW/SI_Device.cpp HW/SI_DeviceDanceMat.cpp HW/SI_DeviceGBA.cpp + HW/SI_DeviceGCAdapter.cpp HW/SI_DeviceGCController.cpp HW/SI_DeviceGCSteeringWheel.cpp HW/SI_DeviceKeyboard.cpp diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index db933bceaf..5e9901f5d8 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -254,6 +254,7 @@ void SConfig::SaveCoreSettings(IniFile& ini) for (int i = 0; i < MAX_SI_CHANNELS; ++i) { core->Set(StringFromFormat("SIDevice%i", i), m_SIDevice[i]); + core->Set(StringFromFormat("AdapterRumble%i", i), m_AdapterRumble[i]); } core->Set("WiiSDCard", m_WiiSDCard); core->Set("WiiKeyboard", m_WiiKeyboard); @@ -267,8 +268,6 @@ void SConfig::SaveCoreSettings(IniFile& ini) core->Set("OverclockEnable", m_OCEnable); core->Set("GFXBackend", m_strVideoBackend); core->Set("GPUDeterminismMode", m_strGPUDeterminismMode); - core->Set("GameCubeAdapter", m_GameCubeAdapter); - core->Set("AdapterRumble", m_AdapterRumble); core->Set("PerfMapDir", m_perfDir); } @@ -509,6 +508,7 @@ void SConfig::LoadCoreSettings(IniFile& ini) for (int i = 0; i < MAX_SI_CHANNELS; ++i) { core->Get(StringFromFormat("SIDevice%i", i), (u32*)&m_SIDevice[i], (i == 0) ? SIDEVICE_GC_CONTROLLER : SIDEVICE_NONE); + core->Get(StringFromFormat("AdapterRumble%i", i), &m_AdapterRumble[i], true); } core->Get("WiiSDCard", &m_WiiSDCard, false); core->Get("WiiKeyboard", &m_WiiKeyboard, false); @@ -532,8 +532,6 @@ void SConfig::LoadCoreSettings(IniFile& ini) core->Get("FrameSkip", &m_FrameSkip, 0); core->Get("GFXBackend", &m_strVideoBackend, ""); core->Get("GPUDeterminismMode", &m_strGPUDeterminismMode, "auto"); - core->Get("GameCubeAdapter", &m_GameCubeAdapter, false); - core->Get("AdapterRumble", &m_AdapterRumble, true); core->Get("PerfMapDir", &m_perfDir, ""); } diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index de2be855e8..880e93bc8a 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -265,8 +265,7 @@ struct SConfig : NonCopyable // Input settings bool m_BackgroundInput; - bool m_GameCubeAdapter; - bool m_AdapterRumble; + bool m_AdapterRumble[4]; SysConf* m_SYSCONF; diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 87f7e52bd4..490e724006 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -145,6 +145,7 @@ + @@ -350,6 +351,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 855ee5edcb..1a3df6a407 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -447,6 +447,9 @@ HW %28Flipper/Hollywood%29\SI - Serial Interface + + HW %28Flipper/Hollywood%29\SI - Serial Interface + HW %28Flipper/Hollywood%29\SI - Serial Interface @@ -988,6 +991,9 @@ HW %28Flipper/Hollywood%29\SI - Serial Interface + + HW %28Flipper/Hollywood%29\SI - Serial Interface + HW %28Flipper/Hollywood%29\SI - Serial Interface diff --git a/Source/Core/Core/HW/SI_Device.cpp b/Source/Core/Core/HW/SI_Device.cpp index 9546cba42f..fb9b9ec638 100644 --- a/Source/Core/Core/HW/SI_Device.cpp +++ b/Source/Core/Core/HW/SI_Device.cpp @@ -11,6 +11,7 @@ #include "Core/HW/SI_DeviceAMBaseboard.h" #include "Core/HW/SI_DeviceDanceMat.h" #include "Core/HW/SI_DeviceGBA.h" +#include "Core/HW/SI_DeviceGCAdapter.h" #include "Core/HW/SI_DeviceGCController.h" #include "Core/HW/SI_DeviceGCSteeringWheel.h" #include "Core/HW/SI_DeviceKeyboard.h" @@ -73,6 +74,9 @@ std::unique_ptr SIDevice_Create(const SIDevices device, const int por case SIDEVICE_GC_CONTROLLER: return std::make_unique(device, port_number); + case SIDEVICE_WIIU_ADAPTER: + return std::make_unique(device, port_number); + case SIDEVICE_DANCEMAT: return std::make_unique(device, port_number); diff --git a/Source/Core/Core/HW/SI_Device.h b/Source/Core/Core/HW/SI_Device.h index abaf25cbd3..866ae98e2a 100644 --- a/Source/Core/Core/HW/SI_Device.h +++ b/Source/Core/Core/HW/SI_Device.h @@ -61,7 +61,8 @@ enum SIDevices : int SIDEVICE_GC_STEERING, SIDEVICE_DANCEMAT, SIDEVICE_GC_TARUKONGA, - SIDEVICE_AM_BASEBOARD + SIDEVICE_AM_BASEBOARD, + SIDEVICE_WIIU_ADAPTER, }; diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp new file mode 100644 index 0000000000..70215aa6a8 --- /dev/null +++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.cpp @@ -0,0 +1,147 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Common/MsgHandler.h" +#include "Common/Logging/Log.h" +#include "Core/Movie.h" +#include "Core/HW/SI_DeviceGCAdapter.h" + +GCPadStatus CSIDevice_GCAdapter::GetPadStatus() +{ + GCPadStatus PadStatus; + memset(&PadStatus, 0, sizeof(PadStatus)); + +#if defined(__LIBUSB__) || defined (_WIN32) + GCAdapter::Input(ISIDevice::m_iDeviceNumber, &PadStatus); +#endif + + HandleMoviePadStatus(&PadStatus); + + return PadStatus; +} + +int CSIDevice_GCAdapter::RunBuffer(u8* _pBuffer, int _iLength) +{ + // For debug logging only + ISIDevice::RunBuffer(_pBuffer, _iLength); + + // Read the command + EBufferCommands command = static_cast(_pBuffer[3]); + +#if defined(__LIBUSB__) || defined (_WIN32) + // get the correct pad number that should rumble locally when using netplay + const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); + if (!GCAdapter::DeviceConnected(numPAD)) +#endif + { + reinterpret_cast(_pBuffer)[0] = SI_NONE; + return 4; + } + + // Handle it + switch (command) + { + case CMD_RESET: + case CMD_ID: + *(u32*)&_pBuffer[0] = SI_GC_CONTROLLER; + break; + + case CMD_DIRECT: + { + INFO_LOG(SERIALINTERFACE, "PAD - Direct (Length: %d)", _iLength); + u32 high, low; + GetData(high, low); + for (int i = 0; i < (_iLength - 1) / 2; i++) + { + _pBuffer[i + 0] = (high >> (i * 8)) & 0xff; + _pBuffer[i + 4] = (low >> (i * 8)) & 0xff; + } + } + break; + + case CMD_ORIGIN: + { + INFO_LOG(SERIALINTERFACE, "PAD - Get Origin"); + + Calibrate(); + + u8* pCalibration = reinterpret_cast(&m_Origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + break; + + // Recalibrate (FiRES: i am not 100 percent sure about this) + case CMD_RECALIBRATE: + { + INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate"); + + Calibrate(); + + u8* pCalibration = reinterpret_cast(&m_Origin); + for (int i = 0; i < (int)sizeof(SOrigin); i++) + { + _pBuffer[i ^ 3] = *pCalibration++; + } + } + break; + + // DEFAULT + default: + { + ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command); + PanicAlert("SI: Unknown command (0x%x)", command); + } + break; + } + + return _iLength; +} + +void CSIDevice_GCAdapter::SendCommand(u32 _Cmd, u8 _Poll) +{ + UCommand command(_Cmd); + + switch (command.Command) + { + // Costis sent it in some demos :) + case 0x00: + break; + + case CMD_WRITE: + { +#if defined(__LIBUSB__) || defined (_WIN32) + unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard + unsigned int uStrength = command.Parameter2; + + // get the correct pad number that should rumble locally when using netplay + const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); + + if (numPAD < 4) + { + if (uType == 1 && uStrength > 2) + GCAdapter::Output(numPAD, 1); + else + GCAdapter::Output(numPAD, 0); + } +#endif + if (!_Poll) + { + m_Mode = command.Parameter2; + INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode); + } + } + break; + + default: + { + ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd); + PanicAlert("SI: Unknown direct command"); + } + break; + } +} + diff --git a/Source/Core/Core/HW/SI_DeviceGCAdapter.h b/Source/Core/Core/HW/SI_DeviceGCAdapter.h new file mode 100644 index 0000000000..05c73253fc --- /dev/null +++ b/Source/Core/Core/HW/SI_DeviceGCAdapter.h @@ -0,0 +1,20 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "Core/HW/SI_Device.h" +#include "Core/HW/SI_DeviceGCController.h" +#include "InputCommon/GCAdapter.h" +#include "InputCommon/GCPadStatus.h" + +class CSIDevice_GCAdapter : public CSIDevice_GCController +{ +public: + CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) {} + + GCPadStatus GetPadStatus() override; + int RunBuffer(u8* _pBuffer, int _iLength) override; + void SendCommand(u32 _Cmd, u8 _Poll) override; +}; diff --git a/Source/Core/Core/HW/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI_DeviceGCController.cpp index ccf27baac4..3b2a191b2e 100644 --- a/Source/Core/Core/HW/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI_DeviceGCController.cpp @@ -13,9 +13,6 @@ #include "Core/HW/SI.h" #include "Core/HW/SI_Device.h" #include "Core/HW/SI_DeviceGCController.h" -#if defined(__LIBUSB__) || defined (_WIN32) -#include "Core/HW/SI_GCAdapter.h" -#endif #include "Core/HW/SystemTimers.h" #include "InputCommon/GCPadStatus.h" @@ -119,6 +116,30 @@ int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength) return _iLength; } +void CSIDevice_GCController::HandleMoviePadStatus(GCPadStatus* PadStatus) +{ + Movie::CallGCInputManip(PadStatus, ISIDevice::m_iDeviceNumber); + + Movie::SetPolledDevice(); + if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus)) + { + } + else if (Movie::IsPlayingInput()) + { + Movie::PlayController(PadStatus, ISIDevice::m_iDeviceNumber); + Movie::InputUpdate(); + } + else if (Movie::IsRecordingInput()) + { + Movie::RecordInput(PadStatus, ISIDevice::m_iDeviceNumber); + Movie::InputUpdate(); + } + else + { + Movie::CheckPadStatus(PadStatus, ISIDevice::m_iDeviceNumber); + } +} + GCPadStatus CSIDevice_GCController::GetPadStatus() { GCPadStatus PadStatus; @@ -126,31 +147,7 @@ GCPadStatus CSIDevice_GCController::GetPadStatus() Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); -#if defined(__LIBUSB__) || defined (_WIN32) - SI_GCAdapter::Input(ISIDevice::m_iDeviceNumber, &PadStatus); -#endif - - Movie::CallGCInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); - - Movie::SetPolledDevice(); - if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, &PadStatus)) - { - } - else if (Movie::IsPlayingInput()) - { - Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); - Movie::InputUpdate(); - } - else if (Movie::IsRecordingInput()) - { - Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); - Movie::InputUpdate(); - } - else - { - Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); - } - + HandleMoviePadStatus(&PadStatus); return PadStatus; } @@ -281,15 +278,6 @@ void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll) // get the correct pad number that should rumble locally when using netplay const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); -#if defined(__LIBUSB__) || defined (_WIN32) - if (numPAD < 4) - { - if (uType == 1 && uStrength > 2) - SI_GCAdapter::Output(numPAD, 1); - else - SI_GCAdapter::Output(numPAD, 0); - } -#endif if (numPAD < 4) { if (uType == 1 && uStrength > 2) diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt index d9cdb9bd9b..1c17ccd207 100644 --- a/Source/Core/DolphinWX/CMakeLists.txt +++ b/Source/Core/DolphinWX/CMakeLists.txt @@ -10,6 +10,7 @@ set(GUI_SRCS Config/AudioConfigPane.cpp Config/ConfigMain.cpp Config/GameCubeConfigPane.cpp + Config/GCAdapterConfigDiag.cpp Config/GeneralConfigPane.cpp Config/InterfaceConfigPane.cpp Config/PathConfigPane.cpp diff --git a/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp new file mode 100644 index 0000000000..21d64a686d --- /dev/null +++ b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.cpp @@ -0,0 +1,78 @@ +// Copyright 2010 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include + +#include "Common/CommonTypes.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "DolphinWX/Config/GCAdapterConfigDiag.h" +#include "InputCommon/GCAdapter.h" + +wxDEFINE_EVENT(wxEVT_ADAPTER_UPDATE, wxCommandEvent); + + +GCAdapterConfigDiag::GCAdapterConfigDiag(wxWindow* const parent, const wxString& name, const int tab_num) + : wxDialog(parent, wxID_ANY, name, wxPoint(128,-1)), m_pad_id(tab_num) +{ + wxBoxSizer* const szr = new wxBoxSizer(wxVERTICAL); + + + wxCheckBox* const gamecube_rumble = new wxCheckBox(this, wxID_ANY, _("Rumble")); + gamecube_rumble->SetValue(SConfig::GetInstance().m_AdapterRumble[m_pad_id]); + gamecube_rumble->Bind(wxEVT_CHECKBOX, &GCAdapterConfigDiag::OnAdapterRumble, this); + + m_adapter_status = new wxStaticText(this, wxID_ANY, _("Adapter Not Detected")); + +#if defined(__LIBUSB__) || defined (_WIN32) + if (!GCAdapter::IsDetected()) + { + if (!GCAdapter::IsDriverDetected()) + { + m_adapter_status->SetLabelText(_("Driver Not Detected")); + gamecube_rumble->Disable(); + } + } + else + { + m_adapter_status->SetLabelText(_("Adapter Detected")); + } + GCAdapter::SetAdapterCallback(std::bind(&GCAdapterConfigDiag::ScheduleAdapterUpdate, this)); +#endif + + szr->Add(m_adapter_status, 0, wxEXPAND); + szr->Add(gamecube_rumble, 0, wxEXPAND); + szr->Add(CreateButtonSizer(wxOK | wxNO_DEFAULT), 0, wxEXPAND|wxALL, 5); + + SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED); + SetSizerAndFit(szr); + Center(); + + Bind(wxEVT_ADAPTER_UPDATE, &GCAdapterConfigDiag::UpdateAdapter, this); +} + +void GCAdapterConfigDiag::ScheduleAdapterUpdate() +{ + wxQueueEvent(this, new wxCommandEvent(wxEVT_ADAPTER_UPDATE)); +} + +void GCAdapterConfigDiag::UpdateAdapter(wxCommandEvent& ev) +{ +#if defined(__LIBUSB__) || defined (_WIN32) + bool unpause = Core::PauseAndLock(true); + if (GCAdapter::IsDetected()) + m_adapter_status->SetLabelText(_("Adapter Detected")); + else + m_adapter_status->SetLabelText(_("Adapter Not Detected")); + Core::PauseAndLock(false, unpause); +#endif +} + +GCAdapterConfigDiag::~GCAdapterConfigDiag() +{ +#if defined(__LIBUSB__) || defined (_WIN32) + GCAdapter::SetAdapterCallback(nullptr); +#endif +} diff --git a/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h new file mode 100644 index 0000000000..fa7bf471d8 --- /dev/null +++ b/Source/Core/DolphinWX/Config/GCAdapterConfigDiag.h @@ -0,0 +1,35 @@ +// Copyright 2010 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Core/ConfigManager.h" + +class GCAdapterConfigDiag : public wxDialog +{ +public: + GCAdapterConfigDiag(wxWindow* const parent, const wxString& name, const int tab_num = 0); + ~GCAdapterConfigDiag(); + + void ScheduleAdapterUpdate(); + void UpdateAdapter(wxCommandEvent& ev); + +private: + wxStaticText* m_adapter_status; + int m_pad_id; + + void OnAdapterRumble(wxCommandEvent& event) + { + SConfig::GetInstance().m_AdapterRumble[m_pad_id] = event.IsChecked(); + } +}; diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.cpp b/Source/Core/DolphinWX/ControllerConfigDiag.cpp index 85154040ea..1e736ce56b 100644 --- a/Source/Core/DolphinWX/ControllerConfigDiag.cpp +++ b/Source/Core/DolphinWX/ControllerConfigDiag.cpp @@ -30,20 +30,20 @@ #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "DolphinWX/ControllerConfigDiag.h" #include "DolphinWX/InputConfigDiag.h" +#include "DolphinWX/Config/GCAdapterConfigDiag.h" #include "InputCommon/GCAdapter.h" #if defined(HAVE_XRANDR) && HAVE_XRANDR #include "DolphinWX/X11Utils.h" #endif -wxDEFINE_EVENT(wxEVT_ADAPTER_UPDATE, wxCommandEvent); - ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent) : wxDialog(parent, wxID_ANY, _("Dolphin Controller Configuration")) { m_gc_pad_type_strs = {{ _("None"), _("Standard Controller"), + _("GameCube Adapter for Wii U"), _("Steering Wheel"), _("Dance Mat"), _("TaruKonga (Bongos)"), @@ -68,7 +68,6 @@ ControllerConfigDiag::ControllerConfigDiag(wxWindow* const parent) SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED); SetSizerAndFit(main_sizer); Center(); - Bind(wxEVT_ADAPTER_UPDATE, &ControllerConfigDiag::UpdateAdapter, this); } wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer() @@ -111,24 +110,27 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer() case SIDEVICE_GC_CONTROLLER: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]); break; - case SIDEVICE_GC_STEERING: + case SIDEVICE_WIIU_ADAPTER: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[2]); break; - case SIDEVICE_DANCEMAT: + case SIDEVICE_GC_STEERING: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[3]); break; - case SIDEVICE_GC_TARUKONGA: + case SIDEVICE_DANCEMAT: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[4]); break; - case SIDEVICE_GC_GBA: + case SIDEVICE_GC_TARUKONGA: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[5]); + break; + case SIDEVICE_GC_GBA: + pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[6]); gamecube_configure_bt[i]->Disable(); break; case SIDEVICE_GC_KEYBOARD: - pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[6]); + pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[7]); break; case SIDEVICE_AM_BASEBOARD: - pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[7]); + pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[8]); break; default: pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[0]); @@ -145,67 +147,9 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer() gamecube_static_sizer->Add(gamecube_flex_sizer, 1, wxEXPAND, 5); gamecube_static_sizer->AddSpacer(5); - wxStaticBoxSizer* const gamecube_adapter_group = new wxStaticBoxSizer(wxVERTICAL, this, _("GameCube Adapter")); - wxBoxSizer* const gamecube_adapter_sizer = new wxBoxSizer(wxHORIZONTAL); - - wxCheckBox* const gamecube_adapter = new wxCheckBox(this, wxID_ANY, _("Direct Connect")); - gamecube_adapter->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnGameCubeAdapter, this); - - wxCheckBox* const gamecube_rumble = new wxCheckBox(this, wxID_ANY, _("Rumble")); - gamecube_rumble->SetValue(SConfig::GetInstance().m_AdapterRumble); - gamecube_rumble->Bind(wxEVT_CHECKBOX, &ControllerConfigDiag::OnAdapterRumble, this); - - m_adapter_status = new wxStaticText(this, wxID_ANY, _("Adapter Not Detected")); - - gamecube_adapter_group->Add(m_adapter_status, 0, wxEXPAND); - gamecube_adapter_sizer->Add(gamecube_adapter, 0, wxEXPAND); - gamecube_adapter_sizer->Add(gamecube_rumble, 0, wxEXPAND); - gamecube_adapter_group->Add(gamecube_adapter_sizer, 0, wxEXPAND); - gamecube_static_sizer->Add(gamecube_adapter_group, 0, wxEXPAND); - -#if defined(__LIBUSB__) || defined (_WIN32) - gamecube_adapter->SetValue(SConfig::GetInstance().m_GameCubeAdapter); - if (!SI_GCAdapter::IsDetected()) - { - if (!SI_GCAdapter::IsDriverDetected()) - { - m_adapter_status->SetLabelText(_("Driver Not Detected")); - gamecube_adapter->Disable(); - gamecube_adapter->SetValue(false); - gamecube_rumble->Disable(); - } - } - else - { - m_adapter_status->SetLabelText(_("Adapter Detected")); - } - if (Core::GetState() != Core::CORE_UNINITIALIZED) - { - gamecube_adapter->Disable(); - } - SI_GCAdapter::SetAdapterCallback(std::bind(&ControllerConfigDiag::ScheduleAdapterUpdate, this)); -#endif - return gamecube_static_sizer; } -void ControllerConfigDiag::ScheduleAdapterUpdate() -{ - wxQueueEvent(this, new wxCommandEvent(wxEVT_ADAPTER_UPDATE)); -} - -void ControllerConfigDiag::UpdateAdapter(wxCommandEvent& ev) -{ -#if defined(__LIBUSB__) || defined (_WIN32) - bool unpause = Core::PauseAndLock(true); - if (SI_GCAdapter::IsDetected()) - m_adapter_status->SetLabelText(_("Adapter Detected")); - else - m_adapter_status->SetLabelText(_("Adapter Not Detected")); - Core::PauseAndLock(false, unpause); -#endif -} - wxStaticBoxSizer* ControllerConfigDiag::CreateWiimoteConfigSizer() { wxStaticText* wiimote_label[4]; @@ -502,30 +446,35 @@ void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event) } else if (device_name == m_gc_pad_type_strs[2]) { - tempType = SIDEVICE_GC_STEERING; + tempType = SIDEVICE_WIIU_ADAPTER; gamecube_configure_bt[device_num]->Enable(); } else if (device_name == m_gc_pad_type_strs[3]) { - tempType = SIDEVICE_DANCEMAT; + tempType = SIDEVICE_GC_STEERING; gamecube_configure_bt[device_num]->Enable(); } else if (device_name == m_gc_pad_type_strs[4]) { - tempType = SIDEVICE_GC_TARUKONGA; + tempType = SIDEVICE_DANCEMAT; gamecube_configure_bt[device_num]->Enable(); } else if (device_name == m_gc_pad_type_strs[5]) + { + tempType = SIDEVICE_GC_TARUKONGA; + gamecube_configure_bt[device_num]->Enable(); + } + else if (device_name == m_gc_pad_type_strs[6]) { tempType = SIDEVICE_GC_GBA; gamecube_configure_bt[device_num]->Disable(); } - else if (device_name == m_gc_pad_type_strs[6]) + else if (device_name == m_gc_pad_type_strs[7]) { tempType = SIDEVICE_GC_KEYBOARD; gamecube_configure_bt[device_num]->Enable(); } - else if (device_name == m_gc_pad_type_strs[7]) + else if (device_name == m_gc_pad_type_strs[8]) { tempType = SIDEVICE_AM_BASEBOARD; gamecube_configure_bt[device_num]->Enable(); @@ -538,6 +487,13 @@ void ControllerConfigDiag::OnGameCubePortChanged(wxCommandEvent& event) SConfig::GetInstance().m_SIDevice[device_num] = tempType; +#if defined(__LIBUSB__) || defined (_WIN32) + if (GCAdapter::UseAdapter()) + GCAdapter::StartScanThread(); + else + GCAdapter::StopScanThread(); +#endif + if (Core::IsRunning()) SerialInterface::ChangeDevice(tempType, device_num); } @@ -555,6 +511,11 @@ void ControllerConfigDiag::OnGameCubeConfigButton(wxCommandEvent& event) InputConfigDialog m_ConfigFrame(this, *key_plugin, _("GameCube Controller Configuration"), port_num); m_ConfigFrame.ShowModal(); } + else if (SConfig::GetInstance().m_SIDevice[port_num] == SIDEVICE_WIIU_ADAPTER) + { + GCAdapterConfigDiag m_ConfigFramg(this, _("Wii U Gamecube Controller Adapter Configuration"), port_num); + m_ConfigFramg.ShowModal(); + } else { InputConfigDialog m_ConfigFrame(this, *pad_plugin, _("GameCube Controller Configuration"), port_num); @@ -563,10 +524,3 @@ void ControllerConfigDiag::OnGameCubeConfigButton(wxCommandEvent& event) HotkeyManagerEmu::Enable(true); } - -ControllerConfigDiag::~ControllerConfigDiag() -{ -#if defined(__LIBUSB__) || defined (_WIN32) - SI_GCAdapter::SetAdapterCallback(nullptr); -#endif -} diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.h b/Source/Core/DolphinWX/ControllerConfigDiag.h index 7bfc76bca7..8646396b2b 100644 --- a/Source/Core/DolphinWX/ControllerConfigDiag.h +++ b/Source/Core/DolphinWX/ControllerConfigDiag.h @@ -21,7 +21,6 @@ class ControllerConfigDiag : public wxDialog { public: ControllerConfigDiag(wxWindow* const parent); - ~ControllerConfigDiag(); private: void RefreshRealWiimotes(wxCommandEvent& event); @@ -70,23 +69,6 @@ private: event.Skip(); } - void OnGameCubeAdapter(wxCommandEvent& event) - { - SConfig::GetInstance().m_GameCubeAdapter = event.IsChecked(); -#ifdef __LIBUSB__ - if (event.IsChecked()) - SI_GCAdapter::StartScanThread(); - else - SI_GCAdapter::StopScanThread(); -#endif - event.Skip(); - } - void OnAdapterRumble(wxCommandEvent& event) - { - SConfig::GetInstance().m_AdapterRumble = event.IsChecked(); - } - - wxStaticBoxSizer* CreateGamecubeSizer(); wxStaticBoxSizer* CreateWiimoteConfigSizer(); wxStaticBoxSizer* CreateBalanceBoardSizer(); @@ -96,17 +78,14 @@ private: void Cancel(wxCommandEvent& event); void OnGameCubePortChanged(wxCommandEvent& event); void OnGameCubeConfigButton(wxCommandEvent& event); - void ScheduleAdapterUpdate(); - void UpdateAdapter(wxCommandEvent& ev); std::map m_gc_port_choice_ids; std::map m_gc_port_config_ids; - std::array m_gc_pad_type_strs; + std::array m_gc_pad_type_strs; std::map m_wiimote_index_from_ctrl_id; unsigned int m_orig_wiimote_sources[MAX_BBMOTES]; - wxStaticText* m_adapter_status; wxButton* wiimote_configure_bt[MAX_WIIMOTES]; wxButton* gamecube_configure_bt[4]; std::map m_wiimote_index_from_conf_bt_id; diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj b/Source/Core/DolphinWX/DolphinWX.vcxproj index b4818cf162..13882b44a4 100644 --- a/Source/Core/DolphinWX/DolphinWX.vcxproj +++ b/Source/Core/DolphinWX/DolphinWX.vcxproj @@ -58,6 +58,7 @@ + @@ -113,6 +114,7 @@ + @@ -246,4 +248,4 @@ - \ No newline at end of file + diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters index 87fb5df32a..5534ec41f8 100644 --- a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters +++ b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters @@ -178,6 +178,9 @@ GUI\Config + + GUI\Config + GUI\Config @@ -339,6 +342,9 @@ GUI\Config + + GUI\Config + GUI\Config @@ -369,4 +375,4 @@ - \ No newline at end of file + diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index b6b12bcfdb..d357952f4f 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -8,15 +8,17 @@ #include "Common/Flag.h" #include "Common/Thread.h" +#include "Common/Logging/Log.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/HW/SI.h" -#include "Core/HW/SI_GCAdapter.h" #include "Core/HW/SystemTimers.h" + +#include "InputCommon/GCAdapter.h" #include "InputCommon/GCPadStatus.h" -namespace SI_GCAdapter +namespace GCAdapter { enum ControllerTypes { @@ -158,13 +160,16 @@ void Init() } else { - if (SConfig::GetInstance().m_GameCubeAdapter) + if (UseAdapter()) StartScanThread(); } } void StartScanThread() { + if (s_adapter_detect_thread_running.IsSet()) + return; + s_adapter_detect_thread_running.Set(true); s_adapter_detect_thread = std::thread(ScanThreadFunc); } @@ -351,7 +356,11 @@ void Reset() void Input(int chan, GCPadStatus* pad) { - if (!SConfig::GetInstance().m_GameCubeAdapter) + bool use_adapter = SConfig::GetInstance().m_SIDevice[0] == SIDEVICE_WIIU_ADAPTER || + SConfig::GetInstance().m_SIDevice[1] == SIDEVICE_WIIU_ADAPTER || + SConfig::GetInstance().m_SIDevice[2] == SIDEVICE_WIIU_ADAPTER || + SConfig::GetInstance().m_SIDevice[3] == SIDEVICE_WIIU_ADAPTER; + if (!use_adapter) return; if (s_handle == nullptr || !s_detected) @@ -371,15 +380,19 @@ void Input(int chan, GCPadStatus* pad) } else { + bool get_origin = false; u8 type = controller_payload_copy[1 + (9 * chan)] >> 4; if (type != CONTROLLER_NONE && s_controller_type[chan] == CONTROLLER_NONE) + { NOTICE_LOG(SERIALINTERFACE, "New device connected to Port %d of Type: %02x", chan + 1, controller_payload_copy[1 + (9 * chan)]); + get_origin = true; + } s_controller_type[chan] = type; + memset(pad, 0, sizeof(*pad)); if (s_controller_type[chan] != CONTROLLER_NONE) { - memset(pad, 0, sizeof(*pad)); u8 b1 = controller_payload_copy[1 + (9 * chan) + 1]; u8 b2 = controller_payload_copy[1 + (9 * chan) + 2]; @@ -398,6 +411,8 @@ void Input(int chan, GCPadStatus* pad) if (b2 & (1 << 2)) pad->button |= PAD_TRIGGER_R; if (b2 & (1 << 3)) pad->button |= PAD_TRIGGER_L; + if (get_origin) pad->button |= PAD_GET_ORIGIN; + pad->stickX = controller_payload_copy[1 + (9 * chan) + 3]; pad->stickY = controller_payload_copy[1 + (9 * chan) + 4]; pad->substickX = controller_payload_copy[1 + (9 * chan) + 5]; @@ -405,12 +420,29 @@ void Input(int chan, GCPadStatus* pad) pad->triggerLeft = controller_payload_copy[1 + (9 * chan) + 7]; pad->triggerRight = controller_payload_copy[1 + (9 * chan) + 8]; } + else + { + pad->button = PAD_ERR_STATUS; + } } } +bool DeviceConnected(int chan) +{ + return s_controller_type[chan] != CONTROLLER_NONE; +} + +bool UseAdapter() +{ + return SConfig::GetInstance().m_SIDevice[0] == SIDEVICE_WIIU_ADAPTER || + SConfig::GetInstance().m_SIDevice[1] == SIDEVICE_WIIU_ADAPTER || + SConfig::GetInstance().m_SIDevice[2] == SIDEVICE_WIIU_ADAPTER || + SConfig::GetInstance().m_SIDevice[3] == SIDEVICE_WIIU_ADAPTER; +} + void ResetRumble() { - if (!SConfig::GetInstance().m_GameCubeAdapter) + if (!UseAdapter()) return; if (s_handle == nullptr || !s_detected) return; @@ -427,7 +459,7 @@ void ResetRumble() void Output(int chan, u8 rumble_command) { - if (s_handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter || !SConfig::GetInstance().m_AdapterRumble) + if (s_handle == nullptr || !UseAdapter() || !SConfig::GetInstance().m_AdapterRumble) return; // Skip over rumble commands if it has not changed or the controller is wireless @@ -458,4 +490,4 @@ bool IsDriverDetected() return !s_libusb_driver_not_supported; } -} // end of namespace SI_GCAdapter +} // end of namespace GCAdapter diff --git a/Source/Core/InputCommon/GCAdapter.h b/Source/Core/InputCommon/GCAdapter.h index 13deb8b536..c8091291ff 100644 --- a/Source/Core/InputCommon/GCAdapter.h +++ b/Source/Core/InputCommon/GCAdapter.h @@ -8,7 +8,7 @@ struct GCPadStatus; -namespace SI_GCAdapter +namespace GCAdapter { void Init(); @@ -23,5 +23,7 @@ void Input(int chan, GCPadStatus* pad); void Output(int chan, u8 rumble_command); bool IsDetected(); bool IsDriverDetected(); +bool DeviceConnected(int chan); +bool UseAdapter(); -} // end of namespace SI_GCAdapter +} // end of namespace GCAdapter