summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/haptic/windows/SDL_windowshaptic.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/haptic/windows/SDL_windowshaptic.c')
-rw-r--r--contrib/SDL-3.2.8/src/haptic/windows/SDL_windowshaptic.c369
1 files changed, 369 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/haptic/windows/SDL_windowshaptic.c b/contrib/SDL-3.2.8/src/haptic/windows/SDL_windowshaptic.c
new file mode 100644
index 0000000..e21ab91
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/haptic/windows/SDL_windowshaptic.c
@@ -0,0 +1,369 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_HAPTIC_DINPUT
24
25#include "../SDL_syshaptic.h"
26#include "../../joystick/SDL_sysjoystick.h" // For the real SDL_Joystick
27#include "../../joystick/windows/SDL_windowsjoystick_c.h" // For joystick hwdata
28#include "../../joystick/windows/SDL_xinputjoystick_c.h" // For xinput rumble
29
30#include "SDL_windowshaptic_c.h"
31#include "SDL_dinputhaptic_c.h"
32
33// Set up for C function definitions, even when using C++
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38/*
39 * Internal stuff.
40 */
41SDL_hapticlist_item *SDL_hapticlist = NULL;
42static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
43static int numhaptics = 0;
44
45/*
46 * Initializes the haptic subsystem.
47 */
48bool SDL_SYS_HapticInit(void)
49{
50 JoyStick_DeviceData *device;
51
52 if (!SDL_DINPUT_HapticInit()) {
53 return false;
54 }
55
56 /* The joystick subsystem will usually be initialized before haptics,
57 * so the initial HapticMaybeAddDevice() calls from the joystick
58 * subsystem will arrive too early to create haptic devices. We will
59 * invoke those callbacks again here to pick up any joysticks that
60 * were added prior to haptics initialization. */
61 for (device = SYS_Joystick; device; device = device->pNext) {
62 SDL_DINPUT_HapticMaybeAddDevice(&device->dxdevice);
63 }
64
65 return true;
66}
67
68bool SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item)
69{
70 if (!SDL_hapticlist_tail) {
71 SDL_hapticlist = SDL_hapticlist_tail = item;
72 } else {
73 SDL_hapticlist_tail->next = item;
74 SDL_hapticlist_tail = item;
75 }
76
77 // Device has been added.
78 ++numhaptics;
79
80 return true;
81}
82
83bool SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item)
84{
85 const bool result = item->haptic ? true : false;
86 if (prev) {
87 prev->next = item->next;
88 } else {
89 SDL_assert(SDL_hapticlist == item);
90 SDL_hapticlist = item->next;
91 }
92 if (item == SDL_hapticlist_tail) {
93 SDL_hapticlist_tail = prev;
94 }
95 --numhaptics;
96 // !!! TODO: Send a haptic remove event?
97 SDL_free(item);
98 return result;
99}
100
101int SDL_SYS_NumHaptics(void)
102{
103 return numhaptics;
104}
105
106static SDL_hapticlist_item *HapticByDevIndex(int device_index)
107{
108 SDL_hapticlist_item *item = SDL_hapticlist;
109
110 if ((device_index < 0) || (device_index >= numhaptics)) {
111 return NULL;
112 }
113
114 while (device_index > 0) {
115 SDL_assert(item != NULL);
116 --device_index;
117 item = item->next;
118 }
119 return item;
120}
121
122static SDL_hapticlist_item *HapticByInstanceID(SDL_HapticID instance_id)
123{
124 SDL_hapticlist_item *item;
125 for (item = SDL_hapticlist; item; item = item->next) {
126 if (instance_id == item->instance_id) {
127 return item;
128 }
129 }
130 return NULL;
131}
132
133SDL_HapticID SDL_SYS_HapticInstanceID(int index)
134{
135 SDL_hapticlist_item *item = HapticByDevIndex(index);
136 if (item) {
137 return item->instance_id;
138 }
139 return 0;
140}
141
142/*
143 * Return the name of a haptic device, does not need to be opened.
144 */
145const char *SDL_SYS_HapticName(int index)
146{
147 SDL_hapticlist_item *item = HapticByDevIndex(index);
148 return item->name;
149}
150
151/*
152 * Opens a haptic device for usage.
153 */
154bool SDL_SYS_HapticOpen(SDL_Haptic *haptic)
155{
156 SDL_hapticlist_item *item = HapticByInstanceID(haptic->instance_id);
157 return SDL_DINPUT_HapticOpen(haptic, item);
158}
159
160/*
161 * Opens a haptic device from first mouse it finds for usage.
162 */
163int SDL_SYS_HapticMouse(void)
164{
165#ifdef SDL_HAPTIC_DINPUT
166 SDL_hapticlist_item *item;
167 int index = 0;
168
169 // Grab the first mouse haptic device we find.
170 for (item = SDL_hapticlist; item; item = item->next) {
171 if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER) {
172 return index;
173 }
174 ++index;
175 }
176#endif // SDL_HAPTIC_DINPUT
177 return -1;
178}
179
180/*
181 * Checks to see if a joystick has haptic features.
182 */
183bool SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
184{
185 if (joystick->driver != &SDL_WINDOWS_JoystickDriver) {
186 return false;
187 }
188 if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
189 return true;
190 }
191 return false;
192}
193
194/*
195 * Checks to see if the haptic device and joystick are in reality the same.
196 */
197bool SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
198{
199 if (joystick->driver != &SDL_WINDOWS_JoystickDriver) {
200 return false;
201 }
202 return SDL_DINPUT_JoystickSameHaptic(haptic, joystick);
203}
204
205/*
206 * Opens a SDL_Haptic from a SDL_Joystick.
207 */
208bool SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
209{
210 SDL_assert(joystick->driver == &SDL_WINDOWS_JoystickDriver);
211
212 return SDL_DINPUT_HapticOpenFromJoystick(haptic, joystick);
213}
214
215/*
216 * Closes the haptic device.
217 */
218void SDL_SYS_HapticClose(SDL_Haptic *haptic)
219{
220 if (haptic->hwdata) {
221
222 // Free effects.
223 SDL_free(haptic->effects);
224 haptic->effects = NULL;
225 haptic->neffects = 0;
226
227 // Clean up
228 SDL_DINPUT_HapticClose(haptic);
229
230 // Free
231 SDL_free(haptic->hwdata);
232 haptic->hwdata = NULL;
233 }
234}
235
236/*
237 * Clean up after system specific haptic stuff
238 */
239void SDL_SYS_HapticQuit(void)
240{
241 SDL_hapticlist_item *item;
242 SDL_hapticlist_item *next = NULL;
243
244 for (item = SDL_hapticlist; item; item = next) {
245 /* Opened and not closed haptics are leaked, this is on purpose.
246 * Close your haptic devices after usage. */
247 // !!! FIXME: (...is leaking on purpose a good idea?) - No, of course not.
248 next = item->next;
249 SDL_free(item->name);
250 SDL_free(item);
251 }
252
253 SDL_DINPUT_HapticQuit();
254
255 numhaptics = 0;
256 SDL_hapticlist = NULL;
257 SDL_hapticlist_tail = NULL;
258}
259
260/*
261 * Creates a new haptic effect.
262 */
263bool SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect,
264 const SDL_HapticEffect *base)
265{
266 bool result;
267
268 // Alloc the effect.
269 effect->hweffect = (struct haptic_hweffect *) SDL_calloc(1, sizeof(struct haptic_hweffect));
270 if (!effect->hweffect) {
271 return false;
272 }
273
274 result = SDL_DINPUT_HapticNewEffect(haptic, effect, base);
275 if (!result) {
276 SDL_free(effect->hweffect);
277 effect->hweffect = NULL;
278 }
279 return result;
280}
281
282/*
283 * Updates an effect.
284 */
285bool SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, const SDL_HapticEffect *data)
286{
287 return SDL_DINPUT_HapticUpdateEffect(haptic, effect, data);
288}
289
290/*
291 * Runs an effect.
292 */
293bool SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
294{
295 return SDL_DINPUT_HapticRunEffect(haptic, effect, iterations);
296}
297
298/*
299 * Stops an effect.
300 */
301bool SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
302{
303 return SDL_DINPUT_HapticStopEffect(haptic, effect);
304}
305
306/*
307 * Frees the effect.
308 */
309void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
310{
311 SDL_DINPUT_HapticDestroyEffect(haptic, effect);
312 SDL_free(effect->hweffect);
313 effect->hweffect = NULL;
314}
315
316/*
317 * Gets the status of a haptic effect.
318 */
319int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
320{
321 return SDL_DINPUT_HapticGetEffectStatus(haptic, effect);
322}
323
324/*
325 * Sets the gain.
326 */
327bool SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
328{
329 return SDL_DINPUT_HapticSetGain(haptic, gain);
330}
331
332/*
333 * Sets the autocentering.
334 */
335bool SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
336{
337 return SDL_DINPUT_HapticSetAutocenter(haptic, autocenter);
338}
339
340/*
341 * Pauses the device.
342 */
343bool SDL_SYS_HapticPause(SDL_Haptic *haptic)
344{
345 return SDL_DINPUT_HapticPause(haptic);
346}
347
348/*
349 * Pauses the device.
350 */
351bool SDL_SYS_HapticResume(SDL_Haptic *haptic)
352{
353 return SDL_DINPUT_HapticResume(haptic);
354}
355
356/*
357 * Stops all the playing effects on the device.
358 */
359bool SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
360{
361 return SDL_DINPUT_HapticStopAll(haptic);
362}
363
364// Ends C function definitions when using C++
365#ifdef __cplusplus
366}
367#endif
368
369#endif // SDL_HAPTIC_DINPUT