analog_joystick.h (2381B)
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 AnalogJoystick final : public Controller 13 { 14 public: 15 enum class Axis : u8 16 { 17 LeftX, 18 LeftY, 19 RightX, 20 RightY, 21 Count 22 }; 23 24 enum class Button : u8 25 { 26 Select = 0, 27 L3 = 1, 28 R3 = 2, 29 Start = 3, 30 Up = 4, 31 Right = 5, 32 Down = 6, 33 Left = 7, 34 L2 = 8, 35 R2 = 9, 36 L1 = 10, 37 R1 = 11, 38 Triangle = 12, 39 Circle = 13, 40 Cross = 14, 41 Square = 15, 42 Mode = 16, 43 Count 44 }; 45 46 enum class HalfAxis : u8 47 { 48 LLeft, 49 LRight, 50 LDown, 51 LUp, 52 RLeft, 53 RRight, 54 RDown, 55 RUp, 56 Count 57 }; 58 59 static const Controller::ControllerInfo INFO; 60 61 AnalogJoystick(u32 index); 62 ~AnalogJoystick() override; 63 64 static std::unique_ptr<AnalogJoystick> Create(u32 index); 65 66 ControllerType GetType() const override; 67 bool InAnalogMode() const override; 68 69 void Reset() override; 70 bool DoState(StateWrapper& sw, bool apply_input_state) override; 71 72 float GetBindState(u32 index) const override; 73 void SetBindState(u32 index, float value) override; 74 u32 GetButtonStateBits() const override; 75 std::optional<u32> GetAnalogInputBytes() const override; 76 77 void ResetTransferState() override; 78 bool Transfer(const u8 data_in, u8* data_out) override; 79 80 void LoadSettings(SettingsInterface& si, const char* section, bool initial) override; 81 82 private: 83 enum class TransferState : u8 84 { 85 Idle, 86 Ready, 87 IDMSB, 88 ButtonsLSB, 89 ButtonsMSB, 90 RightAxisX, 91 RightAxisY, 92 LeftAxisX, 93 LeftAxisY 94 }; 95 96 u16 GetID() const; 97 void ToggleAnalogMode(); 98 99 float m_analog_deadzone = 0.0f; 100 float m_analog_sensitivity = 1.33f; 101 u8 m_invert_left_stick = 0; 102 u8 m_invert_right_stick = 0; 103 104 // On original hardware, the mode toggle is a switch rather than a button, so we'll enable Analog Mode by default 105 bool m_analog_mode = true; 106 107 // buttons are active low 108 u16 m_button_state = UINT16_C(0xFFFF); 109 110 std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state{}; 111 112 // both directions of axis state, merged to m_axis_state 113 std::array<u8, static_cast<u32>(HalfAxis::Count)> m_half_axis_state{}; 114 115 TransferState m_transfer_state = TransferState::Idle; 116 };