#include "analog_joystick.h" #include "common/log.h" #include "common/state_wrapper.h" #include "common/string_util.h" #include "host_interface.h" #include "system.h" #include Log_SetChannel(AnalogJoystick); AnalogJoystick::AnalogJoystick(u32 index) { m_index = index; m_axis_state.fill(0x80); Reset(); } AnalogJoystick::~AnalogJoystick() = default; ControllerType AnalogJoystick::GetType() const { return ControllerType::AnalogJoystick; } void AnalogJoystick::Reset() { m_transfer_state = TransferState::Idle; } bool AnalogJoystick::DoState(StateWrapper& sw, bool apply_input_state) { if (!Controller::DoState(sw, apply_input_state)) return false; const bool old_analog_mode = m_analog_mode; sw.Do(&m_analog_mode); u16 button_state = m_button_state; auto axis_state = m_axis_state; sw.Do(&button_state); sw.Do(&axis_state); if (apply_input_state) { m_button_state = button_state; m_axis_state = axis_state; } sw.Do(&m_transfer_state); if (sw.IsReading() && (old_analog_mode != m_analog_mode)) { g_host_interface->AddFormattedOSDMessage( 5.0f, m_analog_mode ? g_host_interface->TranslateString("AnalogJoystick", "Controller %u switched to analog mode.") : g_host_interface->TranslateString("AnalogJoystick", "Controller %u switched to digital mode."), m_index + 1u); } return true; } std::optional AnalogJoystick::GetAxisCodeByName(std::string_view axis_name) const { return StaticGetAxisCodeByName(axis_name); } std::optional AnalogJoystick::GetButtonCodeByName(std::string_view button_name) const { return StaticGetButtonCodeByName(button_name); } float AnalogJoystick::GetAxisState(s32 axis_code) const { if (axis_code < 0 || axis_code >= static_cast(Axis::Count)) return 0.0f; // 0..255 -> -1..1 const float value = (((static_cast(m_axis_state[static_cast(axis_code)]) / 255.0f) * 2.0f) - 1.0f); return std::clamp(value / m_axis_scale, -1.0f, 1.0f); } void AnalogJoystick::SetAxisState(s32 axis_code, float value) { if (axis_code < 0 || axis_code >= static_cast(Axis::Count)) return; // -1..1 -> 0..255 const float scaled_value = std::clamp(value * m_axis_scale, -1.0f, 1.0f); const u8 u8_value = static_cast(std::clamp(std::round(((scaled_value + 1.0f) / 2.0f) * 255.0f), 0.0f, 255.0f)); SetAxisState(static_cast(axis_code), u8_value); } void AnalogJoystick::SetAxisState(Axis axis, u8 value) { if (m_axis_state[static_cast(axis)] != value) System::SetRunaheadReplayFlag(); m_axis_state[static_cast(axis)] = value; } bool AnalogJoystick::GetButtonState(s32 button_code) const { if (button_code < 0 || button_code >= static_cast(Button::Count)) return false; const u16 bit = u16(1) << static_cast(button_code); return ((m_button_state & bit) == 0); } void AnalogJoystick::SetButtonState(Button button, bool pressed) { if (button == Button::Mode) { if (pressed) ToggleAnalogMode(); return; } const u16 bit = u16(1) << static_cast(button); if (pressed) { if (m_button_state & bit) System::SetRunaheadReplayFlag(); m_button_state &= ~bit; } else { if (!(m_button_state & bit)) System::SetRunaheadReplayFlag(); m_button_state |= bit; } } void AnalogJoystick::SetButtonState(s32 button_code, bool pressed) { if (button_code < 0 || button_code >= static_cast(Button::Count)) return; SetButtonState(static_cast