controller.h (4517B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "input_types.h" 7 #include "settings.h" 8 #include "types.h" 9 10 #include <memory> 11 #include <optional> 12 #include <span> 13 #include <string> 14 #include <string_view> 15 #include <tuple> 16 #include <vector> 17 18 class SettingsInterface; 19 class StateWrapper; 20 class HostInterface; 21 22 class Controller 23 { 24 public: 25 enum class VibrationCapabilities : u8 26 { 27 NoVibration, 28 LargeSmallMotors, 29 SingleMotor, 30 Count 31 }; 32 33 struct ControllerBindingInfo 34 { 35 const char* name; 36 const char* display_name; 37 const char* icon_name; 38 u32 bind_index; 39 InputBindingInfo::Type type; 40 GenericInputBinding generic_mapping; 41 }; 42 43 struct ControllerInfo 44 { 45 ControllerType type; 46 const char* name; 47 const char* display_name; 48 const char* icon_name; 49 std::span<const ControllerBindingInfo> bindings; 50 std::span<const SettingInfo> settings; 51 VibrationCapabilities vibration_caps; 52 53 /// Returns localized controller type name. 54 const char* GetDisplayName() const; 55 }; 56 57 /// Default stick deadzone/sensitivity. 58 static constexpr float DEFAULT_STICK_DEADZONE = 0.0f; 59 static constexpr float DEFAULT_STICK_SENSITIVITY = 1.33f; 60 static constexpr float DEFAULT_BUTTON_DEADZONE = 0.25f; 61 62 Controller(u32 index); 63 virtual ~Controller(); 64 65 /// Returns the type of controller. 66 virtual ControllerType GetType() const = 0; 67 68 virtual void Reset(); 69 virtual bool DoState(StateWrapper& sw, bool apply_input_state); 70 71 // Resets all state for the transferring to/from the device. 72 virtual void ResetTransferState(); 73 74 // Returns the value of ACK, as well as filling out_data. 75 virtual bool Transfer(const u8 data_in, u8* data_out); 76 77 /// Changes the specified axis state. Values are normalized from -1..1. 78 virtual float GetBindState(u32 index) const; 79 80 /// Changes the specified bind state. Values are normalized from -1..1. 81 virtual void SetBindState(u32 index, float value); 82 83 /// Returns a bitmask of the current button states, 1 = on. 84 virtual u32 GetButtonStateBits() const; 85 86 /// Returns true if the controller supports analog mode, and it is active. 87 virtual bool InAnalogMode() const; 88 89 /// Returns analog input bytes packed as a u32. Values are specific to controller type. 90 virtual std::optional<u32> GetAnalogInputBytes() const; 91 92 /// Returns the colour to use in the input overlay. 93 virtual u32 GetInputOverlayIconColor() const; 94 95 /// Loads/refreshes any per-controller settings. 96 virtual void LoadSettings(SettingsInterface& si, const char* section, bool initial); 97 98 /// Creates a new controller of the specified type. 99 static std::unique_ptr<Controller> Create(ControllerType type, u32 index); 100 101 /// Returns the default type for the specified port. 102 static const char* GetDefaultPadType(u32 pad); 103 104 /// Returns a list of controller type names. Pair of [name, display name]. 105 static std::vector<std::pair<std::string, std::string>> GetControllerTypeNames(); 106 107 /// Gets the integer code for an axis in the specified controller type. 108 static std::optional<u32> GetBindIndex(ControllerType type, std::string_view bind_name); 109 110 /// Returns general information for the specified controller type. 111 static const ControllerInfo* GetControllerInfo(ControllerType type); 112 static const ControllerInfo* GetControllerInfo(std::string_view name); 113 114 /// Converts a global pad index to a multitap port and slot. 115 static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index); 116 117 /// Converts a multitap port and slot to a global pad index. 118 static u32 ConvertPortAndSlotToPad(u32 port, u32 slot); 119 120 /// Returns true if the given pad index is a multitap slot. 121 static bool PadIsMultitapSlot(u32 index); 122 static bool PortAndSlotIsMultitap(u32 port, u32 slot); 123 124 /// Returns the configuration section for the specified gamepad. 125 static std::string GetSettingsSection(u32 pad); 126 127 /// Applies an analog deadzone/sensitivity. 128 static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value) 129 { 130 return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity); 131 } 132 133 /// Returns true if the specified coordinates are inside a circular deadzone. 134 static bool InCircularDeadzone(float deadzone, float pos_x, float pos_y); 135 136 protected: 137 /// Returns true if automatic analog mode can be used. 138 static bool CanStartInAnalogMode(ControllerType ctype); 139 140 u32 m_index; 141 };