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_SDL_JOYSTICK_H
22#define LOVE_JOYSTICK_SDL_JOYSTICK_H
23
24// LOVE
25#include "joystick/Joystick.h"
26#include "common/EnumMap.h"
27
28// SDL
29#include <SDL.h>
30
31namespace love
32{
33namespace joystick
34{
35namespace sdl
36{
37
38class Joystick : public love::joystick::Joystick
39{
40public:
41
42 Joystick(int id);
43 Joystick(int id, int joyindex);
44
45 virtual ~Joystick();
46
47 bool open(int deviceindex) override;
48 void close() override;
49
50 bool isConnected() const override;
51
52 const char *getName() const override;
53
54 int getAxisCount() const override;
55 int getButtonCount() const override;
56 int getHatCount() const override;
57
58 float getAxis(int axisindex) const override;
59 std::vector<float> getAxes() const override;
60 Hat getHat(int hatindex) const override;
61
62 bool isDown(const std::vector<int> &buttonlist) const override;
63
64 bool openGamepad(int deviceindex) override;
65 bool isGamepad() const override;
66
67 float getGamepadAxis(GamepadAxis axis) const override;
68 bool isGamepadDown(const std::vector<GamepadButton> &blist) const override;
69
70 JoystickInput getGamepadMapping(const GamepadInput &input) const override;
71 std::string getGamepadMappingString() const override;
72
73 void *getHandle() const override;
74
75 std::string getGUID() const override;
76 int getInstanceID() const override;
77 int getID() const override;
78
79 void getDeviceInfo(int &vendorID, int &productID, int &productVersion) const override;
80
81 bool isVibrationSupported() override;
82 bool setVibration(float left, float right, float duration = -1.0f) override;
83 bool setVibration() override;
84 void getVibration(float &left, float &right) override;
85
86 static bool getConstant(Hat in, Uint8 &out);
87 static bool getConstant(Uint8 in, Hat &out);
88
89 static bool getConstant(SDL_GameControllerAxis in, GamepadAxis &out);
90 static bool getConstant(GamepadAxis in, SDL_GameControllerAxis &out);
91
92 static bool getConstant(SDL_GameControllerButton in, GamepadButton &out);
93 static bool getConstant(GamepadButton in, SDL_GameControllerButton &out);
94
95private:
96
97 Joystick() {}
98
99 bool checkCreateHaptic();
100 bool runVibrationEffect();
101
102 SDL_Joystick *joyhandle;
103 SDL_GameController *controller;
104 SDL_Haptic *haptic;
105
106 SDL_JoystickID instanceid;
107 std::string pguid;
108 int id;
109
110 std::string name;
111
112 struct Vibration
113 {
114 float left = 0.0f;
115 float right = 0.0f;
116 SDL_HapticEffect effect;
117 Uint16 data[4];
118 int id = -1;
119 Uint32 endtime = SDL_HAPTIC_INFINITY;
120
121 // Old versions of VS2013 have trouble with initializing these in-line.
122 Vibration()
123 : effect()
124 , data()
125 {}
126
127 } vibration;
128
129 static EnumMap<Hat, Uint8, Joystick::HAT_MAX_ENUM>::Entry hatEntries[];
130 static EnumMap<Hat, Uint8, Joystick::HAT_MAX_ENUM> hats;
131
132 static EnumMap<GamepadAxis, SDL_GameControllerAxis, GAMEPAD_AXIS_MAX_ENUM>::Entry gpAxisEntries[];
133 static EnumMap<GamepadAxis, SDL_GameControllerAxis, GAMEPAD_AXIS_MAX_ENUM> gpAxes;
134
135 static EnumMap<GamepadButton, SDL_GameControllerButton, GAMEPAD_BUTTON_MAX_ENUM>::Entry gpButtonEntries[];
136 static EnumMap<GamepadButton, SDL_GameControllerButton, GAMEPAD_BUTTON_MAX_ENUM> gpButtons;
137
138};
139
140} // sdl
141} // joystick
142} // love
143
144#endif // LOVE_JOYSTICK_SDL_JOYSTICK_H
145