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.
This commit is contained in:
Ryan Houdek 2015-12-31 11:09:47 -06:00
parent 6e932af831
commit 49410576e9
19 changed files with 412 additions and 157 deletions

View File

@ -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

View File

@ -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, "");
}

View File

@ -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;

View File

@ -145,6 +145,7 @@
<ClCompile Include="HW\SI_DeviceAMBaseboard.cpp" />
<ClCompile Include="HW\SI_DeviceDanceMat.cpp" />
<ClCompile Include="HW\SI_DeviceGBA.cpp" />
<ClCompile Include="HW\SI_DeviceGCAdapter.cpp" />
<ClCompile Include="HW\SI_DeviceGCController.cpp" />
<ClCompile Include="HW\SI_DeviceGCSteeringWheel.cpp" />
<ClCompile Include="HW\SI_DeviceKeyboard.cpp" />
@ -350,6 +351,7 @@
<ClInclude Include="HW\SI_DeviceAMBaseboard.h" />
<ClInclude Include="HW\SI_DeviceDanceMat.h" />
<ClInclude Include="HW\SI_DeviceGBA.h" />
<ClInclude Include="HW\SI_DeviceGCAdapter.h" />
<ClInclude Include="HW\SI_DeviceGCController.h" />
<ClInclude Include="HW\SI_DeviceGCSteeringWheel.h" />
<ClInclude Include="HW\SI_DeviceKeyboard.h" />

View File

@ -447,6 +447,9 @@
<ClCompile Include="HW\SI_DeviceGBA.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
<ClCompile Include="HW\SI_DeviceGCAdapter.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
<ClCompile Include="HW\SI_DeviceGCController.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
@ -988,6 +991,9 @@
<ClInclude Include="HW\SI_DeviceGBA.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
<ClInclude Include="HW\SI_DeviceGCAdapter.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
<ClInclude Include="HW\SI_DeviceGCController.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>

View File

@ -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<ISIDevice> SIDevice_Create(const SIDevices device, const int por
case SIDEVICE_GC_CONTROLLER:
return std::make_unique<CSIDevice_GCController>(device, port_number);
case SIDEVICE_WIIU_ADAPTER:
return std::make_unique<CSIDevice_GCAdapter>(device, port_number);
case SIDEVICE_DANCEMAT:
return std::make_unique<CSIDevice_DanceMat>(device, port_number);

View File

@ -61,7 +61,8 @@ enum SIDevices : int
SIDEVICE_GC_STEERING,
SIDEVICE_DANCEMAT,
SIDEVICE_GC_TARUKONGA,
SIDEVICE_AM_BASEBOARD
SIDEVICE_AM_BASEBOARD,
SIDEVICE_WIIU_ADAPTER,
};

View File

@ -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<EBufferCommands>(_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<u32*>(_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<u8*>(&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<u8*>(&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;
}
}

View File

@ -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;
};

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,78 @@
// Copyright 2010 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <wx/checkbox.h>
#include <wx/stattext.h>
#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
}

View File

@ -0,0 +1,35 @@
// Copyright 2010 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <cstddef>
#include <string>
#include <vector>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/eventfilter.h>
#include <wx/panel.h>
#include <wx/sizer.h>
#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();
}
};

View File

@ -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
}

View File

@ -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<wxWindowID, unsigned int> m_gc_port_choice_ids;
std::map<wxWindowID, unsigned int> m_gc_port_config_ids;
std::array<wxString, 8> m_gc_pad_type_strs;
std::array<wxString, 9> m_gc_pad_type_strs;
std::map<wxWindowID, unsigned int> 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<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;

View File

@ -58,6 +58,7 @@
<ClCompile Include="Config\AudioConfigPane.cpp" />
<ClCompile Include="Config\ConfigMain.cpp" />
<ClCompile Include="Config\GameCubeConfigPane.cpp" />
<ClCompile Include="Config\GCAdapterConfigDiag.cpp" />
<ClCompile Include="Config\GeneralConfigPane.cpp" />
<ClCompile Include="Config\InterfaceConfigPane.cpp" />
<ClCompile Include="Config\PathConfigPane.cpp" />
@ -113,6 +114,7 @@
<ClInclude Include="Config\AdvancedConfigPane.h" />
<ClInclude Include="Config\AudioConfigPane.h" />
<ClInclude Include="Config\GameCubeConfigPane.h" />
<ClInclude Include="Config\GCAdapterConfigDiag.h" />
<ClInclude Include="Config\GeneralConfigPane.h" />
<ClInclude Include="Config\InterfaceConfigPane.h" />
<ClInclude Include="Config\PathConfigPane.h" />

View File

@ -178,6 +178,9 @@
<ClCompile Include="Config\GameCubeConfigPane.cpp">
<Filter>GUI\Config</Filter>
</ClCompile>
<ClCompile Include="Config\GCAdapterConfigDiag.cpp">
<Filter>GUI\Config</Filter>
</ClCompile>
<ClCompile Include="Config\WiiConfigPane.cpp">
<Filter>GUI\Config</Filter>
</ClCompile>
@ -339,6 +342,9 @@
<ClInclude Include="Config\GameCubeConfigPane.h">
<Filter>GUI\Config</Filter>
</ClInclude>
<ClInclude Include="Config\GCAdapterConfigDiag.h">
<Filter>GUI\Config</Filter>
</ClInclude>
<ClInclude Include="Config\WiiConfigPane.h">
<Filter>GUI\Config</Filter>
</ClInclude>

View File

@ -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

View File

@ -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