mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 09:35:40 +00:00
Merge pull request #1666 from ggrtk/controller-fixes
Minor controller fixes
This commit is contained in:
commit
7fc68d0aca
|
@ -130,7 +130,12 @@ void AnalogController::SetButtonState(Button button, bool pressed)
|
||||||
{
|
{
|
||||||
// analog toggle
|
// analog toggle
|
||||||
if (pressed)
|
if (pressed)
|
||||||
m_analog_toggle_queued = true;
|
{
|
||||||
|
if (m_command == Command::Idle)
|
||||||
|
ProcessAnalogModeToggle();
|
||||||
|
else
|
||||||
|
m_analog_toggle_queued = true;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -197,26 +202,7 @@ void AnalogController::ResetTransferState()
|
||||||
{
|
{
|
||||||
if (m_analog_toggle_queued)
|
if (m_analog_toggle_queued)
|
||||||
{
|
{
|
||||||
if (m_analog_locked)
|
ProcessAnalogModeToggle();
|
||||||
{
|
|
||||||
g_host_interface->AddFormattedOSDMessage(
|
|
||||||
5.0f,
|
|
||||||
m_analog_mode ?
|
|
||||||
g_host_interface->TranslateString("AnalogController", "Controller %u is locked to analog mode by the game.") :
|
|
||||||
g_host_interface->TranslateString("AnalogController", "Controller %u is locked to digital mode by the game."),
|
|
||||||
m_index + 1u);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetAnalogMode(!m_analog_mode);
|
|
||||||
|
|
||||||
// Manually toggling controller mode resets and disables rumble configuration
|
|
||||||
m_rumble_unlocked = false;
|
|
||||||
ResetRumbleConfig();
|
|
||||||
|
|
||||||
// TODO: Mode switch detection (0x00 returned on certain commands instead of 0x5A)
|
|
||||||
}
|
|
||||||
|
|
||||||
m_analog_toggle_queued = false;
|
m_analog_toggle_queued = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +224,29 @@ void AnalogController::SetAnalogMode(bool enabled)
|
||||||
m_analog_mode = enabled;
|
m_analog_mode = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnalogController::ProcessAnalogModeToggle()
|
||||||
|
{
|
||||||
|
if (m_analog_locked)
|
||||||
|
{
|
||||||
|
g_host_interface->AddFormattedOSDMessage(
|
||||||
|
5.0f,
|
||||||
|
m_analog_mode ?
|
||||||
|
g_host_interface->TranslateString("AnalogController", "Controller %u is locked to analog mode by the game.") :
|
||||||
|
g_host_interface->TranslateString("AnalogController", "Controller %u is locked to digital mode by the game."),
|
||||||
|
m_index + 1u);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetAnalogMode(!m_analog_mode);
|
||||||
|
|
||||||
|
// Manually toggling controller mode resets and disables rumble configuration
|
||||||
|
m_rumble_unlocked = false;
|
||||||
|
ResetRumbleConfig();
|
||||||
|
|
||||||
|
// TODO: Mode switch detection (0x00 returned on certain commands instead of 0x5A)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AnalogController::SetMotorState(u8 motor, u8 value)
|
void AnalogController::SetMotorState(u8 motor, u8 value)
|
||||||
{
|
{
|
||||||
DebugAssert(motor < NUM_MOTORS);
|
DebugAssert(motor < NUM_MOTORS);
|
||||||
|
@ -314,6 +323,22 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
|
||||||
switch (m_command)
|
switch (m_command)
|
||||||
{
|
{
|
||||||
case Command::Idle:
|
case Command::Idle:
|
||||||
|
{
|
||||||
|
*data_out = 0xFF;
|
||||||
|
|
||||||
|
if (data_in == 0x01)
|
||||||
|
{
|
||||||
|
Log_DevPrintf("ACK controller access");
|
||||||
|
m_command = Command::Ready;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log_DevPrintf("Unknown data_in = 0x%02X", data_in);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Command::Ready:
|
||||||
{
|
{
|
||||||
if (data_in == 0x42)
|
if (data_in == 0x42)
|
||||||
{
|
{
|
||||||
|
@ -378,15 +403,8 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*data_out = 0xFF;
|
Log_ErrorPrintf("Unimplemented analog controller command 0x%02X", data_in);
|
||||||
ack = (data_in == 0x01);
|
Panic("Unimplemented analog controller command");
|
||||||
|
|
||||||
if (ack)
|
|
||||||
Log_DevPrintf("ACK controller access");
|
|
||||||
else
|
|
||||||
Log_DevPrintf("Unknown data_in = 0x%02X", data_in);
|
|
||||||
|
|
||||||
return ack;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -81,6 +81,7 @@ private:
|
||||||
enum class Command : u8
|
enum class Command : u8
|
||||||
{
|
{
|
||||||
Idle,
|
Idle,
|
||||||
|
Ready,
|
||||||
ReadPad, // 0x42
|
ReadPad, // 0x42
|
||||||
ConfigModeSetMode, // 0x43
|
ConfigModeSetMode, // 0x43
|
||||||
SetAnalogMode, // 0x44
|
SetAnalogMode, // 0x44
|
||||||
|
@ -110,6 +111,7 @@ private:
|
||||||
constexpr u8 GetStatusByte() const { return 0x5A; };
|
constexpr u8 GetStatusByte() const { return 0x5A; };
|
||||||
|
|
||||||
void SetAnalogMode(bool enabled);
|
void SetAnalogMode(bool enabled);
|
||||||
|
void ProcessAnalogModeToggle();
|
||||||
void SetMotorState(u8 motor, u8 value);
|
void SetMotorState(u8 motor, u8 value);
|
||||||
u8 GetExtraButtonMaskLSB() const;
|
u8 GetExtraButtonMaskLSB() const;
|
||||||
void ResetRumbleConfig();
|
void ResetRumbleConfig();
|
||||||
|
|
|
@ -167,18 +167,27 @@ bool AnalogJoystick::Transfer(const u8 data_in, u8* data_out)
|
||||||
{
|
{
|
||||||
case TransferState::Idle:
|
case TransferState::Idle:
|
||||||
{
|
{
|
||||||
// ack when sent 0x01, send ID for 0x42
|
*data_out = 0xFF;
|
||||||
|
|
||||||
|
if (data_in == 0x01)
|
||||||
|
{
|
||||||
|
m_transfer_state = TransferState::Ready;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransferState::Ready:
|
||||||
|
{
|
||||||
if (data_in == 0x42)
|
if (data_in == 0x42)
|
||||||
{
|
{
|
||||||
*data_out = Truncate8(GetID());
|
*data_out = Truncate8(GetID());
|
||||||
m_transfer_state = TransferState::IDMSB;
|
m_transfer_state = TransferState::IDMSB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
*data_out = 0xFF;
|
||||||
*data_out = 0xFF;
|
return false;
|
||||||
return (data_in == 0x01);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TransferState::IDMSB:
|
case TransferState::IDMSB:
|
||||||
|
|
|
@ -71,6 +71,7 @@ private:
|
||||||
enum class TransferState : u8
|
enum class TransferState : u8
|
||||||
{
|
{
|
||||||
Idle,
|
Idle,
|
||||||
|
Ready,
|
||||||
IDMSB,
|
IDMSB,
|
||||||
ButtonsLSB,
|
ButtonsLSB,
|
||||||
ButtonsMSB,
|
ButtonsMSB,
|
||||||
|
|
|
@ -89,18 +89,27 @@ bool DigitalController::Transfer(const u8 data_in, u8* data_out)
|
||||||
{
|
{
|
||||||
case TransferState::Idle:
|
case TransferState::Idle:
|
||||||
{
|
{
|
||||||
// ack when sent 0x01, send ID for 0x42
|
*data_out = 0xFF;
|
||||||
|
|
||||||
|
if (data_in == 0x01)
|
||||||
|
{
|
||||||
|
m_transfer_state = TransferState::Ready;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransferState::Ready:
|
||||||
|
{
|
||||||
if (data_in == 0x42)
|
if (data_in == 0x42)
|
||||||
{
|
{
|
||||||
*data_out = Truncate8(ID);
|
*data_out = Truncate8(ID);
|
||||||
m_transfer_state = TransferState::IDMSB;
|
m_transfer_state = TransferState::IDMSB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
*data_out = 0xFF;
|
||||||
*data_out = 0xFF;
|
return false;
|
||||||
return (data_in == 0x01);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TransferState::IDMSB:
|
case TransferState::IDMSB:
|
||||||
|
|
|
@ -61,6 +61,7 @@ private:
|
||||||
enum class TransferState : u8
|
enum class TransferState : u8
|
||||||
{
|
{
|
||||||
Idle,
|
Idle,
|
||||||
|
Ready,
|
||||||
IDMSB,
|
IDMSB,
|
||||||
ButtonsLSB,
|
ButtonsLSB,
|
||||||
ButtonsMSB
|
ButtonsMSB
|
||||||
|
|
|
@ -95,18 +95,27 @@ bool NamcoGunCon::Transfer(const u8 data_in, u8* data_out)
|
||||||
{
|
{
|
||||||
case TransferState::Idle:
|
case TransferState::Idle:
|
||||||
{
|
{
|
||||||
// ack when sent 0x01, send ID for 0x42
|
*data_out = 0xFF;
|
||||||
|
|
||||||
|
if (data_in == 0x01)
|
||||||
|
{
|
||||||
|
m_transfer_state = TransferState::Ready;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransferState::Ready:
|
||||||
|
{
|
||||||
if (data_in == 0x42)
|
if (data_in == 0x42)
|
||||||
{
|
{
|
||||||
*data_out = Truncate8(ID);
|
*data_out = Truncate8(ID);
|
||||||
m_transfer_state = TransferState::IDMSB;
|
m_transfer_state = TransferState::IDMSB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
*data_out = 0xFF;
|
||||||
*data_out = 0xFF;
|
return false;
|
||||||
return (data_in == 0x01);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TransferState::IDMSB:
|
case TransferState::IDMSB:
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
enum class TransferState : u8
|
enum class TransferState : u8
|
||||||
{
|
{
|
||||||
Idle,
|
Idle,
|
||||||
|
Ready,
|
||||||
IDMSB,
|
IDMSB,
|
||||||
ButtonsLSB,
|
ButtonsLSB,
|
||||||
ButtonsMSB,
|
ButtonsMSB,
|
||||||
|
|
|
@ -120,6 +120,18 @@ bool NeGcon::Transfer(const u8 data_in, u8* data_out)
|
||||||
switch (m_transfer_state)
|
switch (m_transfer_state)
|
||||||
{
|
{
|
||||||
case TransferState::Idle:
|
case TransferState::Idle:
|
||||||
|
{
|
||||||
|
*data_out = 0xFF;
|
||||||
|
|
||||||
|
if (data_in == 0x01)
|
||||||
|
{
|
||||||
|
m_transfer_state = TransferState::Ready;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransferState::Ready:
|
||||||
{
|
{
|
||||||
if (data_in == 0x42)
|
if (data_in == 0x42)
|
||||||
{
|
{
|
||||||
|
@ -127,11 +139,9 @@ bool NeGcon::Transfer(const u8 data_in, u8* data_out)
|
||||||
m_transfer_state = TransferState::IDMSB;
|
m_transfer_state = TransferState::IDMSB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
*data_out = 0xFF;
|
||||||
*data_out = 0xFF;
|
return false;
|
||||||
return (data_in == 0x01);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TransferState::IDMSB:
|
case TransferState::IDMSB:
|
||||||
|
|
|
@ -66,6 +66,7 @@ private:
|
||||||
enum class TransferState : u8
|
enum class TransferState : u8
|
||||||
{
|
{
|
||||||
Idle,
|
Idle,
|
||||||
|
Ready,
|
||||||
IDMSB,
|
IDMSB,
|
||||||
ButtonsLSB,
|
ButtonsLSB,
|
||||||
ButtonsMSB,
|
ButtonsMSB,
|
||||||
|
@ -75,7 +76,7 @@ private:
|
||||||
AnalogL
|
AnalogL
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state {};
|
std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state{};
|
||||||
|
|
||||||
// buttons are active low; bits 0-2, 8-10, 14-15 are not used and are always high
|
// buttons are active low; bits 0-2, 8-10, 14-15 are not used and are always high
|
||||||
u16 m_button_state = UINT16_C(0xFFFF);
|
u16 m_button_state = UINT16_C(0xFFFF);
|
||||||
|
|
|
@ -91,18 +91,27 @@ bool PlayStationMouse::Transfer(const u8 data_in, u8* data_out)
|
||||||
{
|
{
|
||||||
case TransferState::Idle:
|
case TransferState::Idle:
|
||||||
{
|
{
|
||||||
// ack when sent 0x01, send ID for 0x42
|
*data_out = 0xFF;
|
||||||
|
|
||||||
|
if (data_in == 0x01)
|
||||||
|
{
|
||||||
|
m_transfer_state = TransferState::Ready;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TransferState::Ready:
|
||||||
|
{
|
||||||
if (data_in == 0x42)
|
if (data_in == 0x42)
|
||||||
{
|
{
|
||||||
*data_out = Truncate8(ID);
|
*data_out = Truncate8(ID);
|
||||||
m_transfer_state = TransferState::IDMSB;
|
m_transfer_state = TransferState::IDMSB;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
*data_out = 0xFF;
|
||||||
*data_out = 0xFF;
|
return false;
|
||||||
return (data_in == 0x01);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case TransferState::IDMSB:
|
case TransferState::IDMSB:
|
||||||
|
|
|
@ -49,6 +49,7 @@ private:
|
||||||
enum class TransferState : u8
|
enum class TransferState : u8
|
||||||
{
|
{
|
||||||
Idle,
|
Idle,
|
||||||
|
Ready,
|
||||||
IDMSB,
|
IDMSB,
|
||||||
ButtonsLSB,
|
ButtonsLSB,
|
||||||
ButtonsMSB,
|
ButtonsMSB,
|
||||||
|
|
Loading…
Reference in a new issue