negcon.h (3151B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> and contributors. 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "controller.h" 7 8 #include <array> 9 #include <memory> 10 #include <optional> 11 12 class NeGcon final : public Controller 13 { 14 public: 15 enum class Axis : u8 16 { 17 Steering = 0, 18 I = 1, 19 II = 2, 20 L = 3, 21 Count 22 }; 23 24 enum class Button : u8 25 { 26 Start = 0, 27 Up = 1, 28 Right = 2, 29 Down = 3, 30 Left = 4, 31 R = 5, 32 B = 6, 33 A = 7, 34 Count 35 }; 36 37 enum class HalfAxis : u8 38 { 39 SteeringLeft, 40 SteeringRight, 41 I, 42 II, 43 L, 44 Count 45 }; 46 47 struct AxisModifier 48 { 49 float deadzone; 50 float saturation; 51 float linearity; 52 float scaling; 53 float zero; 54 float unit; 55 }; 56 57 static constexpr float DEFAULT_DEADZONE = 0.00f; 58 static constexpr float DEFAULT_SATURATION = 1.00f; 59 static constexpr float DEFAULT_LINEARITY = 0.00f; 60 static constexpr float DEFAULT_SCALING = 1.00f; 61 static constexpr float DEFAULT_STEERING_ZERO = 128.0f; 62 static constexpr float DEFAULT_STEERING_UNIT = 128.0f; 63 static constexpr float DEFAULT_PEDAL_ZERO = 0.0f; 64 static constexpr float DEFAULT_PEDAL_UNIT = 255.0f; 65 static constexpr AxisModifier DEFAULT_STEERING_MODIFIER = { 66 .deadzone = DEFAULT_DEADZONE, 67 .saturation = DEFAULT_SATURATION, 68 .linearity = DEFAULT_LINEARITY, 69 .scaling = DEFAULT_SCALING, 70 .zero = DEFAULT_STEERING_ZERO, 71 .unit = DEFAULT_STEERING_UNIT, 72 }; 73 static constexpr AxisModifier DEFAULT_PEDAL_MODIFIER = { 74 .deadzone = DEFAULT_DEADZONE, 75 .saturation = DEFAULT_SATURATION, 76 .linearity = DEFAULT_LINEARITY, 77 .scaling = DEFAULT_SCALING, 78 .zero = DEFAULT_PEDAL_ZERO, 79 .unit = DEFAULT_PEDAL_UNIT, 80 }; 81 82 static const Controller::ControllerInfo INFO; 83 84 NeGcon(u32 index); 85 ~NeGcon() override; 86 87 static std::unique_ptr<NeGcon> Create(u32 index); 88 89 ControllerType GetType() const override; 90 91 void Reset() override; 92 bool DoState(StateWrapper& sw, bool apply_input_state) override; 93 94 float GetBindState(u32 index) const override; 95 void SetBindState(u32 index, float value) override; 96 97 void ResetTransferState() override; 98 bool Transfer(const u8 data_in, u8* data_out) override; 99 100 u32 GetButtonStateBits() const override; 101 std::optional<u32> GetAnalogInputBytes() const override; 102 103 void LoadSettings(SettingsInterface& si, const char* section, bool initial) override; 104 105 private: 106 enum class TransferState : u8 107 { 108 Idle, 109 Ready, 110 IDMSB, 111 ButtonsLSB, 112 ButtonsMSB, 113 AnalogSteering, 114 AnalogI, 115 AnalogII, 116 AnalogL 117 }; 118 119 std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state{}; 120 121 // steering, merged to m_axis_state 122 std::array<float, 2> m_half_axis_state; 123 124 // buttons are active low; bits 0-2, 8-10, 14-15 are not used and are always high 125 u16 m_button_state = UINT16_C(0xFFFF); 126 127 TransferState m_transfer_state = TransferState::Idle; 128 129 AxisModifier m_steering_modifier = DEFAULT_STEERING_MODIFIER; 130 std::array<AxisModifier, 3> m_half_axis_modifiers = { 131 DEFAULT_PEDAL_MODIFIER, 132 DEFAULT_PEDAL_MODIFIER, 133 DEFAULT_PEDAL_MODIFIER, 134 }; 135 };