Fix GCPad recalibration shortcut.
Dolphin has supported the recalibration shortcut (X+Y+Start) for quite a long while. So if someont's axises are terrible, you could easily recalibrate. Games even get the initial calibration upon boot(Most of the time). While changing over the GCAdapter code, I was testing to make sure the reset and calibration shortcuts still worked, turns out they didn't work at all. Looking in to the problem, we capture the combination properly, and we wait three seconds until we actually fire that off recalibration. The problem is for Nintendo's SDK to properly handle recalibrating, we need to send back data saying that it needs to recalibrate. On hardware this is done as part of the 64bits of data the controller sends back to us. On holding of the controller, bit 61 of the return value is set, which the Nintendo SDK catches, and then signals immediately afterwards a CMD_ORIGIN command in order to recalibrate the controller. We were outright ignoring this bit, so the library wasn't ever recalibrating. I suspect in the past the class itself used to use the calibration data to to offset the data, but somewhere along the lines it got munged out of existence. The Gamecube adapter does this shortcut in a bit of a unique way, instead of sending the command and having the library support it and what have you. Once holding the shortcut for the amount of time, the adapter reports back that the controller has actually been disconnected. Then when you let go of the combination, the adapter states that a new device has been connected to that port, and the recalibration happens because a new device is "connected." This fixes controller calibration for both emulated GC controllers and also the Wii Gamecube Adapter.
This commit is contained in:
parent
49410576e9
commit
1dcc199a63
|
@ -255,6 +255,7 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
||||||
{
|
{
|
||||||
core->Set(StringFromFormat("SIDevice%i", i), m_SIDevice[i]);
|
core->Set(StringFromFormat("SIDevice%i", i), m_SIDevice[i]);
|
||||||
core->Set(StringFromFormat("AdapterRumble%i", i), m_AdapterRumble[i]);
|
core->Set(StringFromFormat("AdapterRumble%i", i), m_AdapterRumble[i]);
|
||||||
|
core->Set(StringFromFormat("SimulateKonga%i", i), m_AdapterKonga[i]);
|
||||||
}
|
}
|
||||||
core->Set("WiiSDCard", m_WiiSDCard);
|
core->Set("WiiSDCard", m_WiiSDCard);
|
||||||
core->Set("WiiKeyboard", m_WiiKeyboard);
|
core->Set("WiiKeyboard", m_WiiKeyboard);
|
||||||
|
@ -509,6 +510,7 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
||||||
{
|
{
|
||||||
core->Get(StringFromFormat("SIDevice%i", i), (u32*)&m_SIDevice[i], (i == 0) ? SIDEVICE_GC_CONTROLLER : SIDEVICE_NONE);
|
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(StringFromFormat("AdapterRumble%i", i), &m_AdapterRumble[i], true);
|
||||||
|
core->Get(StringFromFormat("SimulateKonga%i", i), &m_AdapterKonga[i], false);
|
||||||
}
|
}
|
||||||
core->Get("WiiSDCard", &m_WiiSDCard, false);
|
core->Get("WiiSDCard", &m_WiiSDCard, false);
|
||||||
core->Get("WiiKeyboard", &m_WiiKeyboard, false);
|
core->Get("WiiKeyboard", &m_WiiKeyboard, false);
|
||||||
|
|
|
@ -266,6 +266,7 @@ struct SConfig : NonCopyable
|
||||||
// Input settings
|
// Input settings
|
||||||
bool m_BackgroundInput;
|
bool m_BackgroundInput;
|
||||||
bool m_AdapterRumble[4];
|
bool m_AdapterRumble[4];
|
||||||
|
bool m_AdapterKonga[4];
|
||||||
|
|
||||||
SysConf* m_SYSCONF;
|
SysConf* m_SYSCONF;
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,18 @@
|
||||||
|
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
#include "Core/HW/SI_DeviceGCAdapter.h"
|
#include "Core/HW/SI_DeviceGCAdapter.h"
|
||||||
|
|
||||||
|
CSIDevice_GCAdapter::CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber)
|
||||||
|
: CSIDevice_GCController(device, _iDeviceNumber)
|
||||||
|
{
|
||||||
|
// get the correct pad number that should rumble locally when using netplay
|
||||||
|
const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber);
|
||||||
|
m_simulate_konga = SConfig::GetInstance().m_AdapterKonga[numPAD];
|
||||||
|
}
|
||||||
|
|
||||||
GCPadStatus CSIDevice_GCAdapter::GetPadStatus()
|
GCPadStatus CSIDevice_GCAdapter::GetPadStatus()
|
||||||
{
|
{
|
||||||
GCPadStatus PadStatus;
|
GCPadStatus PadStatus;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
class CSIDevice_GCAdapter : public CSIDevice_GCController
|
class CSIDevice_GCAdapter : public CSIDevice_GCController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) {}
|
CSIDevice_GCAdapter(SIDevices device, int _iDeviceNumber);
|
||||||
|
|
||||||
GCPadStatus GetPadStatus() override;
|
GCPadStatus GetPadStatus() override;
|
||||||
int RunBuffer(u8* _pBuffer, int _iLength) override;
|
int RunBuffer(u8* _pBuffer, int _iLength) override;
|
||||||
|
|
|
@ -160,6 +160,8 @@ GCPadStatus CSIDevice_GCController::GetPadStatus()
|
||||||
bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
{
|
{
|
||||||
GCPadStatus PadStatus = GetPadStatus();
|
GCPadStatus PadStatus = GetPadStatus();
|
||||||
|
if (HandleButtonCombos(PadStatus) == COMBO_ORIGIN)
|
||||||
|
PadStatus.button |= PAD_GET_ORIGIN;
|
||||||
|
|
||||||
_Hi = MapPadStatus(PadStatus);
|
_Hi = MapPadStatus(PadStatus);
|
||||||
|
|
||||||
|
@ -208,7 +210,12 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
|
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleButtonCombos(PadStatus);
|
// Unset all bits except those that represent
|
||||||
|
// A, B, X, Y, Start and the error bits, as they
|
||||||
|
// are not used.
|
||||||
|
if (m_simulate_konga)
|
||||||
|
_Hi &= ~0x20FFFFFF;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +229,7 @@ u32 CSIDevice_GCController::MapPadStatus(const GCPadStatus& pad_status)
|
||||||
return _Hi;
|
return _Hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
|
CSIDevice_GCController::EButtonCombo CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
|
||||||
{
|
{
|
||||||
// Keep track of the special button combos (embedded in controller hardware... :( )
|
// Keep track of the special button combos (embedded in controller hardware... :( )
|
||||||
EButtonCombo tempCombo;
|
EButtonCombo tempCombo;
|
||||||
|
@ -255,8 +262,11 @@ void CSIDevice_GCController::HandleButtonCombos(const GCPadStatus& pad_status)
|
||||||
m_Origin.uTrigger_R = pad_status.triggerRight;
|
m_Origin.uTrigger_R = pad_status.triggerRight;
|
||||||
}
|
}
|
||||||
m_LastButtonCombo = COMBO_NONE;
|
m_LastButtonCombo = COMBO_NONE;
|
||||||
|
return tempCombo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return COMBO_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendCommand
|
// SendCommand
|
||||||
|
|
|
@ -79,6 +79,9 @@ protected:
|
||||||
// Type of button combo from the last/current poll
|
// Type of button combo from the last/current poll
|
||||||
EButtonCombo m_LastButtonCombo;
|
EButtonCombo m_LastButtonCombo;
|
||||||
|
|
||||||
|
// Set this if we want to simulate the "TaruKonga" DK Bongo controller
|
||||||
|
bool m_simulate_konga = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -98,14 +101,15 @@ public:
|
||||||
|
|
||||||
virtual GCPadStatus GetPadStatus();
|
virtual GCPadStatus GetPadStatus();
|
||||||
virtual u32 MapPadStatus(const GCPadStatus& pad_status);
|
virtual u32 MapPadStatus(const GCPadStatus& pad_status);
|
||||||
virtual void HandleButtonCombos(const GCPadStatus& pad_status);
|
virtual EButtonCombo HandleButtonCombos(const GCPadStatus& pad_status);
|
||||||
|
|
||||||
// Send and Receive pad input from network
|
// Send and Receive pad input from network
|
||||||
static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status);
|
static bool NetPlay_GetInput(u8 numPAD, GCPadStatus* status);
|
||||||
static u8 NetPlay_InGamePadToLocalPad(u8 numPAD);
|
static u8 NetPlay_InGamePadToLocalPad(u8 numPAD);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void Calibrate();
|
void Calibrate();
|
||||||
|
void HandleMoviePadStatus(GCPadStatus* PadStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,16 +117,8 @@ private:
|
||||||
class CSIDevice_TaruKonga : public CSIDevice_GCController
|
class CSIDevice_TaruKonga : public CSIDevice_GCController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber) { }
|
CSIDevice_TaruKonga(SIDevices device, int _iDeviceNumber) : CSIDevice_GCController(device, _iDeviceNumber)
|
||||||
|
|
||||||
bool GetData(u32& _Hi, u32& _Low) override
|
|
||||||
{
|
{
|
||||||
CSIDevice_GCController::GetData(_Hi, _Low);
|
m_simulate_konga = true;
|
||||||
|
|
||||||
// Unset all bits except those that represent
|
|
||||||
// A, B, X, Y, Start and the error bits, as they
|
|
||||||
// are not used.
|
|
||||||
_Hi &= ~0x20FFFFFF;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,10 @@ GCAdapterConfigDiag::GCAdapterConfigDiag(wxWindow* const parent, const wxString&
|
||||||
gamecube_rumble->SetValue(SConfig::GetInstance().m_AdapterRumble[m_pad_id]);
|
gamecube_rumble->SetValue(SConfig::GetInstance().m_AdapterRumble[m_pad_id]);
|
||||||
gamecube_rumble->Bind(wxEVT_CHECKBOX, &GCAdapterConfigDiag::OnAdapterRumble, this);
|
gamecube_rumble->Bind(wxEVT_CHECKBOX, &GCAdapterConfigDiag::OnAdapterRumble, this);
|
||||||
|
|
||||||
|
wxCheckBox* const gamecube_konga = new wxCheckBox(this, wxID_ANY, _("Simulate DK TaruKonga"));
|
||||||
|
gamecube_konga->SetValue(SConfig::GetInstance().m_AdapterKonga[m_pad_id]);
|
||||||
|
gamecube_konga->Bind(wxEVT_CHECKBOX, &GCAdapterConfigDiag::OnAdapterKonga, this);
|
||||||
|
|
||||||
m_adapter_status = new wxStaticText(this, wxID_ANY, _("Adapter Not Detected"));
|
m_adapter_status = new wxStaticText(this, wxID_ANY, _("Adapter Not Detected"));
|
||||||
|
|
||||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
#if defined(__LIBUSB__) || defined (_WIN32)
|
||||||
|
@ -44,6 +48,7 @@ GCAdapterConfigDiag::GCAdapterConfigDiag(wxWindow* const parent, const wxString&
|
||||||
|
|
||||||
szr->Add(m_adapter_status, 0, wxEXPAND);
|
szr->Add(m_adapter_status, 0, wxEXPAND);
|
||||||
szr->Add(gamecube_rumble, 0, wxEXPAND);
|
szr->Add(gamecube_rumble, 0, wxEXPAND);
|
||||||
|
szr->Add(gamecube_konga, 0, wxEXPAND);
|
||||||
szr->Add(CreateButtonSizer(wxOK | wxNO_DEFAULT), 0, wxEXPAND|wxALL, 5);
|
szr->Add(CreateButtonSizer(wxOK | wxNO_DEFAULT), 0, wxEXPAND|wxALL, 5);
|
||||||
|
|
||||||
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
|
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
|
||||||
|
|
|
@ -32,4 +32,9 @@ private:
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_AdapterRumble[m_pad_id] = event.IsChecked();
|
SConfig::GetInstance().m_AdapterRumble[m_pad_id] = event.IsChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnAdapterKonga(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
SConfig::GetInstance().m_AdapterKonga[m_pad_id] = event.IsChecked();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue