zenilib: zenilib/jni/external/sdl/src/haptic/darwin/SDL_syshaptic.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_syshaptic.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 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_config.h"
22
23 #ifdef SDL_HAPTIC_IOKIT
24
25 #include "SDL_haptic.h"
26 #include "../SDL_syshaptic.h"
27 #include "SDL_joystick.h"
28 #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
29 #include "../../joystick/darwin/SDL_sysjoystick_c.h" /* For joystick hwdata */
30
31 #include <IOKit/IOKitLib.h>
32 #include <IOKit/hid/IOHIDKeys.h>
33 #include <IOKit/hid/IOHIDUsageTables.h>
34 #include <ForceFeedback/ForceFeedback.h>
35 #include <ForceFeedback/ForceFeedbackConstants.h>
36
37 #ifndef IO_OBJECT_NULL
38 #define IO_OBJECT_NULL ((io_service_t)0)
39 #endif
40
41 #define MAX_HAPTICS 32
42
43
44 /*
45 * List of available haptic devices.
46 */
47 static struct
48 {
49 char name[256]; /* Name of the device. */
50
51 io_service_t dev; /* Node we use to create the device. */
52 SDL_Haptic *haptic; /* Haptic currently associated with it. */
53
54 /* Usage pages for determining if it's a mouse or not. */
55 long usage;
56 long usagePage;
57 } SDL_hapticlist[MAX_HAPTICS];
58
59
60 /*
61 * Haptic system hardware data.
62 */
63 struct haptic_hwdata
64 {
65 FFDeviceObjectReference device; /* Hardware device. */
66 UInt8 axes[3];
67 };
68
69
70 /*
71 * Haptic system effect data.
72 */
73 struct haptic_hweffect
74 {
75 FFEffectObjectReference ref; /* Reference. */
76 struct FFEFFECT effect; /* Hardware effect. */
77 };
78
79 /*
80 * Prototypes.
81 */
82 static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type);
83 static int HIDGetDeviceProduct(io_service_t dev, char *name);
84
85
86 /*
87 * Like strerror but for force feedback errors.
88 */
89 static const char *
90 FFStrError(HRESULT err)
91 {
92 switch (err) {
93 case FFERR_DEVICEFULL:
94 return "device full";
95 /* This should be valid, but for some reason isn't defined... */
96 /* case FFERR_DEVICENOTREG:
97 return "device not registered"; */
98 case FFERR_DEVICEPAUSED:
99 return "device paused";
100 case FFERR_DEVICERELEASED:
101 return "device released";
102 case FFERR_EFFECTPLAYING:
103 return "effect playing";
104 case FFERR_EFFECTTYPEMISMATCH:
105 return "effect type mismatch";
106 case FFERR_EFFECTTYPENOTSUPPORTED:
107 return "effect type not supported";
108 case FFERR_GENERIC:
109 return "undetermined error";
110 case FFERR_HASEFFECTS:
111 return "device has effects";
112 case FFERR_INCOMPLETEEFFECT:
113 return "incomplete effect";
114 case FFERR_INTERNAL:
115 return "internal fault";
116 case FFERR_INVALIDDOWNLOADID:
117 return "invalid download id";
118 case FFERR_INVALIDPARAM:
119 return "invalid parameter";
120 case FFERR_MOREDATA:
121 return "more data";
122 case FFERR_NOINTERFACE:
123 return "interface not supported";
124 case FFERR_NOTDOWNLOADED:
125 return "effect is not downloaded";
126 case FFERR_NOTINITIALIZED:
127 return "object has not been initialized";
128 case FFERR_OUTOFMEMORY:
129 return "out of memory";
130 case FFERR_UNPLUGGED:
131 return "device is unplugged";
132 case FFERR_UNSUPPORTED:
133 return "function call unsupported";
134 case FFERR_UNSUPPORTEDAXIS:
135 return "axis unsupported";
136
137 default:
138 return "unknown error";
139 }
140 }
141
142
143 /*
144 * Initializes the haptic subsystem.
145 */
146 int
147 SDL_SYS_HapticInit(void)
148 {
149 int numhaptics;
150 IOReturn result;
151 io_iterator_t iter;
152 CFDictionaryRef match;
153 io_service_t device;
154 CFMutableDictionaryRef hidProperties;
155 CFTypeRef refCF;
156
157 /* Clear all the memory. */
158 SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));
159
160 /* Get HID devices. */
161 match = IOServiceMatching(kIOHIDDeviceKey);
162 if (match == NULL) {
163 return SDL_SetError("Haptic: Failed to get IOServiceMatching.");
164 }
165
166 /* Now search I/O Registry for matching devices. */
167 result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter);
168 if (result != kIOReturnSuccess) {
169 return SDL_SetError("Haptic: Couldn't create a HID object iterator.");
170 }
171 /* IOServiceGetMatchingServices consumes dictionary. */
172
173 if (!IOIteratorIsValid(iter)) { /* No iterator. */
174 return 0;
175 }
176
177 numhaptics = 0;
178 while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
179
180 /* Check for force feedback. */
181 if (FFIsForceFeedback(device) == FF_OK) {
182
183 /* Set basic device data. */
184 HIDGetDeviceProduct(device, SDL_hapticlist[numhaptics].name);
185 SDL_hapticlist[numhaptics].dev = device;
186 SDL_hapticlist[numhaptics].haptic = NULL;
187
188 /* Set usage pages. */
189 hidProperties = 0;
190 refCF = 0;
191 result = IORegistryEntryCreateCFProperties(device,
192 &hidProperties,
193 kCFAllocatorDefault,
194 kNilOptions);
195 if ((result == KERN_SUCCESS) && hidProperties) {
196 refCF =
197 CFDictionaryGetValue(hidProperties,
198 CFSTR(kIOHIDPrimaryUsagePageKey));
199 if (refCF) {
200 if (!CFNumberGetValue(refCF, kCFNumberLongType,
201 &SDL_hapticlist[numhaptics].
202 usagePage))
203 SDL_SetError
204 ("Haptic: Recieving device's usage page.");
205 refCF =
206 CFDictionaryGetValue(hidProperties,
207 CFSTR(kIOHIDPrimaryUsageKey));
208 if (refCF) {
209 if (!CFNumberGetValue(refCF, kCFNumberLongType,
210 &SDL_hapticlist[numhaptics].
211 usage))
212 SDL_SetError("Haptic: Recieving device's usage.");
213 }
214 }
215 CFRelease(hidProperties);
216 }
217
218 /* Device has been added. */
219 numhaptics++;
220 } else { /* Free the unused device. */
221 IOObjectRelease(device);
222 }
223
224 /* Reached haptic limit. */
225 if (numhaptics >= MAX_HAPTICS)
226 break;
227 }
228 IOObjectRelease(iter);
229
230 return numhaptics;
231 }
232
233
234 /*
235 * Return the name of a haptic device, does not need to be opened.
236 */
237 const char *
238 SDL_SYS_HapticName(int index)
239 {
240 return SDL_hapticlist[index].name;
241 }
242
243 /*
244 * Gets the device's product name.
245 */
246 static int
247 HIDGetDeviceProduct(io_service_t dev, char *name)
248 {
249 CFMutableDictionaryRef hidProperties, usbProperties;
250 io_registry_entry_t parent1, parent2;
251 kern_return_t ret;
252
253 hidProperties = usbProperties = 0;
254
255 ret = IORegistryEntryCreateCFProperties(dev, &hidProperties,
256 kCFAllocatorDefault, kNilOptions);
257 if ((ret != KERN_SUCCESS) || !hidProperties) {
258 return SDL_SetError("Haptic: Unable to create CFProperties.");
259 }
260
261 /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
262 * get dictionary for USB properties: step up two levels and get CF dictionary for USB properties
263 */
264 if ((KERN_SUCCESS ==
265 IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1))
266 && (KERN_SUCCESS ==
267 IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
268 && (KERN_SUCCESS ==
269 IORegistryEntryCreateCFProperties(parent2, &usbProperties,
270 kCFAllocatorDefault,
271 kNilOptions))) {
272 if (usbProperties) {
273 CFTypeRef refCF = 0;
274 /* get device info
275 * try hid dictionary first, if fail then go to USB dictionary
276 */
277
278
279 /* Get product name */
280 refCF =
281 CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
282 if (!refCF)
283 refCF =
284 CFDictionaryGetValue(usbProperties,
285 CFSTR("USB Product Name"));
286 if (refCF) {
287 if (!CFStringGetCString(refCF, name, 256,
288 CFStringGetSystemEncoding())) {
289 return SDL_SetError
290 ("Haptic: CFStringGetCString error retrieving pDevice->product.");
291 }
292 }
293
294 CFRelease(usbProperties);
295 } else {
296 return SDL_SetError
297 ("Haptic: IORegistryEntryCreateCFProperties failed to create usbProperties.");
298 }
299
300 /* Release stuff. */
301 if (kIOReturnSuccess != IOObjectRelease(parent2)) {
302 SDL_SetError("Haptic: IOObjectRelease error with parent2.");
303 }
304 if (kIOReturnSuccess != IOObjectRelease(parent1)) {
305 SDL_SetError("Haptic: IOObjectRelease error with parent1.");
306 }
307 } else {
308 return SDL_SetError("Haptic: Error getting registry entries.");
309 }
310
311 return 0;
312 }
313
314
315 #define FF_TEST(ff, s) \
316 if (features.supportedEffects & (ff)) supported |= (s)
317 /*
318 * Gets supported features.
319 */
320 static unsigned int
321 GetSupportedFeatures(SDL_Haptic * haptic)
322 {
323 HRESULT ret;
324 FFDeviceObjectReference device;
325 FFCAPABILITIES features;
326 unsigned int supported;
327 Uint32 val;
328
329 device = haptic->hwdata->device;
330
331 ret = FFDeviceGetForceFeedbackCapabilities(device, &features);
332 if (ret != FF_OK) {
333 return SDL_SetError("Haptic: Unable to get device's supported features.");
334 }
335
336 supported = 0;
337
338 /* Get maximum effects. */
339 haptic->neffects = features.storageCapacity;
340 haptic->nplaying = features.playbackCapacity;
341
342 /* Test for effects. */
343 FF_TEST(FFCAP_ET_CONSTANTFORCE, SDL_HAPTIC_CONSTANT);
344 FF_TEST(FFCAP_ET_RAMPFORCE, SDL_HAPTIC_RAMP);
345 /* !!! FIXME: put this back when we have more bits in 2.1 */
346 /* FF_TEST(FFCAP_ET_SQUARE, SDL_HAPTIC_SQUARE); */
347 FF_TEST(FFCAP_ET_SINE, SDL_HAPTIC_SINE);
348 FF_TEST(FFCAP_ET_TRIANGLE, SDL_HAPTIC_TRIANGLE);
349 FF_TEST(FFCAP_ET_SAWTOOTHUP, SDL_HAPTIC_SAWTOOTHUP);
350 FF_TEST(FFCAP_ET_SAWTOOTHDOWN, SDL_HAPTIC_SAWTOOTHDOWN);
351 FF_TEST(FFCAP_ET_SPRING, SDL_HAPTIC_SPRING);
352 FF_TEST(FFCAP_ET_DAMPER, SDL_HAPTIC_DAMPER);
353 FF_TEST(FFCAP_ET_INERTIA, SDL_HAPTIC_INERTIA);
354 FF_TEST(FFCAP_ET_FRICTION, SDL_HAPTIC_FRICTION);
355 FF_TEST(FFCAP_ET_CUSTOMFORCE, SDL_HAPTIC_CUSTOM);
356
357 /* Check if supports gain. */
358 ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFGAIN,
359 &val, sizeof(val));
360 if (ret == FF_OK)
361 supported |= SDL_HAPTIC_GAIN;
362 else if (ret != FFERR_UNSUPPORTED) {
363 return SDL_SetError("Haptic: Unable to get if device supports gain: %s.",
364 FFStrError(ret));
365 }
366
367 /* Checks if supports autocenter. */
368 ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_AUTOCENTER,
369 &val, sizeof(val));
370 if (ret == FF_OK)
371 supported |= SDL_HAPTIC_AUTOCENTER;
372 else if (ret != FFERR_UNSUPPORTED) {
373 return SDL_SetError
374 ("Haptic: Unable to get if device supports autocenter: %s.",
375 FFStrError(ret));
376 }
377
378 /* Check for axes, we have an artificial limit on axes */
379 haptic->naxes = ((features.numFfAxes) > 3) ? 3 : features.numFfAxes;
380 /* Actually store the axes we want to use */
381 SDL_memcpy(haptic->hwdata->axes, features.ffAxes,
382 haptic->naxes * sizeof(Uint8));
383
384 /* Always supported features. */
385 supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE;
386
387 haptic->supported = supported;
388 return 0;;
389 }
390
391
392 /*
393 * Opens the haptic device from the file descriptor.
394 */
395 static int
396 SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
397 {
398 HRESULT ret;
399 int ret2;
400
401 /* Allocate the hwdata */
402 haptic->hwdata = (struct haptic_hwdata *)
403 SDL_malloc(sizeof(*haptic->hwdata));
404 if (haptic->hwdata == NULL) {
405 SDL_OutOfMemory();
406 goto creat_err;
407 }
408 SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
409
410 /* Open the device */
411 ret = FFCreateDevice(service, &haptic->hwdata->device);
412 if (ret != FF_OK) {
413 SDL_SetError("Haptic: Unable to create device from service: %s.",
414 FFStrError(ret));
415 goto creat_err;
416 }
417
418 /* Get supported features. */
419 ret2 = GetSupportedFeatures(haptic);
420 if (ret2 < 0) {
421 goto open_err;
422 }
423
424
425 /* Reset and then enable actuators. */
426 ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
427 FFSFFC_RESET);
428 if (ret != FF_OK) {
429 SDL_SetError("Haptic: Unable to reset device: %s.", FFStrError(ret));
430 goto open_err;
431 }
432 ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
433 FFSFFC_SETACTUATORSON);
434 if (ret != FF_OK) {
435 SDL_SetError("Haptic: Unable to enable actuators: %s.",
436 FFStrError(ret));
437 goto open_err;
438 }
439
440
441 /* Allocate effects memory. */
442 haptic->effects = (struct haptic_effect *)
443 SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
444 if (haptic->effects == NULL) {
445 SDL_OutOfMemory();
446 goto open_err;
447 }
448 /* Clear the memory */
449 SDL_memset(haptic->effects, 0,
450 sizeof(struct haptic_effect) * haptic->neffects);
451
452 return 0;
453
454 /* Error handling */
455 open_err:
456 FFReleaseDevice(haptic->hwdata->device);
457 creat_err:
458 if (haptic->hwdata != NULL) {
459 free(haptic->hwdata);
460 haptic->hwdata = NULL;
461 }
462 return -1;
463
464 }
465
466
467 /*
468 * Opens a haptic device for usage.
469 */
470 int
471 SDL_SYS_HapticOpen(SDL_Haptic * haptic)
472 {
473 return SDL_SYS_HapticOpenFromService(haptic,
474 SDL_hapticlist[haptic->index].dev);
475 }
476
477
478 /*
479 * Opens a haptic device from first mouse it finds for usage.
480 */
481 int
482 SDL_SYS_HapticMouse(void)
483 {
484 int i;
485
486 for (i = 0; i < SDL_numhaptics; i++) {
487 if ((SDL_hapticlist[i].usagePage == kHIDPage_GenericDesktop) &&
488 (SDL_hapticlist[i].usage == kHIDUsage_GD_Mouse))
489 return i;
490 }
491
492 return -1;
493 }
494
495
496 /*
497 * Checks to see if a joystick has haptic features.
498 */
499 int
500 SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick)
501 {
502 if (joystick->hwdata->ffservice != 0)
503 return SDL_TRUE;
504 return SDL_FALSE;
505 }
506
507
508 /*
509 * Checks to see if the haptic device and joystick are in reality the same.
510 */
511 int
512 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
513 {
514 if (IOObjectIsEqualTo((io_object_t) ((size_t)haptic->hwdata->device),
515 joystick->hwdata->ffservice))
516 return 1;
517 return 0;
518 }
519
520
521 /*
522 * Opens a SDL_Haptic from a SDL_Joystick.
523 */
524 int
525 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
526 {
527 int i;
528 for (i=0; i<SDL_numhaptics; i++) {
529 if (IOObjectIsEqualTo((io_object_t) SDL_hapticlist[i].dev,
530 joystick->hwdata->ffservice)) {
531 haptic->index = i;
532 break;
533 }
534 }
535 if (i >= SDL_numhaptics) {
536 return -1;
537 }
538
539 return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice);
540 }
541
542
543 /*
544 * Closes the haptic device.
545 */
546 void
547 SDL_SYS_HapticClose(SDL_Haptic * haptic)
548 {
549 if (haptic->hwdata) {
550
551 /* Free Effects. */
552 SDL_free(haptic->effects);
553 haptic->effects = NULL;
554 haptic->neffects = 0;
555
556 /* Clean up */
557 FFReleaseDevice(haptic->hwdata->device);
558
559 /* Free */
560 SDL_free(haptic->hwdata);
561 haptic->hwdata = NULL;
562 }
563 }
564
565
566 /*
567 * Clean up after system specific haptic stuff
568 */
569 void
570 SDL_SYS_HapticQuit(void)
571 {
572 int i;
573
574 for (i = 0; i < SDL_numhaptics; i++) {
575 /* Opened and not closed haptics are leaked, this is on purpose.
576 * Close your haptic devices after usage. */
577
578 /* Free the io_service_t */
579 IOObjectRelease(SDL_hapticlist[i].dev);
580 }
581 }
582
583
584 /*
585 * Converts an SDL trigger button to an FFEFFECT trigger button.
586 */
587 static DWORD
588 FFGetTriggerButton(Uint16 button)
589 {
590 DWORD dwTriggerButton;
591
592 dwTriggerButton = FFEB_NOTRIGGER;
593
594 if (button != 0) {
595 dwTriggerButton = FFJOFS_BUTTON(button - 1);
596 }
597
598 return dwTriggerButton;
599 }
600
601
602 /*
603 * Sets the direction.
604 */
605 static int
606 SDL_SYS_SetDirection(FFEFFECT * effect, SDL_HapticDirection * dir, int naxes)
607 {
608 LONG *rglDir;
609
610 /* Handle no axes a part. */
611 if (naxes == 0) {
612 effect->dwFlags |= FFEFF_SPHERICAL; /* Set as default. */
613 effect->rglDirection = NULL;
614 return 0;
615 }
616
617 /* Has axes. */
618 rglDir = SDL_malloc(sizeof(LONG) * naxes);
619 if (rglDir == NULL) {
620 return SDL_OutOfMemory();
621 }
622 SDL_memset(rglDir, 0, sizeof(LONG) * naxes);
623 effect->rglDirection = rglDir;
624
625 switch (dir->type) {
626 case SDL_HAPTIC_POLAR:
627 effect->dwFlags |= FFEFF_POLAR;
628 rglDir[0] = dir->dir[0];
629 return 0;
630 case SDL_HAPTIC_CARTESIAN:
631 effect->dwFlags |= FFEFF_CARTESIAN;
632 rglDir[0] = dir->dir[0];
633 if (naxes > 1)
634 rglDir[1] = dir->dir[1];
635 if (naxes > 2)
636 rglDir[2] = dir->dir[2];
637 return 0;
638 case SDL_HAPTIC_SPHERICAL:
639 effect->dwFlags |= FFEFF_SPHERICAL;
640 rglDir[0] = dir->dir[0];
641 if (naxes > 1)
642 rglDir[1] = dir->dir[1];
643 if (naxes > 2)
644 rglDir[2] = dir->dir[2];
645 return 0;
646
647 default:
648 return SDL_SetError("Haptic: Unknown direction type.");
649 }
650 }
651
652
653 /* Clamps and converts. */
654 #define CCONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF)
655 /* Just converts. */
656 #define CONVERT(x) (((x)*10000) / 0x7FFF)
657 /*
658 * Creates the FFEFFECT from a SDL_HapticEffect.
659 */
660 static int
661 SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest,
662 SDL_HapticEffect * src)
663 {
664 int i;
665 FFCONSTANTFORCE *constant;
666 FFPERIODIC *periodic;
667 FFCONDITION *condition; /* Actually an array of conditions - one per axis. */
668 FFRAMPFORCE *ramp;
669 FFCUSTOMFORCE *custom;
670 FFENVELOPE *envelope;
671 SDL_HapticConstant *hap_constant;
672 SDL_HapticPeriodic *hap_periodic;
673 SDL_HapticCondition *hap_condition;
674 SDL_HapticRamp *hap_ramp;
675 SDL_HapticCustom *hap_custom;
676 DWORD *axes;
677
678 /* Set global stuff. */
679 SDL_memset(dest, 0, sizeof(FFEFFECT));
680 dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */
681 dest->dwSamplePeriod = 0; /* Not used by us. */
682 dest->dwGain = 10000; /* Gain is set globally, not locally. */
683 dest->dwFlags = FFEFF_OBJECTOFFSETS; /* Seems obligatory. */
684
685 /* Envelope. */
686 envelope = SDL_malloc(sizeof(FFENVELOPE));
687 if (envelope == NULL) {
688 return SDL_OutOfMemory();
689 }
690 SDL_memset(envelope, 0, sizeof(FFENVELOPE));
691 dest->lpEnvelope = envelope;
692 envelope->dwSize = sizeof(FFENVELOPE); /* Always should be this. */
693
694 /* Axes. */
695 dest->cAxes = haptic->naxes;
696 if (dest->cAxes > 0) {
697 axes = SDL_malloc(sizeof(DWORD) * dest->cAxes);
698 if (axes == NULL) {
699 return SDL_OutOfMemory();
700 }
701 axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */
702 if (dest->cAxes > 1) {
703 axes[1] = haptic->hwdata->axes[1];
704 }
705 if (dest->cAxes > 2) {
706 axes[2] = haptic->hwdata->axes[2];
707 }
708 dest->rgdwAxes = axes;
709 }
710
711
712 /* The big type handling switch, even bigger then Linux's version. */
713 switch (src->type) {
714 case SDL_HAPTIC_CONSTANT:
715 hap_constant = &src->constant;
716 constant = SDL_malloc(sizeof(FFCONSTANTFORCE));
717 if (constant == NULL) {
718 return SDL_OutOfMemory();
719 }
720 SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE));
721
722 /* Specifics */
723 constant->lMagnitude = CONVERT(hap_constant->level);
724 dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE);
725 dest->lpvTypeSpecificParams = constant;
726
727 /* Generics */
728 dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */
729 dest->dwTriggerButton = FFGetTriggerButton(hap_constant->button);
730 dest->dwTriggerRepeatInterval = hap_constant->interval;
731 dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */
732
733 /* Direction. */
734 if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes)
735 < 0) {
736 return -1;
737 }
738
739 /* Envelope */
740 if ((hap_constant->attack_length == 0)
741 && (hap_constant->fade_length == 0)) {
742 SDL_free(envelope);
743 dest->lpEnvelope = NULL;
744 } else {
745 envelope->dwAttackLevel = CCONVERT(hap_constant->attack_level);
746 envelope->dwAttackTime = hap_constant->attack_length * 1000;
747 envelope->dwFadeLevel = CCONVERT(hap_constant->fade_level);
748 envelope->dwFadeTime = hap_constant->fade_length * 1000;
749 }
750
751 break;
752
753 case SDL_HAPTIC_SINE:
754 /* !!! FIXME: put this back when we have more bits in 2.1 */
755 /* case SDL_HAPTIC_SQUARE: */
756 case SDL_HAPTIC_TRIANGLE:
757 case SDL_HAPTIC_SAWTOOTHUP:
758 case SDL_HAPTIC_SAWTOOTHDOWN:
759 hap_periodic = &src->periodic;
760 periodic = SDL_malloc(sizeof(FFPERIODIC));
761 if (periodic == NULL) {
762 return SDL_OutOfMemory();
763 }
764 SDL_memset(periodic, 0, sizeof(FFPERIODIC));
765
766 /* Specifics */
767 periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
768 periodic->lOffset = CONVERT(hap_periodic->offset);
769 periodic->dwPhase = hap_periodic->phase;
770 periodic->dwPeriod = hap_periodic->period * 1000;
771 dest->cbTypeSpecificParams = sizeof(FFPERIODIC);
772 dest->lpvTypeSpecificParams = periodic;
773
774 /* Generics */
775 dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */
776 dest->dwTriggerButton = FFGetTriggerButton(hap_periodic->button);
777 dest->dwTriggerRepeatInterval = hap_periodic->interval;
778 dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */
779
780 /* Direction. */
781 if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes)
782 < 0) {
783 return -1;
784 }
785
786 /* Envelope */
787 if ((hap_periodic->attack_length == 0)
788 && (hap_periodic->fade_length == 0)) {
789 SDL_free(envelope);
790 dest->lpEnvelope = NULL;
791 } else {
792 envelope->dwAttackLevel = CCONVERT(hap_periodic->attack_level);
793 envelope->dwAttackTime = hap_periodic->attack_length * 1000;
794 envelope->dwFadeLevel = CCONVERT(hap_periodic->fade_level);
795 envelope->dwFadeTime = hap_periodic->fade_length * 1000;
796 }
797
798 break;
799
800 case SDL_HAPTIC_SPRING:
801 case SDL_HAPTIC_DAMPER:
802 case SDL_HAPTIC_INERTIA:
803 case SDL_HAPTIC_FRICTION:
804 hap_condition = &src->condition;
805 condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes);
806 if (condition == NULL) {
807 return SDL_OutOfMemory();
808 }
809 SDL_memset(condition, 0, sizeof(FFCONDITION));
810
811 /* Specifics */
812 for (i = 0; i < dest->cAxes; i++) {
813 condition[i].lOffset = CONVERT(hap_condition->center[i]);
814 condition[i].lPositiveCoefficient =
815 CONVERT(hap_condition->right_coeff[i]);
816 condition[i].lNegativeCoefficient =
817 CONVERT(hap_condition->left_coeff[i]);
818 condition[i].dwPositiveSaturation =
819 CCONVERT(hap_condition->right_sat[i]);
820 condition[i].dwNegativeSaturation =
821 CCONVERT(hap_condition->left_sat[i]);
822 condition[i].lDeadBand = CCONVERT(hap_condition->deadband[i]);
823 }
824 dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes;
825 dest->lpvTypeSpecificParams = condition;
826
827 /* Generics */
828 dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */
829 dest->dwTriggerButton = FFGetTriggerButton(hap_condition->button);
830 dest->dwTriggerRepeatInterval = hap_condition->interval;
831 dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */
832
833 /* Direction. */
834 if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes)
835 < 0) {
836 return -1;
837 }
838
839 /* Envelope - Not actually supported by most CONDITION implementations. */
840 SDL_free(dest->lpEnvelope);
841 dest->lpEnvelope = NULL;
842
843 break;
844
845 case SDL_HAPTIC_RAMP:
846 hap_ramp = &src->ramp;
847 ramp = SDL_malloc(sizeof(FFRAMPFORCE));
848 if (ramp == NULL) {
849 return SDL_OutOfMemory();
850 }
851 SDL_memset(ramp, 0, sizeof(FFRAMPFORCE));
852
853 /* Specifics */
854 ramp->lStart = CONVERT(hap_ramp->start);
855 ramp->lEnd = CONVERT(hap_ramp->end);
856 dest->cbTypeSpecificParams = sizeof(FFRAMPFORCE);
857 dest->lpvTypeSpecificParams = ramp;
858
859 /* Generics */
860 dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */
861 dest->dwTriggerButton = FFGetTriggerButton(hap_ramp->button);
862 dest->dwTriggerRepeatInterval = hap_ramp->interval;
863 dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */
864
865 /* Direction. */
866 if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) {
867 return -1;
868 }
869
870 /* Envelope */
871 if ((hap_ramp->attack_length == 0) && (hap_ramp->fade_length == 0)) {
872 SDL_free(envelope);
873 dest->lpEnvelope = NULL;
874 } else {
875 envelope->dwAttackLevel = CCONVERT(hap_ramp->attack_level);
876 envelope->dwAttackTime = hap_ramp->attack_length * 1000;
877 envelope->dwFadeLevel = CCONVERT(hap_ramp->fade_level);
878 envelope->dwFadeTime = hap_ramp->fade_length * 1000;
879 }
880
881 break;
882
883 case SDL_HAPTIC_CUSTOM:
884 hap_custom = &src->custom;
885 custom = SDL_malloc(sizeof(FFCUSTOMFORCE));
886 if (custom == NULL) {
887 return SDL_OutOfMemory();
888 }
889 SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE));
890
891 /* Specifics */
892 custom->cChannels = hap_custom->channels;
893 custom->dwSamplePeriod = hap_custom->period * 1000;
894 custom->cSamples = hap_custom->samples;
895 custom->rglForceData =
896 SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels);
897 for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */
898 custom->rglForceData[i] = CCONVERT(hap_custom->data[i]);
899 }
900 dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE);
901 dest->lpvTypeSpecificParams = custom;
902
903 /* Generics */
904 dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */
905 dest->dwTriggerButton = FFGetTriggerButton(hap_custom->button);
906 dest->dwTriggerRepeatInterval = hap_custom->interval;
907 dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */
908
909 /* Direction. */
910 if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) <
911 0) {
912 return -1;
913 }
914
915 /* Envelope */
916 if ((hap_custom->attack_length == 0)
917 && (hap_custom->fade_length == 0)) {
918 SDL_free(envelope);
919 dest->lpEnvelope = NULL;
920 } else {
921 envelope->dwAttackLevel = CCONVERT(hap_custom->attack_level);
922 envelope->dwAttackTime = hap_custom->attack_length * 1000;
923 envelope->dwFadeLevel = CCONVERT(hap_custom->fade_level);
924 envelope->dwFadeTime = hap_custom->fade_length * 1000;
925 }
926
927 break;
928
929
930 default:
931 return SDL_SetError("Haptic: Unknown effect type.");
932 }
933
934 return 0;
935 }
936
937
938 /*
939 * Frees an FFEFFECT allocated by SDL_SYS_ToFFEFFECT.
940 */
941 static void
942 SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type)
943 {
944 FFCUSTOMFORCE *custom;
945
946 SDL_free(effect->lpEnvelope);
947 effect->lpEnvelope = NULL;
948 SDL_free(effect->rgdwAxes);
949 effect->rgdwAxes = NULL;
950 if (effect->lpvTypeSpecificParams != NULL) {
951 if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */
952 custom = (FFCUSTOMFORCE *) effect->lpvTypeSpecificParams;
953 SDL_free(custom->rglForceData);
954 custom->rglForceData = NULL;
955 }
956 SDL_free(effect->lpvTypeSpecificParams);
957 effect->lpvTypeSpecificParams = NULL;
958 }
959 SDL_free(effect->rglDirection);
960 effect->rglDirection = NULL;
961 }
962
963
964 /*
965 * Gets the effect type from the generic SDL haptic effect wrapper.
966 */
967 CFUUIDRef
968 SDL_SYS_HapticEffectType(Uint16 type)
969 {
970 switch (type) {
971 case SDL_HAPTIC_CONSTANT:
972 return kFFEffectType_ConstantForce_ID;
973
974 case SDL_HAPTIC_RAMP:
975 return kFFEffectType_RampForce_ID;
976
977 /* !!! FIXME: put this back when we have more bits in 2.1 */
978 /* case SDL_HAPTIC_SQUARE:
979 return kFFEffectType_Square_ID; */
980
981 case SDL_HAPTIC_SINE:
982 return kFFEffectType_Sine_ID;
983
984 case SDL_HAPTIC_TRIANGLE:
985 return kFFEffectType_Triangle_ID;
986
987 case SDL_HAPTIC_SAWTOOTHUP:
988 return kFFEffectType_SawtoothUp_ID;
989
990 case SDL_HAPTIC_SAWTOOTHDOWN:
991 return kFFEffectType_SawtoothDown_ID;
992
993 case SDL_HAPTIC_SPRING:
994 return kFFEffectType_Spring_ID;
995
996 case SDL_HAPTIC_DAMPER:
997 return kFFEffectType_Damper_ID;
998
999 case SDL_HAPTIC_INERTIA:
1000 return kFFEffectType_Inertia_ID;
1001
1002 case SDL_HAPTIC_FRICTION:
1003 return kFFEffectType_Friction_ID;
1004
1005 case SDL_HAPTIC_CUSTOM:
1006 return kFFEffectType_CustomForce_ID;
1007
1008 default:
1009 SDL_SetError("Haptic: Unknown effect type.");
1010 return NULL;
1011 }
1012 }
1013
1014
1015 /*
1016 * Creates a new haptic effect.
1017 */
1018 int
1019 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
1020 SDL_HapticEffect * base)
1021 {
1022 HRESULT ret;
1023 CFUUIDRef type;
1024
1025 /* Alloc the effect. */
1026 effect->hweffect = (struct haptic_hweffect *)
1027 SDL_malloc(sizeof(struct haptic_hweffect));
1028 if (effect->hweffect == NULL) {
1029 SDL_OutOfMemory();
1030 goto err_hweffect;
1031 }
1032
1033 /* Get the type. */
1034 type = SDL_SYS_HapticEffectType(base->type);
1035 if (type == NULL) {
1036 goto err_hweffect;
1037 }
1038
1039 /* Get the effect. */
1040 if (SDL_SYS_ToFFEFFECT(haptic, &effect->hweffect->effect, base) < 0) {
1041 goto err_effectdone;
1042 }
1043
1044 /* Create the actual effect. */
1045 ret = FFDeviceCreateEffect(haptic->hwdata->device, type,
1046 &effect->hweffect->effect,
1047 &effect->hweffect->ref);
1048 if (ret != FF_OK) {
1049 SDL_SetError("Haptic: Unable to create effect: %s.", FFStrError(ret));
1050 goto err_effectdone;
1051 }
1052
1053 return 0;
1054
1055 err_effectdone:
1056 SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, base->type);
1057 err_hweffect:
1058 SDL_free(effect->hweffect);
1059 effect->hweffect = NULL;
1060 return -1;
1061 }
1062
1063
1064 /*
1065 * Updates an effect.
1066 */
1067 int
1068 SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
1069 struct haptic_effect *effect,
1070 SDL_HapticEffect * data)
1071 {
1072 HRESULT ret;
1073 FFEffectParameterFlag flags;
1074 FFEFFECT temp;
1075
1076 /* Get the effect. */
1077 SDL_memset(&temp, 0, sizeof(FFEFFECT));
1078 if (SDL_SYS_ToFFEFFECT(haptic, &temp, data) < 0) {
1079 goto err_update;
1080 }
1081
1082 /* Set the flags. Might be worthwhile to diff temp with loaded effect and
1083 * only change those parameters. */
1084 flags = FFEP_DIRECTION |
1085 FFEP_DURATION |
1086 FFEP_ENVELOPE |
1087 FFEP_STARTDELAY |
1088 FFEP_TRIGGERBUTTON |
1089 FFEP_TRIGGERREPEATINTERVAL | FFEP_TYPESPECIFICPARAMS;
1090
1091 /* Create the actual effect. */
1092 ret = FFEffectSetParameters(effect->hweffect->ref, &temp, flags);
1093 if (ret != FF_OK) {
1094 SDL_SetError("Haptic: Unable to update effect: %s.", FFStrError(ret));
1095 goto err_update;
1096 }
1097
1098 /* Copy it over. */
1099 SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, data->type);
1100 SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(FFEFFECT));
1101
1102 return 0;
1103
1104 err_update:
1105 SDL_SYS_HapticFreeFFEFFECT(&temp, data->type);
1106 return -1;
1107 }
1108
1109
1110 /*
1111 * Runs an effect.
1112 */
1113 int
1114 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
1115 Uint32 iterations)
1116 {
1117 HRESULT ret;
1118 Uint32 iter;
1119
1120 /* Check if it's infinite. */
1121 if (iterations == SDL_HAPTIC_INFINITY) {
1122 iter = FF_INFINITE;
1123 } else
1124 iter = iterations;
1125
1126 /* Run the effect. */
1127 ret = FFEffectStart(effect->hweffect->ref, iter, 0);
1128 if (ret != FF_OK) {
1129 return SDL_SetError("Haptic: Unable to run the effect: %s.",
1130 FFStrError(ret));
1131 }
1132
1133 return 0;
1134 }
1135
1136
1137 /*
1138 * Stops an effect.
1139 */
1140 int
1141 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
1142 {
1143 HRESULT ret;
1144
1145 ret = FFEffectStop(effect->hweffect->ref);
1146 if (ret != FF_OK) {
1147 return SDL_SetError("Haptic: Unable to stop the effect: %s.",
1148 FFStrError(ret));
1149 }
1150
1151 return 0;
1152 }
1153
1154
1155 /*
1156 * Frees the effect.
1157 */
1158 void
1159 SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
1160 {
1161 HRESULT ret;
1162
1163 ret =
1164 FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref);
1165 if (ret != FF_OK) {
1166 SDL_SetError("Haptic: Error removing the effect from the device: %s.",
1167 FFStrError(ret));
1168 }
1169 SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect,
1170 effect->effect.type);
1171 SDL_free(effect->hweffect);
1172 effect->hweffect = NULL;
1173 }
1174
1175
1176 /*
1177 * Gets the status of a haptic effect.
1178 */
1179 int
1180 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
1181 struct haptic_effect *effect)
1182 {
1183 HRESULT ret;
1184 FFEffectStatusFlag status;
1185
1186 ret = FFEffectGetEffectStatus(effect->hweffect->ref, &status);
1187 if (ret != FF_OK) {
1188 SDL_SetError("Haptic: Unable to get effect status: %s.",
1189 FFStrError(ret));
1190 return -1;
1191 }
1192
1193 if (status == 0)
1194 return SDL_FALSE;
1195 return SDL_TRUE; /* Assume it's playing or emulated. */
1196 }
1197
1198
1199 /*
1200 * Sets the gain.
1201 */
1202 int
1203 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
1204 {
1205 HRESULT ret;
1206 Uint32 val;
1207
1208 val = gain * 100; /* Mac OS X uses 0 to 10,000 */
1209 ret =
1210 FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
1211 FFPROP_FFGAIN, &val);
1212 if (ret != FF_OK) {
1213 return SDL_SetError("Haptic: Error setting gain: %s.", FFStrError(ret));
1214 }
1215
1216 return 0;
1217 }
1218
1219
1220 /*
1221 * Sets the autocentering.
1222 */
1223 int
1224 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
1225 {
1226 HRESULT ret;
1227 Uint32 val;
1228
1229 /* Mac OS X only has 0 (off) and 1 (on) */
1230 if (autocenter == 0)
1231 val = 0;
1232 else
1233 val = 1;
1234
1235 ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
1236 FFPROP_AUTOCENTER, &val);
1237 if (ret != FF_OK) {
1238 return SDL_SetError("Haptic: Error setting autocenter: %s.",
1239 FFStrError(ret));
1240 }
1241
1242 return 0;
1243 }
1244
1245
1246 /*
1247 * Pauses the device.
1248 */
1249 int
1250 SDL_SYS_HapticPause(SDL_Haptic * haptic)
1251 {
1252 HRESULT ret;
1253
1254 ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
1255 FFSFFC_PAUSE);
1256 if (ret != FF_OK) {
1257 return SDL_SetError("Haptic: Error pausing device: %s.", FFStrError(ret));
1258 }
1259
1260 return 0;
1261 }
1262
1263
1264 /*
1265 * Unpauses the device.
1266 */
1267 int
1268 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
1269 {
1270 HRESULT ret;
1271
1272 ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
1273 FFSFFC_CONTINUE);
1274 if (ret != FF_OK) {
1275 return SDL_SetError("Haptic: Error pausing device: %s.", FFStrError(ret));
1276 }
1277
1278 return 0;
1279 }
1280
1281
1282 /*
1283 * Stops all currently playing effects.
1284 */
1285 int
1286 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
1287 {
1288 HRESULT ret;
1289
1290 ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device,
1291 FFSFFC_STOPALL);
1292 if (ret != FF_OK) {
1293 return SDL_SetError("Haptic: Error stopping device: %s.", FFStrError(ret));
1294 }
1295
1296 return 0;
1297 }
1298
1299
1300 #endif /* SDL_HAPTIC_IOKIT */
SDL_SYS_HapticOpenFromJoystick
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
_SDL_Haptic::hwdata
struct haptic_hwdata * hwdata
Definition: SDL_syshaptic.h:52
SDL_HapticPeriodic::period
Uint16 period
Definition: SDL_haptic.h:555
SDL_HapticCondition::deadband
Uint16 deadband[3]
Definition: SDL_haptic.h:611
SDL_HapticDirection
Structure that represents a haptic direction.
Definition: SDL_haptic.h:439
condition
GLenum condition
Definition: gl2ext.h:1403
SDL_HapticCondition::delay
Uint16 delay
Definition: SDL_haptic.h:600
SDL_HapticConstant::interval
Uint16 interval
Definition: SDL_haptic.h:469
val
GLuint const GLfloat * val
Definition: glew.h:2715
_SDL_Haptic::effects
struct haptic_effect * effects
Definition: SDL_syshaptic.h:46
SDL_HAPTIC_SPHERICAL
#define SDL_HAPTIC_SPHERICAL
Uses spherical coordinates for the direction.
Definition: SDL_haptic.h:329
SDL_HapticConstant::fade_level
Uint16 fade_level
Definition: SDL_haptic.h:478
SDL_joystick.h
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
SDL_HAPTIC_AUTOCENTER
#define SDL_HAPTIC_AUTOCENTER
Device can set autocenter.
Definition: SDL_haptic.h:285
_SDL_Haptic::index
Uint8 index
Definition: SDL_syshaptic.h:44
SDL_HapticPeriodic
A structure containing a template for a Periodic effect.
Definition: SDL_haptic.h:538
NULL
#define NULL
Definition: ftobjs.h:61
SDL_HAPTIC_GAIN
#define SDL_HAPTIC_GAIN
Device can set global gain.
Definition: SDL_haptic.h:276
HRESULT
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
SDL_HAPTIC_CUSTOM
#define SDL_HAPTIC_CUSTOM
Custom effect is supported.
Definition: SDL_haptic.h:263
SDL_HAPTIC_TRIANGLE
#define SDL_HAPTIC_TRIANGLE
Triangle wave effect supported.
Definition: SDL_haptic.h:189
SDL_HapticCondition::direction
SDL_HapticDirection direction
Definition: SDL_haptic.h:596
SDL_SYS_HapticOpen
int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
SDL_HapticPeriodic::length
Uint32 length
Definition: SDL_haptic.h:547
SDL_HapticEffect::custom
SDL_HapticCustom custom
Definition: SDL_haptic.h:796
SDL_SYS_HapticMouse
int SDL_SYS_HapticMouse(void)
SDL_SYS_JoystickSameHaptic
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
_SDL_Haptic
Definition: SDL_syshaptic.h:42
SDL_HapticRamp::end
Sint16 end
Definition: SDL_haptic.h:644
SDL_HapticCondition::button
Uint16 button
Definition: SDL_haptic.h:603
SDL_TRUE
Definition: SDL_stdinc.h:119
SDL_HAPTIC_INERTIA
#define SDL_HAPTIC_INERTIA
Inertia effect supported - uses axes acceleration.
Definition: SDL_haptic.h:246
free
SDL_EventEntry * free
Definition: SDL_events.c:80
_SDL_Haptic::naxes
int naxes
Definition: SDL_syshaptic.h:50
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
SDL_HapticRamp::fade_level
Uint16 fade_level
Definition: SDL_haptic.h:650
SDL_HapticEffect::ramp
SDL_HapticRamp ramp
Definition: SDL_haptic.h:794
SDL_HapticCondition::interval
Uint16 interval
Definition: SDL_haptic.h:604
SDL_SYS_HapticStopEffect
int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
SDL_SYS_HapticName
const char * SDL_SYS_HapticName(int index)
SDL_HapticCondition
A structure containing a template for a Condition effect.
Definition: SDL_haptic.h:591
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
SDL_HapticPeriodic::fade_level
Uint16 fade_level
Definition: SDL_haptic.h:564
SDL_haptic.h
The SDL Haptic subsystem allows you to control haptic (force feedback) devices.
SDL_SYS_HapticUnpause
int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
SDL_HapticConstant::attack_length
Uint16 attack_length
Definition: SDL_haptic.h:475
SDL_HapticCondition::left_coeff
Sint16 left_coeff[3]
Definition: SDL_haptic.h:610
SDL_HapticCondition::right_sat
Uint16 right_sat[3]
Definition: SDL_haptic.h:607
SDL_HapticPeriodic::button
Uint16 button
Definition: SDL_haptic.h:551
SDL_HapticCustom::fade_length
Uint16 fade_length
Definition: SDL_haptic.h:714
SDL_HapticCondition::right_coeff
Sint16 right_coeff[3]
Definition: SDL_haptic.h:609
SDL_HapticDirection::type
Uint8 type
Definition: SDL_haptic.h:441
SDL_HAPTIC_SINE
#define SDL_HAPTIC_SINE
Sine wave effect supported.
Definition: SDL_haptic.h:166
SDL_FALSE
Definition: SDL_stdinc.h:118
SDL_HapticPeriodic::attack_level
Uint16 attack_level
Definition: SDL_haptic.h:562
SDL_SYS_HapticGetEffectStatus
int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
SDL_config.h
_SDL_Joystick::hwdata
struct joystick_hwdata * hwdata
Definition: SDL_sysjoystick.h:49
ret
ret
Definition: glew_str_glx.c:2
SDL_HapticCustom::data
Uint16 * data
Definition: SDL_haptic.h:709
SDL_HapticRamp::length
Uint32 length
Definition: SDL_haptic.h:635
SDL_HapticConstant
A structure containing a template for a Constant effect.
Definition: SDL_haptic.h:457
SDL_numhaptics
Uint8 SDL_numhaptics
Definition: SDL_haptic.c:28
_SDL_Haptic::neffects
int neffects
Definition: SDL_syshaptic.h:47
SDL_HAPTIC_INFINITY
#define SDL_HAPTIC_INFINITY
Used to play a device an infinite number of times.
Definition: SDL_haptic.h:344
SDL_HapticRamp::interval
Uint16 interval
Definition: SDL_haptic.h:640
SDL_HAPTIC_CARTESIAN
#define SDL_HAPTIC_CARTESIAN
Uses cartesian coordinates for the direction.
Definition: SDL_haptic.h:322
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
SDL_HapticPeriodic::fade_length
Uint16 fade_length
Definition: SDL_haptic.h:563
_SDL_Haptic::supported
unsigned int supported
Definition: SDL_syshaptic.h:49
SDL_HapticEffect::condition
SDL_HapticCondition condition
Definition: SDL_haptic.h:793
joystick_hwdata::ffservice
io_service_t ffservice
Definition: SDL_sysjoystick_c.h:60
result
GLuint64EXT * result
Definition: glew.h:12708
SDL_HapticConstant::level
Sint16 level
Definition: SDL_haptic.h:472
SDL_HapticEffect
The generic template for any haptic effect.
Definition: SDL_haptic.h:787
SDL_HapticConstant::delay
Uint16 delay
Definition: SDL_haptic.h:465
SDL_HAPTIC_CONSTANT
#define SDL_HAPTIC_CONSTANT
Constant effect supported.
Definition: SDL_haptic.h:157
SDL_SYS_HapticSetAutocenter
int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
SDL_HapticConstant::attack_level
Uint16 attack_level
Definition: SDL_haptic.h:476
SDL_HapticCondition::length
Uint32 length
Definition: SDL_haptic.h:599
SDL_HapticPeriodic::offset
Sint16 offset
Definition: SDL_haptic.h:557
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
SDL_HapticCustom::button
Uint16 button
Definition: SDL_haptic.h:702
haptic_effect
Definition: SDL_syshaptic.h:33
SDL_HAPTIC_POLAR
#define SDL_HAPTIC_POLAR
Uses polar coordinates for the direction.
Definition: SDL_haptic.h:315
SDL_HapticCustom::period
Uint16 period
Definition: SDL_haptic.h:707
SDL_memset
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
SDL_HapticCustom::fade_level
Uint16 fade_level
Definition: SDL_haptic.h:715
SDL_HapticEffect::constant
SDL_HapticConstant constant
Definition: SDL_haptic.h:791
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
SDL_HAPTIC_PAUSE
#define SDL_HAPTIC_PAUSE
Device can be paused.
Definition: SDL_haptic.h:302
SDL_malloc
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
index
GLuint index
Definition: glew.h:1800
SDL_SYS_HapticUpdateEffect
int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
SDL_HapticDirection::dir
Sint32 dir[3]
Definition: SDL_haptic.h:442
SDL_HapticCustom::length
Uint32 length
Definition: SDL_haptic.h:698
SDL_SYS_JoystickIsHaptic
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
SDL_HapticConstant::length
Uint32 length
Definition: SDL_haptic.h:464
SDL_HapticRamp::direction
SDL_HapticDirection direction
Definition: SDL_haptic.h:632
SDL_HapticConstant::button
Uint16 button
Definition: SDL_haptic.h:468
SDL_HapticEffect::type
Uint16 type
Definition: SDL_haptic.h:790
SDL_HapticRamp
A structure containing a template for a Ramp effect.
Definition: SDL_haptic.h:628
SDL_SYS_HapticDestroyEffect
void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
SDL_HapticRamp::attack_length
Uint16 attack_length
Definition: SDL_haptic.h:647
SDL_HapticRamp::fade_length
Uint16 fade_length
Definition: SDL_haptic.h:649
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_HapticRamp::delay
Uint16 delay
Definition: SDL_haptic.h:636
haptic_effect::effect
SDL_HapticEffect effect
Definition: SDL_syshaptic.h:35
SDL_HapticCustom::delay
Uint16 delay
Definition: SDL_haptic.h:699
SDL_SYS_HapticInit
int SDL_SYS_HapticInit(void)
SDL_SYS_HapticQuit
void SDL_SYS_HapticQuit(void)
haptic_effect::hweffect
struct haptic_hweffect * hweffect
Definition: SDL_syshaptic.h:36
SDL_HAPTIC_STATUS
#define SDL_HAPTIC_STATUS
Device can be queried for effect status.
Definition: SDL_haptic.h:294
SDL_SYS_HapticClose
void SDL_SYS_HapticClose(SDL_Haptic *haptic)
SDL_SYS_HapticPause
int SDL_SYS_HapticPause(SDL_Haptic *haptic)
SDL_memcpy
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
SDL_HapticPeriodic::direction
SDL_HapticDirection direction
Definition: SDL_haptic.h:544
flags
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
SDL_HapticPeriodic::magnitude
Sint16 magnitude
Definition: SDL_haptic.h:556
SDL_HapticCustom::attack_level
Uint16 attack_level
Definition: SDL_haptic.h:713
SDL_HapticCustom::samples
Uint16 samples
Definition: SDL_haptic.h:708
SDL_HAPTIC_RAMP
#define SDL_HAPTIC_RAMP
Ramp effect supported.
Definition: SDL_haptic.h:216
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
SDL_HAPTIC_SPRING
#define SDL_HAPTIC_SPRING
Spring effect supported - uses axes position.
Definition: SDL_haptic.h:226
_SDL_Haptic::nplaying
int nplaying
Definition: SDL_syshaptic.h:48
DWORD
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
SDL_HapticPeriodic::attack_length
Uint16 attack_length
Definition: SDL_haptic.h:561
SDL_HapticRamp::start
Sint16 start
Definition: SDL_haptic.h:643
_SDL_Joystick
Definition: SDL_sysjoystick.h:29
SDL_HapticPeriodic::delay
Uint16 delay
Definition: SDL_haptic.h:548
SDL_HapticPeriodic::interval
Uint16 interval
Definition: SDL_haptic.h:552
SDL_HapticCustom
A structure containing a template for the SDL_HAPTIC_CUSTOM effect.
Definition: SDL_haptic.h:691
SDL_SYS_HapticStopAll
int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
SDL_HapticCondition::center
Sint16 center[3]
Definition: SDL_haptic.h:612
Uint16
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
ref
GLclampf ref
Definition: gl2ext.h:1455
SDL_HAPTIC_SAWTOOTHUP
#define SDL_HAPTIC_SAWTOOTHUP
Sawtoothup wave effect supported.
Definition: SDL_haptic.h:198
SDL_SYS_HapticSetGain
int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
src
GLenum src
Definition: glew.h:2396
i
int i
Definition: pngrutil.c:1377
SDL_SYS_HapticRunEffect
int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
SDL_HapticEffect::periodic
SDL_HapticPeriodic periodic
Definition: SDL_haptic.h:792
SDL_HapticRamp::attack_level
Uint16 attack_level
Definition: SDL_haptic.h:648
SDL_HapticCustom::attack_length
Uint16 attack_length
Definition: SDL_haptic.h:712
SDL_HapticRamp::button
Uint16 button
Definition: SDL_haptic.h:639
usage
GLsizeiptr const GLvoid GLenum usage
Definition: glew.h:1667
SDL_HAPTIC_FRICTION
#define SDL_HAPTIC_FRICTION
Friction effect supported - uses axes movement.
Definition: SDL_haptic.h:256
SDL_HAPTIC_SAWTOOTHDOWN
#define SDL_HAPTIC_SAWTOOTHDOWN
Sawtoothdown wave effect supported.
Definition: SDL_haptic.h:207
SDL_HapticPeriodic::phase
Uint16 phase
Definition: SDL_haptic.h:558
SDL_HapticConstant::fade_length
Uint16 fade_length
Definition: SDL_haptic.h:477
SDL_HapticConstant::direction
SDL_HapticDirection direction
Definition: SDL_haptic.h:461
SDL_HapticCustom::direction
SDL_HapticDirection direction
Definition: SDL_haptic.h:695
SDL_HapticCustom::channels
Uint8 channels
Definition: SDL_haptic.h:706
SDL_SYS_HapticNewEffect
int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)
SDL_HAPTIC_DAMPER
#define SDL_HAPTIC_DAMPER
Damper effect supported - uses axes velocity.
Definition: SDL_haptic.h:236
SDL_HapticCustom::interval
Uint16 interval
Definition: SDL_haptic.h:703
SDL_HapticCondition::left_sat
Uint16 left_sat[3]
Definition: SDL_haptic.h:608