mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-13 15:59:23 +01:00
Moved the GC Adapter processing under "Standard Controller" as it appears the adapter does not work with controllers other than the standard controller (pads, bongos, some dance mats).
This commit is contained in:
parent
8fdd04e647
commit
30b34f3b2e
@ -15,9 +15,6 @@
|
||||
#include "Core/HW/ProcessorInterface.h"
|
||||
#include "Core/HW/SI.h"
|
||||
#include "Core/HW/SI_DeviceGBA.h"
|
||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
||||
#include "Core/HW/SI_GCAdapter.h"
|
||||
#endif
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
#include "Core/HW/VideoInterface.h"
|
||||
|
||||
@ -59,6 +56,56 @@ enum
|
||||
SI_EXI_CLOCK_COUNT = 0x3C,
|
||||
};
|
||||
|
||||
// SI Channel Output
|
||||
union USIChannelOut
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
u32 OUTPUT1 : 8;
|
||||
u32 OUTPUT0 : 8;
|
||||
u32 CMD : 8;
|
||||
u32 : 8;
|
||||
};
|
||||
};
|
||||
|
||||
// SI Channel Input High u32
|
||||
union USIChannelIn_Hi
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
u32 INPUT3 : 8;
|
||||
u32 INPUT2 : 8;
|
||||
u32 INPUT1 : 8;
|
||||
u32 INPUT0 : 6;
|
||||
u32 ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR.
|
||||
u32 ERRSTAT : 1; // 0: no error 1: error on last transfer
|
||||
};
|
||||
};
|
||||
|
||||
// SI Channel Input Low u32
|
||||
union USIChannelIn_Lo
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
u32 INPUT7 : 8;
|
||||
u32 INPUT6 : 8;
|
||||
u32 INPUT5 : 8;
|
||||
u32 INPUT4 : 8;
|
||||
};
|
||||
};
|
||||
|
||||
// SI Channel
|
||||
struct SSIChannel
|
||||
{
|
||||
USIChannelOut m_Out;
|
||||
USIChannelIn_Hi m_InHi;
|
||||
USIChannelIn_Lo m_InLo;
|
||||
ISIDevice* m_pDevice;
|
||||
};
|
||||
|
||||
// SI Poll: Controls how often a device is polled
|
||||
union USIPoll
|
||||
{
|
||||
@ -337,9 +384,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
g_Channel[1].m_pDevice->SendCommand(g_Channel[1].m_Out.Hex, g_Poll.EN1);
|
||||
g_Channel[2].m_pDevice->SendCommand(g_Channel[2].m_Out.Hex, g_Poll.EN2);
|
||||
g_Channel[3].m_pDevice->SendCommand(g_Channel[3].m_Out.Hex, g_Poll.EN3);
|
||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
||||
SI_GCAdapter::Output(g_Channel);
|
||||
#endif
|
||||
|
||||
g_StatusReg.WR = 0;
|
||||
g_StatusReg.WRST0 = 0;
|
||||
g_StatusReg.WRST1 = 0;
|
||||
@ -462,29 +507,6 @@ void UpdateDevices()
|
||||
g_StatusReg.RDST2 = !!g_Channel[2].m_pDevice->GetData(g_Channel[2].m_InHi.Hex, g_Channel[2].m_InLo.Hex);
|
||||
g_StatusReg.RDST3 = !!g_Channel[3].m_pDevice->GetData(g_Channel[3].m_InHi.Hex, g_Channel[3].m_InLo.Hex);
|
||||
|
||||
// Check for connected GC Adapter
|
||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
||||
if (SConfig::GetInstance().m_GameCubeAdapter)
|
||||
{
|
||||
g_StatusReg.RDST0 |= (SI_GCAdapter::GetDeviceType(0) != SIDEVICE_NONE);
|
||||
g_StatusReg.RDST1 |= (SI_GCAdapter::GetDeviceType(1) != SIDEVICE_NONE);
|
||||
g_StatusReg.RDST2 |= (SI_GCAdapter::GetDeviceType(2) != SIDEVICE_NONE);
|
||||
g_StatusReg.RDST3 |= (SI_GCAdapter::GetDeviceType(3) != SIDEVICE_NONE);
|
||||
|
||||
for (int chan = 0; chan < MAX_SI_CHANNELS; chan++)
|
||||
{
|
||||
SIDevices connected_device = SI_GCAdapter::GetDeviceType(chan);
|
||||
SIDevices configured_device = SConfig::GetInstance().m_SIDevice[chan];
|
||||
|
||||
if (connected_device != SIDEVICE_NONE)
|
||||
ChangeDevice(connected_device, chan);
|
||||
else
|
||||
ChangeDevice(configured_device, chan);
|
||||
}
|
||||
|
||||
SI_GCAdapter::Input(g_Channel);
|
||||
}
|
||||
#endif
|
||||
UpdateInterrupts();
|
||||
}
|
||||
|
||||
|
@ -20,56 +20,6 @@ enum
|
||||
namespace SerialInterface
|
||||
{
|
||||
|
||||
// SI Channel Output
|
||||
union USIChannelOut
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
u32 OUTPUT1 : 8;
|
||||
u32 OUTPUT0 : 8;
|
||||
u32 CMD : 8;
|
||||
u32 : 8;
|
||||
};
|
||||
};
|
||||
|
||||
// SI Channel Input High u32
|
||||
union USIChannelIn_Hi
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
u32 INPUT3 : 8;
|
||||
u32 INPUT2 : 8;
|
||||
u32 INPUT1 : 8;
|
||||
u32 INPUT0 : 6;
|
||||
u32 ERRLATCH : 1; // 0: no error 1: Error latched. Check SISR.
|
||||
u32 ERRSTAT : 1; // 0: no error 1: error on last transfer
|
||||
};
|
||||
};
|
||||
|
||||
// SI Channel Input Low u32
|
||||
union USIChannelIn_Lo
|
||||
{
|
||||
u32 Hex;
|
||||
struct
|
||||
{
|
||||
u32 INPUT7 : 8;
|
||||
u32 INPUT6 : 8;
|
||||
u32 INPUT5 : 8;
|
||||
u32 INPUT4 : 8;
|
||||
};
|
||||
};
|
||||
|
||||
// SI Channel
|
||||
struct SSIChannel
|
||||
{
|
||||
USIChannelOut m_Out;
|
||||
USIChannelIn_Hi m_InHi;
|
||||
USIChannelIn_Lo m_InLo;
|
||||
ISIDevice* m_pDevice;
|
||||
};
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void DoState(PointerWrap &p);
|
||||
|
@ -12,6 +12,9 @@
|
||||
#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"
|
||||
|
||||
// --- standard GameCube controller ---
|
||||
@ -110,6 +113,11 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||
memset(&PadStatus, 0, sizeof(PadStatus));
|
||||
|
||||
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();
|
||||
@ -248,6 +256,9 @@ 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)
|
||||
SI_GCAdapter::Output(numPAD, command.Parameter1 & 0xff);
|
||||
#endif
|
||||
if (numPAD < 4)
|
||||
{
|
||||
if (uType == 1 && uStrength > 2)
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/HW/SI_GCAdapter.h"
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
|
||||
namespace SI_GCAdapter
|
||||
{
|
||||
@ -19,7 +18,7 @@ enum ControllerTypes
|
||||
|
||||
static libusb_device_handle* s_handle = nullptr;
|
||||
static u8 s_controller_type[MAX_SI_CHANNELS] = { CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE, CONTROLLER_NONE };
|
||||
static u8 s_controller_last_rumble[4];
|
||||
static u8 s_controller_rumble[4];
|
||||
|
||||
static std::mutex s_mutex;
|
||||
static u8 s_controller_payload[37];
|
||||
@ -60,7 +59,7 @@ void Init()
|
||||
for (int i = 0; i < MAX_SI_CHANNELS; i++)
|
||||
{
|
||||
s_controller_type[i] = CONTROLLER_NONE;
|
||||
s_controller_last_rumble[i] = 0;
|
||||
s_controller_rumble[i] = 0;
|
||||
}
|
||||
|
||||
int ret = libusb_init(nullptr);
|
||||
@ -196,7 +195,7 @@ void Shutdown()
|
||||
s_handle = nullptr;
|
||||
}
|
||||
|
||||
void Input(SerialInterface::SSIChannel* g_Channel)
|
||||
void Input(int chan, GCPadStatus* pad)
|
||||
{
|
||||
if (s_handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter)
|
||||
return;
|
||||
@ -215,60 +214,43 @@ void Input(SerialInterface::SSIChannel* g_Channel)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int chan = 0; chan < MAX_SI_CHANNELS; chan++)
|
||||
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)]);
|
||||
|
||||
s_controller_type[chan] = type;
|
||||
|
||||
if (s_controller_type[chan] != CONTROLLER_NONE)
|
||||
{
|
||||
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)]);
|
||||
pad->button = controller_payload_copy[1 + (9 * chan) + 1] << 8;
|
||||
|
||||
s_controller_type[chan] = type;
|
||||
u8 b = controller_payload_copy[1 + (9 * chan) + 2];
|
||||
if (b & (1 << 0)) pad->button |= PAD_BUTTON_START;
|
||||
if (b & (1 << 1)) pad->button |= PAD_TRIGGER_Z;
|
||||
if (b & (1 << 2)) pad->button |= PAD_TRIGGER_R;
|
||||
if (b & (1 << 3)) pad->button |= PAD_TRIGGER_L;
|
||||
|
||||
if (s_controller_type[chan] != CONTROLLER_NONE)
|
||||
{
|
||||
g_Channel[chan].m_InHi.Hex = 0;
|
||||
g_Channel[chan].m_InLo.Hex = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
g_Channel[chan].m_InHi.Hex |= (controller_payload_copy[2 + chan + j + (8 * chan) + 0] << (8 * (3 - j)));
|
||||
g_Channel[chan].m_InLo.Hex |= (controller_payload_copy[2 + chan + j + (8 * chan) + 4] << (8 * (3 - j)));
|
||||
}
|
||||
|
||||
u8 buttons_0 = (g_Channel[chan].m_InHi.Hex >> 28) & 0x0f;
|
||||
u8 buttons_1 = (g_Channel[chan].m_InHi.Hex >> 24) & 0x0f;
|
||||
u8 buttons_2 = (g_Channel[chan].m_InHi.Hex >> 20) & 0x0f;
|
||||
u8 buttons_3 = (g_Channel[chan].m_InHi.Hex >> 16) & 0x0f;
|
||||
g_Channel[chan].m_InHi.Hex = buttons_3 << 28 | buttons_1 << 24 | (buttons_2) << 20 | buttons_0 << 16 | (g_Channel[chan].m_InHi.Hex & 0x0000ffff);
|
||||
|
||||
if (type == CONTROLLER_WIRED || type == CONTROLLER_WIRELESS)
|
||||
g_Channel[chan].m_InHi.Hex |= (PAD_USE_ORIGIN << 16);
|
||||
}
|
||||
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];
|
||||
pad->substickY = controller_payload_copy[1 + (9 * chan) + 6];
|
||||
pad->triggerLeft = controller_payload_copy[1 + (9 * chan) + 7];
|
||||
pad->triggerRight = controller_payload_copy[1 + (9 * chan) + 8];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Output(SerialInterface::SSIChannel* g_Channel)
|
||||
void Output(int chan, u8 rumble)
|
||||
{
|
||||
if (s_handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter)
|
||||
return;
|
||||
|
||||
bool rumble_update = false;
|
||||
u8 current_rumble[4] = { 0, 0, 0, 0 };
|
||||
|
||||
for (int chan = 0; chan < MAX_SI_CHANNELS; chan++)
|
||||
// Skip over rumble commands if it has not changed or the controller is wireless
|
||||
if (rumble != s_controller_rumble[chan] && s_controller_type[chan] != CONTROLLER_WIRELESS)
|
||||
{
|
||||
// Skip over rumble commands if the controller is wireless
|
||||
if (s_controller_type[chan] != CONTROLLER_WIRELESS)
|
||||
current_rumble[chan] = g_Channel[chan].m_Out.Hex & 0xff;
|
||||
s_controller_rumble[chan] = rumble;
|
||||
|
||||
if (current_rumble[chan] != s_controller_last_rumble[chan])
|
||||
rumble_update = true;
|
||||
|
||||
s_controller_last_rumble[chan] = current_rumble[chan];
|
||||
}
|
||||
|
||||
if (rumble_update)
|
||||
{
|
||||
unsigned char rumble[5] = { 0x11, current_rumble[0], current_rumble[1], current_rumble[2], current_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;
|
||||
libusb_interrupt_transfer(s_handle, s_endpoint_out, rumble, sizeof(rumble), &size, 0);
|
||||
|
||||
|
@ -6,14 +6,15 @@
|
||||
|
||||
#include "Common/Thread.h"
|
||||
#include "Core/HW/SI.h"
|
||||
#include "InputCommon/GCPadStatus.h"
|
||||
|
||||
namespace SI_GCAdapter
|
||||
{
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void Input(SerialInterface::SSIChannel* g_Channel);
|
||||
void Output(SerialInterface::SSIChannel* g_Channel);
|
||||
void Input(int chan, GCPadStatus* pad);
|
||||
void Output(int chan, u8 rumble);
|
||||
SIDevices GetDeviceType(int channel);
|
||||
void RefreshConnectedDevices();
|
||||
bool IsDetected();
|
||||
|
@ -104,22 +104,8 @@ wxStaticBoxSizer* ControllerConfigDiag::CreateGamecubeSizer()
|
||||
if (NetPlay::IsNetPlayRunning() || Movie::IsMovieActive())
|
||||
pad_type_choices[i]->Disable();
|
||||
|
||||
SIDevices selected_device = SConfig::GetInstance().m_SIDevice[i];
|
||||
|
||||
#if defined(__LIBUSB__) || defined (_WIN32)
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||
{
|
||||
SI_GCAdapter::RefreshConnectedDevices();
|
||||
if (SI_GCAdapter::GetDeviceType(i) != SIDEVICE_NONE)
|
||||
{
|
||||
pad_type_choices[i]->Disable();
|
||||
selected_device = SI_GCAdapter::GetDeviceType(i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set the saved pad type as the default choice.
|
||||
switch (selected_device)
|
||||
switch (SConfig::GetInstance().m_SIDevice[i])
|
||||
{
|
||||
case SIDEVICE_GC_CONTROLLER:
|
||||
pad_type_choices[i]->SetStringSelection(m_gc_pad_type_strs[1]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user