1 
2 //          Copyright 2018 - 2021 Michael D. Parker
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 module bindbc.sdl.bind.sdlgamecontroller;
8 
9 import bindbc.sdl.config;
10 
11 import bindbc.sdl.bind.sdljoystick,
12        bindbc.sdl.bind.sdlrwops,
13        bindbc.sdl.bind.sdlsensor;
14 import bindbc.sdl.bind.sdlstdinc : SDL_bool;
15 
16 struct SDL_GameController;
17 
18 static if(sdlSupport >= SDLSupport.sdl2014) {
19     enum SDL_GameControllerType {
20         SDL_CONTROLLER_TYPE_UNKNOWN = 0,
21         SDL_CONTROLLER_TYPE_XBOX360,
22         SDL_CONTROLLER_TYPE_XBOXONE,
23         SDL_CONTROLLER_TYPE_PS3,
24         SDL_CONTROLLER_TYPE_PS4,
25         SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO,
26         SDL_CONTROLLER_TYPE_VIRTUAL,
27         SDL_CONTROLLER_TYPE_PS5
28     }
29     mixin(expandEnum!SDL_GameControllerType);
30 }
31 else static if(sdlSupport >= SDLSupport.sdl2012) {
32     enum SDL_GameControllerType {
33         SDL_CONTROLLER_TYPE_UNKNOWN = 0,
34         SDL_CONTROLLER_TYPE_XBOX360,
35         SDL_CONTROLLER_TYPE_XBOXONE,
36         SDL_CONTROLLER_TYPE_PS3,
37         SDL_CONTROLLER_TYPE_PS4,
38         SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO,
39     }
40     mixin(expandEnum!SDL_GameControllerType);
41 }
42 
43 enum SDL_GameControllerBindType {
44     SDL_CONTROLLER_BINDTYPE_NONE = 0,
45     SDL_CONTROLLER_BINDTYPE_BUTTON,
46     SDL_CONTROLLER_BINDTYPE_AXIS,
47     SDL_CONTROLLER_BINDTYPE_HAT,
48 }
49 mixin(expandEnum!SDL_GameControllerBindType);
50 
51 struct SDL_GameControllerButtonBind {
52     SDL_GameControllerBindType bindType;
53     union value {
54         int button;
55         int axis;
56         struct hat {
57             int hat;
58             int hat_mask;
59         }
60     }
61     alias button = value.button;
62     alias axis = value.axis;
63     alias hat = value.hat;
64 }
65 
66 enum SDL_GameControllerAxis {
67     SDL_CONTROLLER_AXIS_INVALID = -1,
68     SDL_CONTROLLER_AXIS_LEFTX,
69     SDL_CONTROLLER_AXIS_LEFTY,
70     SDL_CONTROLLER_AXIS_RIGHTX,
71     SDL_CONTROLLER_AXIS_RIGHTY,
72     SDL_CONTROLLER_AXIS_TRIGGERLEFT,
73     SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
74     SDL_CONTROLLER_AXIS_MAX
75 }
76 mixin(expandEnum!SDL_GameControllerAxis);
77 
78 static if(sdlSupport >= SDLSupport.sdl2014) {
79     enum SDL_GameControllerButton {
80         SDL_CONTROLLER_BUTTON_INVALID = -1,
81         SDL_CONTROLLER_BUTTON_A,
82         SDL_CONTROLLER_BUTTON_B,
83         SDL_CONTROLLER_BUTTON_X,
84         SDL_CONTROLLER_BUTTON_Y,
85         SDL_CONTROLLER_BUTTON_BACK,
86         SDL_CONTROLLER_BUTTON_GUIDE,
87         SDL_CONTROLLER_BUTTON_START,
88         SDL_CONTROLLER_BUTTON_LEFTSTICK,
89         SDL_CONTROLLER_BUTTON_RIGHTSTICK,
90         SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
91         SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
92         SDL_CONTROLLER_BUTTON_DPAD_UP,
93         SDL_CONTROLLER_BUTTON_DPAD_DOWN,
94         SDL_CONTROLLER_BUTTON_DPAD_LEFT,
95         SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
96         SDL_CONTROLLER_BUTTON_MISC1,
97         SDL_CONTROLLER_BUTTON_PADDLE1,
98         SDL_CONTROLLER_BUTTON_PADDLE2,
99         SDL_CONTROLLER_BUTTON_PADDLE3,
100         SDL_CONTROLLER_BUTTON_PADDLE4,
101         SDL_CONTROLLER_BUTTON_TOUCHPAD,
102         SDL_CONTROLLER_BUTTON_MAX,
103     }
104 }
105 else {
106     enum SDL_GameControllerButton {
107         SDL_CONTROLLER_BUTTON_INVALID = -1,
108         SDL_CONTROLLER_BUTTON_A,
109         SDL_CONTROLLER_BUTTON_B,
110         SDL_CONTROLLER_BUTTON_X,
111         SDL_CONTROLLER_BUTTON_Y,
112         SDL_CONTROLLER_BUTTON_BACK,
113         SDL_CONTROLLER_BUTTON_GUIDE,
114         SDL_CONTROLLER_BUTTON_START,
115         SDL_CONTROLLER_BUTTON_LEFTSTICK,
116         SDL_CONTROLLER_BUTTON_RIGHTSTICK,
117         SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
118         SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
119         SDL_CONTROLLER_BUTTON_DPAD_UP,
120         SDL_CONTROLLER_BUTTON_DPAD_DOWN,
121         SDL_CONTROLLER_BUTTON_DPAD_LEFT,
122         SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
123         SDL_CONTROLLER_BUTTON_MAX,
124     }
125 }
126 mixin(expandEnum!SDL_GameControllerButton);
127 
128 static if(sdlSupport >= SDLSupport.sdl202) {
129     @nogc nothrow
130     int SDL_GameControllerAddMappingsFromFile(const(char)* file) {
131         pragma(inline, true);
132         return SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file,"rb"),1);
133     }
134 }
135 
136 static if(staticBinding) {
137     extern(C) @nogc nothrow {
138         int SDL_GameControllerAddMapping(const(char)* mappingString);
139         char* SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid);
140         char* SDL_GameControllerMapping(SDL_GameController* gamecontroller);
141         SDL_bool SDL_IsGameController(int joystick_index);
142         const(char)* SDL_GameControllerNameForIndex(int joystick_index);
143         SDL_GameController* SDL_GameControllerOpen(int joystick_index);
144         const(char)* SDL_GameControllerName(SDL_GameController* gamecontroller);
145         SDL_bool SDL_GameControllerGetAttached(SDL_GameController* gamecontroller);
146         SDL_Joystick* SDL_GameControllerGetJoystick(SDL_GameController* gamecontroller);
147         int SDL_GameControllerEventState(int state);
148         void SDL_GameControllerUpdate();
149         SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const(char)* pchString);
150         const(char)* SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis);
151         SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis);
152         short SDL_GameControllerGetAxis(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis);
153         SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const(char*) pchString);
154         const(char)* SDL_GameControllerGetStringForButton(SDL_GameControllerButton button);
155         SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController* gamecontroller, SDL_GameControllerButton button);
156         ubyte SDL_GameControllerGetButton(SDL_GameController* gamecontroller, SDL_GameControllerButton button);
157         void SDL_GameControllerClose(SDL_GameController* gamecontroller);
158 
159         static if(sdlSupport >= SDLSupport.sdl202) {
160             int SDL_GameControllerAddMappingsFromRW(SDL_RWops* rw, int freerw);
161         }
162         static if(sdlSupport >= SDLSupport.sdl204) {
163             SDL_GameController* SDL_GameControllerFromInstanceID(SDL_JoystickID joyid);
164         }
165         static if(sdlSupport >= SDLSupport.sdl206) {
166             ushort SDL_GameControllerGetProduct(SDL_GameController* gamecontroller);
167             ushort SDL_GameControllerGetProductVersion(SDL_GameController* gamecontroller);
168             ushort SDL_GameControllerGetVendor(SDL_GameController* gamecontroller);
169             char* SDL_GameControllerMappingForIndex(int mapping_index);
170             int SDL_GameControllerNumMappings();
171         }
172         static if(sdlSupport >= SDLSupport.sdl209) {
173             char* SDL_GameControllerMappingForDeviceIndex(int joystick_index);
174             int SDL_GameControllerRumble(SDL_GameController* gamecontroller, ushort low_frequency_rumble, ushort high_frequency_rumble, uint duration_ms);
175         }
176         static if(sdlSupport >= SDLSupport.sdl2010) {
177             int SDL_GameControllerGetPlayerIndex(SDL_GameController* gamecontroller);
178         }
179         static if(sdlSupport >= SDLSupport.sdl2012) {
180             SDL_GameControllerType SDL_GameControllerTypeForIndex(int joystick_index);
181             SDL_GameController* SDL_GameControllerFromPlayerIndex(int player_index);
182             SDL_GameControllerType SDL_GameControllerGetType(SDL_GameController* gamecontroller);
183             void SDL_GameControllerSetPlayerIndex(SDL_GameController* gamecontroller, int player_index);
184         }
185         static if(sdlSupport >= SDLSupport.sdl2014) {
186             SDL_bool SDL_GameControllerHasAxis(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis);
187             SDL_bool SDL_GameControllerHasButton(SDL_GameController* gamecontroller, SDL_GameControllerButton button);
188             int SDL_GameControllerGetNumTouchpads(SDL_GameController* gamecontroller);
189             int SDL_GameControllerGetNumTouchpadFingers (SDL_GameController* gamecontroller, int touchpad);
190             int SDL_GameControllerGetTouchpadFinger(SDL_GameController* gamecontroller, int touchpad, int finger, ubyte* state, float* x, float* y, float* pressure);
191             SDL_bool SDL_GameControllerHasSensor(SDL_GameController* gamecontroller, SDL_SensorType type);
192             int SDL_GameControllerSetSensorEnabled(SDL_GameController* gamecontroller, SDL_SensorType type, SDL_bool enabled);
193             SDL_bool SDL_GameControllerIsSensorEnabled(SDL_GameController* gamecontroller, SDL_SensorType type);
194             int SDL_GameControllerGetSensorData(SDL_GameController* gamecontroller, SDL_SensorType type, float* data, int num_values);
195             int SDL_GameControllerRumbleTriggers(SDL_GameController* gamecontroller, ushort left_rumble, ushort right_rumble, uint duration_ms);
196             SDL_bool SDL_GameControllerHasLED(SDL_GameController* gamecontroller);
197             int SDL_GameControllerSetLED(SDL_GameController* gamecontroller, ubyte red, ubyte green, ubyte blue);
198         }
199     }
200 }
201 else {
202     extern(C) @nogc nothrow {
203         alias pSDL_GameControllerAddMapping = int function(const(char)* mappingString);
204         alias pSDL_GameControllerMappingForGUID = char* function(SDL_JoystickGUID guid);
205         alias pSDL_GameControllerMapping = char* function(SDL_GameController* gamecontroller);
206         alias pSDL_IsGameController = SDL_bool function(int joystick_index);
207         alias pSDL_GameControllerNameForIndex = const(char)* function(int joystick_index);
208         alias pSDL_GameControllerOpen = SDL_GameController* function(int joystick_index);
209         alias pSDL_GameControllerName = const(char)* function(SDL_GameController* gamecontroller);
210         alias pSDL_GameControllerGetAttached = SDL_bool function(SDL_GameController* gamecontroller);
211         alias pSDL_GameControllerGetJoystick = SDL_Joystick* function(SDL_GameController* gamecontroller);
212         alias pSDL_GameControllerEventState = int function(int state);
213         alias pSDL_GameControllerUpdate = void function();
214         alias pSDL_GameControllerGetAxisFromString = SDL_GameControllerAxis function(const(char)* pchString);
215         alias pSDL_GameControllerGetStringForAxis = const(char)* function(SDL_GameControllerAxis axis);
216         alias pSDL_GameControllerGetBindForAxis = SDL_GameControllerButtonBind function(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis);
217         alias pSDL_GameControllerGetAxis = short function(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis);
218         alias pSDL_GameControllerGetButtonFromString = SDL_GameControllerButton function(const(char*) pchString);
219         alias pSDL_GameControllerGetStringForButton = const(char)* function(SDL_GameControllerButton button);
220         alias pSDL_GameControllerGetBindForButton = SDL_GameControllerButtonBind function(SDL_GameController* gamecontroller, SDL_GameControllerButton button);
221         alias pSDL_GameControllerGetButton = ubyte function(SDL_GameController* gamecontroller, SDL_GameControllerButton button);
222         alias pSDL_GameControllerClose = void function(SDL_GameController* gamecontroller);
223     }
224     __gshared {
225         pSDL_GameControllerAddMapping SDL_GameControllerAddMapping;
226         pSDL_GameControllerMappingForGUID SDL_GameControllerMappingForGUID;
227         pSDL_GameControllerMapping SDL_GameControllerMapping;
228         pSDL_IsGameController SDL_IsGameController;
229         pSDL_GameControllerNameForIndex SDL_GameControllerNameForIndex;
230         pSDL_GameControllerOpen SDL_GameControllerOpen;
231         pSDL_GameControllerName SDL_GameControllerName;
232         pSDL_GameControllerGetAttached SDL_GameControllerGetAttached;
233         pSDL_GameControllerGetJoystick SDL_GameControllerGetJoystick;
234         pSDL_GameControllerEventState SDL_GameControllerEventState;
235         pSDL_GameControllerUpdate SDL_GameControllerUpdate;
236         pSDL_GameControllerGetAxisFromString SDL_GameControllerGetAxisFromString;
237         pSDL_GameControllerGetStringForAxis SDL_GameControllerGetStringForAxis;
238         pSDL_GameControllerGetBindForAxis SDL_GameControllerGetBindForAxis;
239         pSDL_GameControllerGetAxis SDL_GameControllerGetAxis;
240         pSDL_GameControllerGetButtonFromString SDL_GameControllerGetButtonFromString;
241         pSDL_GameControllerGetStringForButton SDL_GameControllerGetStringForButton;
242         pSDL_GameControllerGetBindForButton SDL_GameControllerGetBindForButton;
243         pSDL_GameControllerGetButton SDL_GameControllerGetButton;
244         pSDL_GameControllerClose SDL_GameControllerClose;
245     }
246     static if(sdlSupport >= SDLSupport.sdl202) {
247         extern(C) @nogc nothrow {
248             alias pSDL_GameControllerAddMappingsFromRW = int function(SDL_RWops* rw, int freerw);
249         }
250 
251         __gshared {
252             pSDL_GameControllerAddMappingsFromRW SDL_GameControllerAddMappingsFromRW;
253         }
254     }
255     static if(sdlSupport >= SDLSupport.sdl204) {
256         extern(C) @nogc nothrow {
257             alias pSDL_GameControllerFromInstanceID = SDL_GameController* function(SDL_JoystickID joyid);
258         }
259 
260         __gshared {
261             pSDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID;
262         }
263     }
264     static if(sdlSupport >= SDLSupport.sdl206) {
265         extern(C) @nogc nothrow {
266             alias pSDL_GameControllerGetProduct = ushort function(SDL_GameController* gamecontroller);
267             alias pSDL_GameControllerGetProductVersion = ushort function(SDL_GameController* gamecontroller);
268             alias pSDL_GameControllerGetVendor = ushort function(SDL_GameController* gamecontroller);
269             alias pSDL_GameControllerMappingForIndex = char* function(int mapping_index);
270             alias pSDL_GameControllerNumMappings = int function();
271         }
272 
273         __gshared {
274             pSDL_GameControllerGetProduct SDL_GameControllerGetProduct;
275             pSDL_GameControllerGetProductVersion SDL_GameControllerGetProductVersion;
276             pSDL_GameControllerGetVendor SDL_GameControllerGetVendor;
277             pSDL_GameControllerMappingForIndex SDL_GameControllerMappingForIndex;
278             pSDL_GameControllerNumMappings SDL_GameControllerNumMappings;
279         }
280     }
281     static if(sdlSupport >= SDLSupport.sdl209) {
282         extern(C) @nogc nothrow {
283             alias pSDL_GameControllerMappingForDeviceIndex = char* function(int joystick_index);
284             alias pSDL_GameControllerRumble = int function(SDL_GameController* gamecontroller, ushort low_frequency_rumble, ushort high_frequency_rumble, uint duration_ms);
285         }
286 
287         __gshared {
288             pSDL_GameControllerMappingForDeviceIndex SDL_GameControllerMappingForDeviceIndex;
289             pSDL_GameControllerRumble SDL_GameControllerRumble;
290         }
291     }
292     static if(sdlSupport >= SDLSupport.sdl2010) {
293         extern(C) @nogc nothrow {
294             alias pSDL_GameControllerGetPlayerIndex = int function(SDL_GameController* gamecontroller);
295         }
296         __gshared {
297             pSDL_GameControllerGetPlayerIndex SDL_GameControllerGetPlayerIndex;
298         }
299     }
300     static if(sdlSupport >= SDLSupport.sdl2012) {
301         extern(C) @nogc nothrow {
302             alias pSDL_GameControllerTypeForIndex = SDL_GameControllerType function(int joystick_index);
303             alias pSDL_GameControllerFromPlayerIndex = SDL_GameController* function(int player_index);
304             alias pSDL_GameControllerGetType = SDL_GameControllerType function(SDL_GameController* gamecontroller);
305             alias pSDL_GameControllerSetPlayerIndex = void function(SDL_GameController* gamecontroller, int player_index);
306 
307         }
308         __gshared {
309             pSDL_GameControllerTypeForIndex SDL_GameControllerTypeForIndex;
310             pSDL_GameControllerFromPlayerIndex SDL_GameControllerFromPlayerIndex;
311             pSDL_GameControllerGetType SDL_GameControllerGetType;
312             pSDL_GameControllerSetPlayerIndex SDL_GameControllerSetPlayerIndex;
313         }
314     }
315     static if(sdlSupport >= SDLSupport.sdl2014) {
316         extern(C) @nogc nothrow {
317             alias pSDL_GameControllerHasAxis = SDL_bool function(SDL_GameController* gamecontroller, SDL_GameControllerAxis axis);
318             alias pSDL_GameControllerHasButton = SDL_bool function(SDL_GameController* gamecontroller, SDL_GameControllerButton button);
319             alias pSDL_GameControllerGetNumTouchpads = int function(SDL_GameController* gamecontroller);
320             alias pSDL_GameControllerGetNumTouchpadFingers = int function(SDL_GameController* gamecontroller, int touchpad);
321             alias pSDL_GameControllerGetTouchpadFinger = int function(SDL_GameController* gamecontroller, int touchpad, int finger, ubyte* state, float* x, float* y, float* pressure);
322             alias pSDL_GameControllerHasSensor = SDL_bool function(SDL_GameController* gamecontroller, SDL_SensorType type);
323             alias pSDL_GameControllerSetSensorEnabled = int function(SDL_GameController* gamecontroller, SDL_SensorType type, SDL_bool enabled);
324             alias pSDL_GameControllerIsSensorEnabled = SDL_bool function(SDL_GameController* gamecontroller, SDL_SensorType type);
325             alias pSDL_GameControllerGetSensorData = int function(SDL_GameController* gamecontroller, SDL_SensorType type, float* data, int num_values);
326             alias pSDL_GameControllerRumbleTriggers = int function(SDL_GameController* gamecontroller, ushort left_rumble, ushort right_rumble, uint duration_ms);
327             alias pSDL_GameControllerHasLED = SDL_bool function(SDL_GameController* gamecontroller);
328             alias pSDL_GameControllerSetLED = int function(SDL_GameController* gamecontroller, ubyte red, ubyte green, ubyte blue);
329         }
330         __gshared {
331             pSDL_GameControllerHasAxis SDL_GameControllerHasAxis;
332             pSDL_GameControllerHasButton SDL_GameControllerHasButton;
333             pSDL_GameControllerGetNumTouchpads SDL_GameControllerGetNumTouchpads;
334             pSDL_GameControllerGetNumTouchpadFingers SDL_GameControllerGetNumTouchpadFingers;
335             pSDL_GameControllerGetTouchpadFinger SDL_GameControllerGetTouchpadFinger;
336             pSDL_GameControllerHasSensor SDL_GameControllerHasSensor;
337             pSDL_GameControllerSetSensorEnabled SDL_GameControllerSetSensorEnabled;
338             pSDL_GameControllerIsSensorEnabled SDL_GameControllerIsSensorEnabled;
339             pSDL_GameControllerGetSensorData SDL_GameControllerGetSensorData;
340             pSDL_GameControllerRumbleTriggers SDL_GameControllerRumbleTriggers;
341             pSDL_GameControllerHasLED SDL_GameControllerHasLED;
342             pSDL_GameControllerSetLED SDL_GameControllerSetLED;
343         }
344     }
345 }