From f9d2643d98c3193f607e89b95ac0ad58b4691be2 Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Thu, 12 Nov 2020 23:36:36 -0800 Subject: [PATCH] Controller: Add Analog Joystick support --- src/core/CMakeLists.txt | 2 + src/core/analog_joystick.cpp | 311 ++++++++++++++++++++++++++++++++++ src/core/analog_joystick.h | 100 +++++++++++ src/core/controller.cpp | 22 +++ src/core/core.vcxproj | 2 + src/core/core.vcxproj.filters | 2 + src/core/settings.cpp | 11 +- src/core/types.h | 1 + 8 files changed, 446 insertions(+), 5 deletions(-) create mode 100644 src/core/analog_joystick.cpp create mode 100644 src/core/analog_joystick.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index bc2fc30bc..aaaaaa758 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,6 +1,8 @@ add_library(core analog_controller.cpp analog_controller.h + analog_joystick.cpp + analog_joystick.h bios.cpp bios.h bus.cpp diff --git a/src/core/analog_joystick.cpp b/src/core/analog_joystick.cpp new file mode 100644 index 000000000..ff5fef729 --- /dev/null +++ b/src/core/analog_joystick.cpp @@ -0,0 +1,311 @@ +#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) +{ + if (!Controller::DoState(sw)) + return false; + + const bool old_analog_mode = m_analog_mode; + + sw.Do(&m_analog_mode); + sw.Do(&m_button_state); + sw.Do(&m_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); +} + +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(((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) +{ + m_axis_state[static_cast(axis)] = value; +} + +void AnalogJoystick::SetButtonState(Button button, bool pressed) +{ + if (button == Button::Mode) + { + if (pressed) + ToggleAnalogMode(); + + return; + } + + if (pressed) + m_button_state &= ~(u16(1) << static_cast(button)); + else + m_button_state |= (u16(1) << static_cast(button)); +} + +void AnalogJoystick::SetButtonState(s32 button_code, bool pressed) +{ + if (button_code < 0 || button_code >= static_cast(Button::Count)) + return; + + SetButtonState(static_cast