diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c770f5f21..d044e9650 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -54,6 +54,8 @@ add_library(core memory_card.h namco_guncon.cpp namco_guncon.h + negcon.cpp + negcon.h pad.cpp pad.h playstation_mouse.cpp diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 12e147fcd..9c38cc864 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -4,6 +4,7 @@ #include "digital_controller.h" #include "namco_guncon.h" #include "playstation_mouse.h" +#include "negcon.h" Controller::Controller() = default; @@ -54,6 +55,9 @@ std::unique_ptr Controller::Create(System* system, ControllerType ty case ControllerType::PlayStationMouse: return PlayStationMouse::Create(system); + case ControllerType::NeGcon: + return NeGcon::Create(); + case ControllerType::None: default: return {}; @@ -86,6 +90,9 @@ Controller::AxisList Controller::GetAxisNames(ControllerType type) case ControllerType::PlayStationMouse: return PlayStationMouse::StaticGetAxisNames(); + case ControllerType::NeGcon: + return NeGcon::StaticGetAxisNames(); + case ControllerType::None: default: return {}; @@ -108,6 +115,9 @@ Controller::ButtonList Controller::GetButtonNames(ControllerType type) case ControllerType::PlayStationMouse: return PlayStationMouse::StaticGetButtonNames(); + case ControllerType::NeGcon: + return NeGcon::StaticGetButtonNames(); + case ControllerType::None: default: return {}; @@ -130,6 +140,9 @@ u32 Controller::GetVibrationMotorCount(ControllerType type) case ControllerType::PlayStationMouse: return PlayStationMouse::StaticGetVibrationMotorCount(); + case ControllerType::NeGcon: + return NeGcon::StaticGetVibrationMotorCount(); + case ControllerType::None: default: return 0; @@ -152,6 +165,9 @@ std::optional Controller::GetAxisCodeByName(ControllerType type, std::strin case ControllerType::PlayStationMouse: return PlayStationMouse::StaticGetAxisCodeByName(axis_name); + case ControllerType::NeGcon: + return NeGcon::StaticGetAxisCodeByName(axis_name); + case ControllerType::None: default: return std::nullopt; @@ -174,6 +190,9 @@ std::optional Controller::GetButtonCodeByName(ControllerType type, std::str case ControllerType::PlayStationMouse: return PlayStationMouse::StaticGetButtonCodeByName(button_name); + case ControllerType::NeGcon: + return NeGcon::StaticGetButtonCodeByName(button_name); + case ControllerType::None: default: return std::nullopt; diff --git a/src/core/negcon.cpp b/src/core/negcon.cpp new file mode 100644 index 000000000..85d235c41 --- /dev/null +++ b/src/core/negcon.cpp @@ -0,0 +1,246 @@ +#include "negcon.h" +#include "common/assert.h" +#include "common/log.h" +#include "common/state_wrapper.h" +#include +#include + +NeGcon::NeGcon() +{ + m_axis_state.fill(0x00); + m_axis_state[static_cast(Axis::Steering)] = 0x80; +} + +NeGcon::~NeGcon() = default; + +ControllerType NeGcon::GetType() const +{ + return ControllerType::NeGcon; +} + +std::optional NeGcon::GetAxisCodeByName(std::string_view axis_name) const +{ + return StaticGetAxisCodeByName(axis_name); +} + +std::optional NeGcon::GetButtonCodeByName(std::string_view button_name) const +{ + return StaticGetButtonCodeByName(button_name); +} + +void NeGcon::Reset() +{ + m_transfer_state = TransferState::Idle; +} + +bool NeGcon::DoState(StateWrapper& sw) +{ + if (!Controller::DoState(sw)) + return false; + + sw.Do(&m_button_state); + sw.Do(&m_transfer_state); + return true; +} + +void NeGcon::SetAxisState(s32 axis_code, float value) +{ + if (axis_code < 0 || axis_code >= static_cast(Axis::Count)) + return; + + // Steering Axis: -1..1 -> 0..255 + if (axis_code == static_cast(Axis::Steering)) + { + 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); + + return; + } + + // I, II, L: 0..1 -> 0..255 or -1..0 -> 0..255 to support negative axis ranges, + // e.g. if bound to analog stick instead of trigger + const u8 u8_value = static_cast(std::clamp(std::abs(value) * 255.0f, 0.0f, 255.0f)); + + SetAxisState(static_cast(axis_code), u8_value); +} + +void NeGcon::SetAxisState(Axis axis, u8 value) +{ + m_axis_state[static_cast(axis)] = value; +} + +void NeGcon::SetButtonState(s32 button_code, bool pressed) +{ + if (button_code < 0 || button_code >= static_cast(Button::Count)) + return; + + SetButtonState(static_cast