From a347b3606ec12ec1fb9e7d72129c00283dc179eb Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 15 Dec 2019 21:58:27 +1000 Subject: [PATCH] Implement support for analog controllers --- src/core/CMakeLists.txt | 2 + src/core/analog_controller.cpp | 360 +++++++++++++++++++++++++++++++++ src/core/analog_controller.h | 132 ++++++++++++ src/core/controller.cpp | 22 +- src/core/core.vcxproj | 2 + src/core/core.vcxproj.filters | 2 + src/core/settings.cpp | 5 +- src/core/types.h | 1 + 8 files changed, 517 insertions(+), 9 deletions(-) create mode 100644 src/core/analog_controller.cpp create mode 100644 src/core/analog_controller.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4b5050f16..b28c674fa 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,4 +1,6 @@ add_library(core + analog_controller.cpp + analog_controller.h bios.cpp bios.h bus.cpp diff --git a/src/core/analog_controller.cpp b/src/core/analog_controller.cpp new file mode 100644 index 000000000..c631f4148 --- /dev/null +++ b/src/core/analog_controller.cpp @@ -0,0 +1,360 @@ +#include "analog_controller.h" +#include "YBaseLib/Log.h" +#include "common/state_wrapper.h" +Log_SetChannel(AnalogController); + +AnalogController::AnalogController() +{ + m_axis_state.fill(0x80); +} + +AnalogController::~AnalogController() = default; + +ControllerType AnalogController::GetType() const +{ + return ControllerType::AnalogController; +} + +void AnalogController::Reset() +{ + m_analog_mode = false; + m_configuration_mode = false; + m_command_param = 0; +} + +bool AnalogController::DoState(StateWrapper& sw) +{ + if (!Controller::DoState(sw)) + return false; + + sw.Do(&m_analog_mode); + sw.Do(&m_configuration_mode); + sw.Do(&m_command_param); + sw.Do(&m_state); + return true; +} + +std::optional AnalogController::GetAxisCodeByName(std::string_view axis_name) const +{ + return StaticGetAxisCodeByName(axis_name); +} + +std::optional AnalogController::GetButtonCodeByName(std::string_view button_name) const +{ + return StaticGetButtonCodeByName(button_name); +} + +void AnalogController::SetAxisState(s32 axis_code, float value) +{ + if (axis_code < 0 || axis_code >= static_cast(Button::Count)) + return; + + // -1..1 -> 0..255 + const u8 u8_value = static_cast(std::clamp(((value + 1.0f) / 2.0f) * 255.0f, 0.0f, 255.0f)); + + SetAxisState(static_cast(axis_code), u8_value); +} + +void AnalogController::SetAxisState(Axis axis, u8 value) +{ + m_axis_state[static_cast(axis)] = value; + + // TODO: Map to buttons in digital mode +} + +void AnalogController::SetButtonState(Button button, bool pressed) +{ + if (pressed) + m_button_state &= ~(u16(1) << static_cast(button)); + else + m_button_state |= u16(1) << static_cast(button); +} + +void AnalogController::SetButtonState(s32 button_code, bool pressed) +{ + if (button_code < 0 || button_code >= static_cast(Button::Count)) + return; + + SetButtonState(static_cast