AnalogController: Simulate status byte toggling

This commit is contained in:
Albert Liu 2021-04-14 01:13:34 -07:00
parent ab496ef8fe
commit 3273ca36ef
3 changed files with 28 additions and 23 deletions

View file

@ -31,9 +31,11 @@ void AnalogController::Reset()
m_configuration_mode = false; m_configuration_mode = false;
m_motor_state.fill(0); m_motor_state.fill(0);
m_rumble_unlocked = false; m_dualshock_enabled = false;
ResetRumbleConfig(); ResetRumbleConfig();
m_status_byte = 0x5A;
if (m_force_analog_on_reset) if (m_force_analog_on_reset)
{ {
if (g_settings.controller_disable_analog_mode_forcing) if (g_settings.controller_disable_analog_mode_forcing)
@ -56,10 +58,11 @@ bool AnalogController::DoState(StateWrapper& sw, bool apply_input_state)
const bool old_analog_mode = m_analog_mode; const bool old_analog_mode = m_analog_mode;
sw.Do(&m_analog_mode); sw.Do(&m_analog_mode);
sw.Do(&m_rumble_unlocked); sw.Do(&m_dualshock_enabled);
sw.DoEx(&m_legacy_rumble_unlocked, 44, false); sw.DoEx(&m_legacy_rumble_unlocked, 44, false);
sw.Do(&m_configuration_mode); sw.Do(&m_configuration_mode);
sw.Do(&m_command_param); sw.Do(&m_command_param);
sw.DoEx(&m_status_byte, 55, static_cast<u8>(0x5A));
u16 button_state = m_button_state; u16 button_state = m_button_state;
sw.DoEx(&button_state, 44, static_cast<u16>(0xFFFF)); sw.DoEx(&button_state, 44, static_cast<u16>(0xFFFF));
@ -261,7 +264,8 @@ void AnalogController::ProcessAnalogModeToggle()
SetAnalogMode(!m_analog_mode); SetAnalogMode(!m_analog_mode);
ResetRumbleConfig(); ResetRumbleConfig();
// TODO: Mode switch detection (0x00 returned on certain commands instead of 0x5A) if (m_dualshock_enabled)
m_status_byte = 0x00;
} }
} }
@ -363,21 +367,21 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::ReadPad; m_command = Command::ReadPad;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
} }
else if (data_in == 0x43) else if (data_in == 0x43)
{ {
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::ConfigModeSetMode; m_command = Command::ConfigModeSetMode;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
} }
else if (m_configuration_mode && data_in == 0x44) else if (m_configuration_mode && data_in == 0x44)
{ {
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::SetAnalogMode; m_command = Command::SetAnalogMode;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ResetRumbleConfig(); ResetRumbleConfig();
} }
@ -386,35 +390,35 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::GetAnalogMode; m_command = Command::GetAnalogMode;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x01, 0x02, BoolToUInt8(m_analog_mode), 0x02, 0x01, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x01, 0x02, BoolToUInt8(m_analog_mode), 0x02, 0x01, 0x00};
} }
else if (m_configuration_mode && data_in == 0x46) else if (m_configuration_mode && data_in == 0x46)
{ {
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::Command46; m_command = Command::Command46;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
} }
else if (m_configuration_mode && data_in == 0x47) else if (m_configuration_mode && data_in == 0x47)
{ {
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::Command47; m_command = Command::Command47;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00};
} }
else if (m_configuration_mode && data_in == 0x4C) else if (m_configuration_mode && data_in == 0x4C)
{ {
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::Command4C; m_command = Command::Command4C;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
} }
else if (m_configuration_mode && data_in == 0x4D) else if (m_configuration_mode && data_in == 0x4D)
{ {
Assert(m_command_step == 0); Assert(m_command_step == 0);
m_response_length = (GetResponseNumHalfwords() + 1) * 2; m_response_length = (GetResponseNumHalfwords() + 1) * 2;
m_command = Command::GetSetRumble; m_command = Command::GetSetRumble;
m_tx_buffer = {GetIDByte(), GetStatusByte(), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; m_tx_buffer = {GetIDByte(), m_status_byte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
m_rumble_config_large_motor_index = -1; m_rumble_config_large_motor_index = -1;
m_rumble_config_small_motor_index = -1; m_rumble_config_small_motor_index = -1;
@ -440,7 +444,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
{ {
m_tx_buffer[m_command_step] = Truncate8(m_button_state) & GetExtraButtonMaskLSB(); m_tx_buffer[m_command_step] = Truncate8(m_button_state) & GetExtraButtonMaskLSB();
if (m_rumble_unlocked) if (m_dualshock_enabled)
SetMotorStateForConfigIndex(rumble_index, data_in); SetMotorStateForConfigIndex(rumble_index, data_in);
} }
break; break;
@ -449,7 +453,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
{ {
m_tx_buffer[m_command_step] = Truncate8(m_button_state >> 8); m_tx_buffer[m_command_step] = Truncate8(m_button_state >> 8);
if (m_rumble_unlocked) if (m_dualshock_enabled)
{ {
SetMotorStateForConfigIndex(rumble_index, data_in); SetMotorStateForConfigIndex(rumble_index, data_in);
} }
@ -466,7 +470,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
if (m_configuration_mode || m_analog_mode) if (m_configuration_mode || m_analog_mode)
m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::RightX)]; m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::RightX)];
if (m_rumble_unlocked) if (m_dualshock_enabled)
SetMotorStateForConfigIndex(rumble_index, data_in); SetMotorStateForConfigIndex(rumble_index, data_in);
} }
break; break;
@ -476,7 +480,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
if (m_configuration_mode || m_analog_mode) if (m_configuration_mode || m_analog_mode)
m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::RightY)]; m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::RightY)];
if (m_rumble_unlocked) if (m_dualshock_enabled)
SetMotorStateForConfigIndex(rumble_index, data_in); SetMotorStateForConfigIndex(rumble_index, data_in);
} }
break; break;
@ -486,7 +490,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
if (m_configuration_mode || m_analog_mode) if (m_configuration_mode || m_analog_mode)
m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::LeftX)]; m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::LeftX)];
if (m_rumble_unlocked) if (m_dualshock_enabled)
SetMotorStateForConfigIndex(rumble_index, data_in); SetMotorStateForConfigIndex(rumble_index, data_in);
} }
break; break;
@ -496,7 +500,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
if (m_configuration_mode || m_analog_mode) if (m_configuration_mode || m_analog_mode)
m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::LeftY)]; m_tx_buffer[m_command_step] = m_axis_state[static_cast<u8>(Axis::LeftY)];
if (m_rumble_unlocked) if (m_dualshock_enabled)
SetMotorStateForConfigIndex(rumble_index, data_in); SetMotorStateForConfigIndex(rumble_index, data_in);
} }
break; break;
@ -567,7 +571,10 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
m_configuration_mode = (m_rx_buffer[2] == 1); m_configuration_mode = (m_rx_buffer[2] == 1);
if (m_configuration_mode) if (m_configuration_mode)
m_rumble_unlocked = true; {
m_dualshock_enabled = true;
m_status_byte = 0x5A;
}
Log_DevPrintf("0x%02x(%s) config mode", m_rx_buffer[2], m_configuration_mode ? "enter" : "leave"); Log_DevPrintf("0x%02x(%s) config mode", m_rx_buffer[2], m_configuration_mode ? "enter" : "leave");
} }

