Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/core/controller.h
4214 views
1
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: 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 <array>
11
#include <memory>
12
#include <optional>
13
#include <span>
14
#include <string>
15
#include <string_view>
16
#include <tuple>
17
#include <vector>
18
19
class SettingsInterface;
20
class StateWrapper;
21
22
class Controller
23
{
24
public:
25
struct ControllerBindingInfo
26
{
27
const char* name;
28
const char* display_name;
29
const char* icon_name;
30
u32 bind_index;
31
InputBindingInfo::Type type;
32
GenericInputBinding generic_mapping;
33
};
34
35
struct ControllerInfo
36
{
37
ControllerType type;
38
const char* name;
39
const char* display_name;
40
const char* icon_name;
41
std::span<const ControllerBindingInfo> bindings;
42
std::span<const SettingInfo> settings;
43
44
/// Returns localized controller type name.
45
std::string_view GetDisplayName() const;
46
47
/// Returns localized controller type name.
48
std::string_view GetBindingDisplayName(const ControllerBindingInfo& bi) const;
49
};
50
51
/// Default stick deadzone/sensitivity.
52
static constexpr float DEFAULT_STICK_DEADZONE = 0.0f;
53
static constexpr float DEFAULT_STICK_SENSITIVITY = 1.33f;
54
static constexpr float DEFAULT_BUTTON_DEADZONE = 0.25f;
55
56
explicit Controller(u32 index);
57
virtual ~Controller();
58
59
/// Returns the type of controller.
60
virtual ControllerType GetType() const = 0;
61
62
virtual void Reset();
63
virtual bool DoState(StateWrapper& sw, bool apply_input_state);
64
65
// Resets all state for the transferring to/from the device.
66
virtual void ResetTransferState();
67
68
// Returns the value of ACK, as well as filling out_data.
69
virtual bool Transfer(const u8 data_in, u8* data_out);
70
71
/// Changes the specified axis state. Values are normalized from -1..1.
72
virtual float GetBindState(u32 index) const;
73
74
/// Changes the specified bind state. Values are normalized from -1..1.
75
virtual void SetBindState(u32 index, float value);
76
77
/// Returns a bitmask of the current button states, 1 = on.
78
virtual u32 GetButtonStateBits() const;
79
80
/// Returns the current state of the specified vibration motor.
81
virtual float GetVibrationMotorState(u32 index) const;
82
83
/// Returns true if the controller supports analog mode, and it is active.
84
virtual bool InAnalogMode() const;
85
86
/// Returns analog input bytes packed as a u32. Values are specific to controller type.
87
virtual std::optional<u32> GetAnalogInputBytes() const;
88
89
/// Returns the colour to use in the input overlay.
90
virtual u32 GetInputOverlayIconColor() const;
91
92
/// Loads/refreshes any per-controller settings.
93
virtual void LoadSettings(const SettingsInterface& si, const char* section, bool initial);
94
95
/// Creates a new controller of the specified type.
96
static std::unique_ptr<Controller> Create(ControllerType type, u32 index);
97
98
/// Returns a list of all controller types.
99
static const std::array<const ControllerInfo*, static_cast<size_t>(ControllerType::Count)>& GetControllerInfoList();
100
101
/// Returns general information for the specified controller type.
102
static const ControllerInfo& GetControllerInfo(ControllerType type);
103
static const ControllerInfo* GetControllerInfo(std::string_view name);
104
105
/// Applies an analog deadzone/sensitivity.
106
static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value)
107
{
108
return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity);
109
}
110
111
/// Returns true if the specified coordinates are inside a circular deadzone.
112
static bool InCircularDeadzone(float deadzone, float pos_x, float pos_y);
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
/// Returns a printable label for a given port.
128
static const char* GetPortDisplayName(u32 port, u32 slot, bool mtap);
129
static const char* GetPortDisplayName(u32 index);
130
131
/// List of controller indices in the order that they should be displayed.
132
static const std::array<u32, NUM_CONTROLLER_AND_CARD_PORTS> PortDisplayOrder;
133
134
/// Returns true if automatic analog mode can be used.
135
static bool CanStartInAnalogMode(ControllerType ctype);
136
137
protected:
138
u32 m_index;
139
};
140
141