1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#ifndef LOVE_JOYSTICK_JOYSTICK_H
22#define LOVE_JOYSTICK_JOYSTICK_H
23
24// LOVE
25#include "common/Object.h"
26#include "common/StringMap.h"
27
28// stdlib
29#include <vector>
30#include <string>
31
32namespace love
33{
34namespace joystick
35{
36
37class Joystick : public Object
38{
39public:
40
41 static love::Type type;
42
43 // Joystick hat values.
44 enum Hat
45 {
46 HAT_INVALID,
47 HAT_CENTERED,
48 HAT_UP,
49 HAT_RIGHT,
50 HAT_DOWN,
51 HAT_LEFT,
52 HAT_RIGHTUP,
53 HAT_RIGHTDOWN,
54 HAT_LEFTUP,
55 HAT_LEFTDOWN,
56 HAT_MAX_ENUM = 16
57 };
58
59 // Valid Gamepad axes.
60 enum GamepadAxis
61 {
62 GAMEPAD_AXIS_INVALID,
63 GAMEPAD_AXIS_LEFTX,
64 GAMEPAD_AXIS_LEFTY,
65 GAMEPAD_AXIS_RIGHTX,
66 GAMEPAD_AXIS_RIGHTY,
67 GAMEPAD_AXIS_TRIGGERLEFT,
68 GAMEPAD_AXIS_TRIGGERRIGHT,
69 GAMEPAD_AXIS_MAX_ENUM
70 };
71
72 // Valid Gamepad buttons.
73 enum GamepadButton
74 {
75 GAMEPAD_BUTTON_INVALID,
76 GAMEPAD_BUTTON_A,
77 GAMEPAD_BUTTON_B,
78 GAMEPAD_BUTTON_X,
79 GAMEPAD_BUTTON_Y,
80 GAMEPAD_BUTTON_BACK,
81 GAMEPAD_BUTTON_GUIDE,
82 GAMEPAD_BUTTON_START,
83 GAMEPAD_BUTTON_LEFTSTICK,
84 GAMEPAD_BUTTON_RIGHTSTICK,
85 GAMEPAD_BUTTON_LEFTSHOULDER,
86 GAMEPAD_BUTTON_RIGHTSHOULDER,
87 GAMEPAD_BUTTON_DPAD_UP,
88 GAMEPAD_BUTTON_DPAD_DOWN,
89 GAMEPAD_BUTTON_DPAD_LEFT,
90 GAMEPAD_BUTTON_DPAD_RIGHT,
91 GAMEPAD_BUTTON_MAX_ENUM
92 };
93
94 // Different types of inputs for a joystick.
95 enum InputType
96 {
97 INPUT_TYPE_AXIS,
98 INPUT_TYPE_BUTTON,
99 INPUT_TYPE_HAT,
100 INPUT_TYPE_MAX_ENUM
101 };
102
103 // Represents a gamepad input value, e.g. the "x" button or the left trigger.
104 struct GamepadInput
105 {
106 InputType type;
107 union
108 {
109 GamepadAxis axis;
110 GamepadButton button;
111 };
112 };
113
114 // Represents a joystick input value, e.g. button 6 or axis 1.
115 struct JoystickInput
116 {
117 InputType type;
118 union
119 {
120 int axis;
121 int button;
122 struct
123 {
124 int index;
125 Hat value;
126 } hat;
127 };
128 };
129
130 virtual ~Joystick() {}
131
132 virtual bool open(int deviceindex) = 0;
133 virtual void close() = 0;
134
135 virtual bool isConnected() const = 0;
136
137 virtual const char *getName() const = 0;
138
139 virtual int getAxisCount() const = 0;
140 virtual int getButtonCount() const = 0;
141 virtual int getHatCount() const = 0;
142
143 virtual float getAxis(int axisindex) const = 0;
144 virtual std::vector<float> getAxes() const = 0;
145 virtual Hat getHat(int hatindex) const = 0;
146
147 virtual bool isDown(const std::vector<int> &buttonlist) const = 0;
148
149 virtual bool openGamepad(int deviceindex) = 0;
150 virtual bool isGamepad() const = 0;
151
152 virtual float getGamepadAxis(GamepadAxis axis) const = 0;
153 virtual bool isGamepadDown(const std::vector<GamepadButton> &blist) const = 0;
154
155 virtual JoystickInput getGamepadMapping(const GamepadInput &input) const = 0;
156 virtual std::string getGamepadMappingString() const = 0;
157
158 virtual void *getHandle() const = 0;
159
160 virtual std::string getGUID() const = 0;
161 virtual int getInstanceID() const = 0;
162 virtual int getID() const = 0;
163
164 virtual void getDeviceInfo(int &vendorID, int &productID, int &productVersion) const = 0;
165
166 virtual bool isVibrationSupported() = 0;
167 virtual bool setVibration(float left, float right, float duration = -1.0f) = 0;
168 virtual bool setVibration() = 0;
169 virtual void getVibration(float &left, float &right) = 0;
170
171 static bool getConstant(const char *in, Hat &out);
172 static bool getConstant(Hat in, const char *&out);
173
174 static bool getConstant(const char *in, GamepadAxis &out);
175 static bool getConstant(GamepadAxis in, const char *&out);
176
177 static bool getConstant(const char *in, GamepadButton &out);
178 static bool getConstant(GamepadButton in, const char *&out);
179
180 static bool getConstant(const char *in, InputType &out);
181 static bool getConstant(InputType in, const char *&out);
182
183 static float clampval(float x);
184
185private:
186
187 static StringMap<Hat, HAT_MAX_ENUM>::Entry hatEntries[];
188 static StringMap<Hat, HAT_MAX_ENUM> hats;
189
190 static StringMap<GamepadAxis, GAMEPAD_AXIS_MAX_ENUM>::Entry gpAxisEntries[];
191 static StringMap<GamepadAxis, GAMEPAD_AXIS_MAX_ENUM> gpAxes;
192
193 static StringMap<GamepadButton, GAMEPAD_BUTTON_MAX_ENUM>::Entry gpButtonEntries[];
194 static StringMap<GamepadButton, GAMEPAD_BUTTON_MAX_ENUM> gpButtons;
195
196 static StringMap<InputType, INPUT_TYPE_MAX_ENUM>::Entry inputTypeEntries[];
197 static StringMap<InputType, INPUT_TYPE_MAX_ENUM> inputTypes;
198
199}; // Joystick
200
201} // joystick
202} // love
203
204
205#endif // LOVE_JOYSTICK_JOYSTICK_H
206