View file

@ -109,9 +109,6 @@ private:
u8 GetModeID() const; u8 GetModeID() const;
u8 GetIDByte() const; u8 GetIDByte() const;
// TODO: Return 0x00 on manual toggles
constexpr u8 GetStatusByte() const { return 0x5A; };
void SetAnalogMode(bool enabled); void SetAnalogMode(bool enabled);
void ProcessAnalogModeToggle(); void ProcessAnalogModeToggle();
void SetMotorState(u8 motor, u8 value); void SetMotorState(u8 motor, u8 value);
@ -128,7 +125,7 @@ private:
bool m_analog_mode = false; bool m_analog_mode = false;
bool m_analog_locked = false; bool m_analog_locked = false;
bool m_rumble_unlocked = false; bool m_dualshock_enabled = false;
bool m_configuration_mode = false; bool m_configuration_mode = false;
std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state{}; std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state{};
@ -144,6 +141,7 @@ private:
int m_rumble_config_small_motor_index = -1; int m_rumble_config_small_motor_index = -1;
bool m_analog_toggle_queued = false; bool m_analog_toggle_queued = false;
u8 m_status_byte = 0x5A;
// TODO: Set this with command 0x4D and increase response length in digital mode accordingly // TODO: Set this with command 0x4D and increase response length in digital mode accordingly
u8 m_digital_mode_extra_halfwords = 0; u8 m_digital_mode_extra_halfwords = 0;

View file

@ -2,7 +2,7 @@
#include "types.h" #include "types.h"
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544; static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
static constexpr u32 SAVE_STATE_VERSION = 54; static constexpr u32 SAVE_STATE_VERSION = 55;
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42; static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION); static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION);