Mercurial > sdl-ios-xcode
comparison src/haptic/darwin/SDL_syshaptic.c @ 2520:6aee9eb4fc6d gsoc2008_force_feedback
Adding initial darwin port of haptic subsystem - broken atm.
author | Edgar Simo <bobbens@gmail.com> |
---|---|
date | Tue, 15 Jul 2008 16:35:14 +0000 |
parents | |
children | 7aa91c21ce5f |
comparison
equal
deleted
inserted
replaced
2519:af9df9662807 | 2520:6aee9eb4fc6d |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 2008 Edgar Simo | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 #include "SDL_config.h" | |
23 | |
24 #ifdef SDL_HAPTIC_IOKIT | |
25 | |
26 #include "SDL_haptic.h" | |
27 #include "../SDL_syshaptic.h" | |
28 #include "SDL_joystick.h" | |
29 #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ | |
30 /*#include "../../joystick/dawrin/SDL_sysjoystick_c.h"*/ /* For joystick hwdata */ | |
31 | |
32 #include <ForceFeedback/ForceFeedback.h> | |
33 #include <ForceFeedback/ForceFeedbackConstants.h> | |
34 | |
35 | |
36 #define MAX_HAPTICS 32 | |
37 | |
38 | |
39 /* | |
40 * List of available haptic devices. | |
41 */ | |
42 static struct | |
43 { | |
44 io_service_t dev; | |
45 SDL_Haptic *haptic; | |
46 } SDL_hapticlist[MAX_HAPTICS]; | |
47 | |
48 | |
49 /* | |
50 * Haptic system hardware data. | |
51 */ | |
52 struct haptic_hwdata | |
53 { | |
54 FFDeviceObjectReference device; /* Hardware device. */ | |
55 }; | |
56 | |
57 | |
58 /* | |
59 * Haptic system effect data. | |
60 */ | |
61 struct haptic_hweffect | |
62 { | |
63 FFEffectObjectReference ref; /* Reference. */ | |
64 struct FFEFFECT effect; /* Hardware effect. */ | |
65 }; | |
66 | |
67 | |
68 /* | |
69 * Initializes the haptic subsystem. | |
70 */ | |
71 int | |
72 SDL_SYS_HapticInit(void) | |
73 { | |
74 int numhaptics; | |
75 IOReturn result; | |
76 io_iterator_t iter; | |
77 CFDictionaryRef match; | |
78 io_sercive_t device; | |
79 | |
80 /* Get HID devices. */ | |
81 match = IOServiceMatching(kIOHIDDeviceKey); | |
82 if (match == NULL) { | |
83 SDL_SetError("Haptic: Failed to get IOServiceMatching."); | |
84 return -1; | |
85 } | |
86 | |
87 /* Now search I/O Registry for matching devices. */ | |
88 result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter); | |
89 if (result != kIOReturnSuccess) { | |
90 SDL_SetError("Haptic: Couldn't create a HID object iterator."); | |
91 return -1; | |
92 } | |
93 /* IOServiceGetMatchingServices consumes dictionary. */ | |
94 | |
95 numhaptics = 0; | |
96 while ((device = IOIteratorNext(iter)) != IO_OBJECT_NULL) { | |
97 | |
98 /* Check for force feedback. */ | |
99 if (FFIsForceFeedback(device) == FF_OK) { | |
100 SDL_hapticlist[numhaptics].dev = device; | |
101 SDL_hapticlist[numhaptics].haptic = NULL; | |
102 numhaptics++; | |
103 } | |
104 | |
105 /* Reached haptic limit. */ | |
106 if (numhaptics >= MAX_HAPTICS) | |
107 break; | |
108 } | |
109 IOObjectRelease(iter); | |
110 | |
111 return numhaptics; | |
112 } | |
113 | |
114 | |
115 /* | |
116 * Return the name of a haptic device, does not need to be opened. | |
117 */ | |
118 const char * | |
119 SDL_SYS_HapticName(int index) | |
120 { | |
121 return NULL; | |
122 } | |
123 | |
124 | |
125 #define FF_TEST(ff, s) \ | |
126 if (features.supportedEffects & ff) supported |= s | |
127 /* | |
128 * Gets supported features. | |
129 */ | |
130 static unsigned int | |
131 GetSupportedFeatures(FFDeviceObjectReference device, | |
132 int *neffects, int *nplaying) | |
133 { | |
134 HRESULT ret; | |
135 FFCAPABILITIES features; | |
136 unsigned int supported; | |
137 Uint32 val; | |
138 | |
139 ret = FFDeviceGetForceFeedbackCapabilities(device, &features); | |
140 if (ret != FF_OK) { | |
141 SDL_SetError("Haptic: Unable to get device's supported features."); | |
142 return 0; | |
143 } | |
144 | |
145 supported = 0; | |
146 | |
147 /* Get maximum effects. */ | |
148 *neffects = features.storageCapacity; | |
149 *nplaying = features.playbackCapacity; | |
150 | |
151 /* Test for effects. */ | |
152 FF_TEST(FFCAP_ET_CONSTANTFORCE, SDL_HAPTIC_CONSTANT); | |
153 FF_TEST(FFCAP_ET_RAMPFORCE, SDL_HAPTIC_RAMP); | |
154 FF_TEST(FFCAP_ET_SQUARE, SDL_HAPTIC_SQUARE); | |
155 FF_TEST(FFCAP_ET_SINE, SDL_HAPTIC_SINE); | |
156 FF_TEST(FFCAP_ET_TRIANGLE, SDL_HAPTIC_TRIANGLE); | |
157 FF_TEST(FFCAP_ET_SAWTOOTHUP, SDL_HAPTIC_SAWTOOTHUP); | |
158 FF_TEST(FFCAP_ET_SAWTOOTHDOWN, SDL_HAPTIC_SAWTOOTHDOWN); | |
159 FF_TEST(FFCAP_ET_SPRING, SDL_HAPTIC_SPRING); | |
160 FF_TEST(FFCAP_ET_DAMPER, SDL_HAPTIC_DAMPER); | |
161 FF_TEST(FFCAP_ET_INERTIA, SDL_HAPTIC_INERTIA); | |
162 FF_TEST(FFCAP_ET_FRICTION, SDL_HAPTIC_FRICTION); | |
163 FF_TEST(FFCAP_ET_CUSTOMFORCE, SDL_HAPTIC_CUSTOM); | |
164 | |
165 /* Check if supports gain. */ | |
166 ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFGAIN, | |
167 val, sizeof(val)); | |
168 if (ret == FF_OK) supported |= SDL_HAPTIC_GAIN; | |
169 else if (ret != FFERR_UNSUPPORTED) { | |
170 SDL_SetError("Haptic: Unable to get if device supports gain."); | |
171 return 0; | |
172 } | |
173 | |
174 /* Checks if supports autocenter. */ | |
175 ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFAUTOCENTER, | |
176 val, sizeof(val)); | |
177 if (ret == FF_OK) supported |= SDL_HAPTIC_AUTOCENTER; | |
178 else if (ret != FFERR_UNSUPPORTED) { | |
179 SDL_SetError("Haptic: Unable to get if device supports autocenter."); | |
180 return 0; | |
181 } | |
182 | |
183 /* Always supported features. */ | |
184 supported |= SDL_HAPTIC_STATUS; | |
185 return supported; | |
186 } | |
187 | |
188 | |
189 /* | |
190 * Opens the haptic device from the file descriptor. | |
191 */ | |
192 static int | |
193 SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service) | |
194 { | |
195 /* Allocate the hwdata */ | |
196 haptic->hwdata = (struct haptic_hwdata *) | |
197 SDL_malloc(sizeof(*haptic->hwdata)); | |
198 if (haptic->hwdata == NULL) { | |
199 SDL_OutOfMemory(); | |
200 goto creat_err; | |
201 } | |
202 SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); | |
203 | |
204 /* Open the device */ | |
205 if (FFCreateDevice( &service, &haptic->hwdata->device ) != FF_OK) { | |
206 SDL_SetError("Haptic: Unable to create device from service."); | |
207 goto creat_err; | |
208 } | |
209 | |
210 /* Get supported features. */ | |
211 haptic->supported = GetSupportedFeatures(haptic->hwdata->device, | |
212 &haptic->neffects, &haptic->nplaying); | |
213 if (haptic->supported == 0) { /* Error since device supports nothing. */ | |
214 goto open_err; | |
215 } | |
216 haptic->effects = (struct haptic_effect *) | |
217 SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); | |
218 if (haptic->effects == NULL) { | |
219 SDL_OutOfMemory(); | |
220 goto open_err; | |
221 } | |
222 /* Clear the memory */ | |
223 SDL_memset(haptic->effects, 0, | |
224 sizeof(struct haptic_effect) * haptic->neffects); | |
225 | |
226 return 0; | |
227 | |
228 /* Error handling */ | |
229 open_err: | |
230 FFReleaseDevice(haptic->hwdata->device); | |
231 creat_err: | |
232 if (haptic->hwdata != NULL) { | |
233 free(haptic->hwdata); | |
234 haptic->hwdata = NULL; | |
235 } | |
236 return -1; | |
237 | |
238 } | |
239 | |
240 | |
241 /* | |
242 * Opens a haptic device for usage. | |
243 */ | |
244 int | |
245 SDL_SYS_HapticOpen(SDL_Haptic * haptic) | |
246 { | |
247 return SDL_SYS_HapticOpenFromService(haptic, | |
248 SDL_hapticlist[haptic->index].device); | |
249 } | |
250 | |
251 | |
252 /* | |
253 * Opens a haptic device from first mouse it finds for usage. | |
254 */ | |
255 int | |
256 SDL_SYS_HapticMouse(void) | |
257 { | |
258 return -1; | |
259 } | |
260 | |
261 | |
262 /* | |
263 * Checks to see if a joystick has haptic features. | |
264 */ | |
265 int | |
266 SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) | |
267 { | |
268 return SDL_FALSE; | |
269 } | |
270 | |
271 | |
272 /* | |
273 * Checks to see if the haptic device and joystick and in reality the same. | |
274 */ | |
275 int | |
276 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) | |
277 { | |
278 if (SDL_strcmp(joystick->name,haptic->name)==0) { | |
279 return 1; | |
280 } | |
281 return 0; | |
282 } | |
283 | |
284 | |
285 /* | |
286 * Opens a SDL_Haptic from a SDL_Joystick. | |
287 */ | |
288 int | |
289 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) | |
290 { | |
291 return -1; | |
292 } | |
293 | |
294 | |
295 /* | |
296 * Closes the haptic device. | |
297 */ | |
298 void | |
299 SDL_SYS_HapticClose(SDL_Haptic * haptic) | |
300 { | |
301 int i; | |
302 | |
303 if (haptic->hwdata) { | |
304 | |
305 /* Clean up */ | |
306 FFReleaseDevice(haptic->hwdata->device); | |
307 | |
308 /* Free */ | |
309 SDL_free(haptic->hwdata); | |
310 haptic->hwdata = NULL; | |
311 for (i=0; i<haptic->neffects; i++) { | |
312 if (haptic->effects[i].hweffect != NULL) | |
313 SDL_free(haptic->effects[i].hweffect->effect.lpvTypeSpecificParams); | |
314 } | |
315 SDL_free(haptic->effects); | |
316 haptic->neffects = 0; | |
317 } | |
318 } | |
319 | |
320 | |
321 /* | |
322 * Clean up after system specific haptic stuff | |
323 */ | |
324 void | |
325 SDL_SYS_HapticQuit(void) | |
326 { | |
327 int i; | |
328 | |
329 for (i=0; i < SDL_numhaptics; i++) { | |
330 IOObjectRelease(SDL_hapticlist[i].dev); | |
331 /* TODO free effects. */ | |
332 } | |
333 } | |
334 | |
335 | |
336 /* | |
337 * Sets the direction. | |
338 */ | |
339 static int | |
340 SDL_SYS_SetDirection( FFEFFECT * effect, SDL_HapticDirection *dir, int axes ) | |
341 { | |
342 LONG *dir; | |
343 dir = SDL_malloc( sizeof(LONG) * axes ); | |
344 if (dir == NULL) { | |
345 SDL_OutOfMemory(); | |
346 return -1; | |
347 } | |
348 SDL_memset( dir, 0, sizeof(LONG) * axes ); | |
349 effect->rglDirection = dir; | |
350 | |
351 switch (dir->type) { | |
352 case SDL_HAPTIC_POLAR: | |
353 effect->dwFlags |= FFEFF_POLAR; | |
354 dir[0] = dir->dir[0]; | |
355 return 0; | |
356 case SDL_HAPTIC_CARTESIAN: | |
357 effects->dwFlags |= FFEFF_CARTESIAN; | |
358 dir[0] = dir->dir[0]; | |
359 dir[1] = dir->dir[1]; | |
360 dir[2] = dir->dir[2]; | |
361 return 0; | |
362 case SDL_HAPTIC_SHPERICAL: | |
363 effects->dwFlags |= FFEFF_SPHERICAL; | |
364 dir[0] = dir->dir[0]; | |
365 dir[1] = dir->dir[1]; | |
366 dir[2] = dir->dir[2]; | |
367 return 0; | |
368 | |
369 default: | |
370 SDL_SetError("Haptic: Unknown direction type."); | |
371 return -1; | |
372 } | |
373 } | |
374 | |
375 #define CONVERT(x) (((x)*10000) / 0xFFFF ) | |
376 /* | |
377 * Creates the FFStruct | |
378 */ | |
379 static int | |
380 SDL_SYS_ToFFEFFECT( FFEFFECT * dest, SDL_HapticEffect * src ) | |
381 { | |
382 FFCONSTANTFORCE *constant; | |
383 FFPERIODIC *periodic; | |
384 FFCONDITION *condition; | |
385 FFRAMPFORCE *ramp; | |
386 FFCUSTOMFORCE *custom; | |
387 SDL_HapticConstant *hap_constant; | |
388 SDL_HapticPeriodic *hap-periodic; | |
389 SDL_HapticCondition *hap_condition; | |
390 SDL_HapticRamp *hap_ramp; | |
391 | |
392 /* Set global stuff. */ | |
393 SDL_memset(dest, 0, sizeof(FFEFFECT)); | |
394 dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */ | |
395 dest->dwSamplePeriod = 0; /* Not used by us. */ | |
396 dest->dwGain = 10000; /* Gain is set globally, not locally. */ | |
397 dest->lpEnvelope.dwSize = sizeof(FFENVELOPE); /* Always should be this. */ | |
398 | |
399 switch (src->type) { | |
400 case SDL_HAPTIC_CONSTANT: | |
401 hap_constant = &src->constant; | |
402 constant = SDL_malloc( sizeof(FFCONSTANTFORCE) ); | |
403 | |
404 /* Specifics */ | |
405 constant->lMagnitude = CONVERT(hap_constant->level); | |
406 dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE); | |
407 dest->lpvTypeSpecificParams = constant; | |
408 | |
409 /* Generics */ | |
410 dest->dwDuration = src->length * 1000; /* In microseconds. */ | |
411 dest->dwTriggerButton = FFJOFS_BUTTON(hap_constant->button); | |
412 dest->dwTriggerRepeatInterval = hap_constant->interval; | |
413 dest->dwStartDelay = src->delay * 1000; /* In microseconds. */ | |
414 | |
415 /* Axes */ | |
416 dest->cAxes = 2; /* TODO handle */ | |
417 dest->rgdwAxes = 0; | |
418 | |
419 /* Direction. */ | |
420 if (SDL_SYS_SetDirection(dest, hap_constant->direction, dest->cAxes) < 0) { | |
421 return -1; | |
422 } | |
423 | |
424 /* Envelope */ | |
425 dest->lpEnvelope.dwAttackLevel = CONVERT(hap_constant->attack_level); | |
426 dest->lpEnvelope.dwAttackTime = hap_constant->attack_length * 1000; | |
427 dest->lpEnvelope.dwFadeLevel = CONVERT(hap_constant->fade_level); | |
428 dest->lpEnvelope.dwFadeTime = hap_constant->fade_length * 1000; | |
429 | |
430 break; | |
431 | |
432 /* TODO finish */ | |
433 | |
434 case SDL_HAPTIC_SINE: | |
435 case SDL_HAPTIC_SQUARE: | |
436 case SDL_HAPTIC_TRIANGLE: | |
437 case SDL_HAPTIC_SAWTOOTHUP: | |
438 case SDL_HAPTIC_SAWTOOTHDOWN: | |
439 periodic = &src->periodic; | |
440 | |
441 break; | |
442 | |
443 case SDL_HAPTIC_SPRING: | |
444 case SDL_HAPTIC_DAMPER: | |
445 case SDL_HAPTIC_INERTIA: | |
446 case SDL_HAPTIC_FRICTION: | |
447 condition = &src->condition; | |
448 | |
449 break; | |
450 | |
451 case SDL_HAPTIC_RAMP: | |
452 ramp = &src->ramp; | |
453 | |
454 break; | |
455 | |
456 | |
457 default: | |
458 SDL_SetError("Haptic: Unknown effect type."); | |
459 return -1; | |
460 } | |
461 | |
462 return 0; | |
463 } | |
464 | |
465 | |
466 /* | |
467 * Gets the effect type from the generic SDL haptic effect wrapper. | |
468 */ | |
469 CFUUIDRef SDL_SYS_HapticEffectType(struct haptic_effect * effect) | |
470 { | |
471 switch (effect->effect->type) { | |
472 case SDL_HAPTIC_CONSTANT: | |
473 return kFFEffectType_ConstantForce_ID; | |
474 | |
475 case SDL_HAPTIC_RAMP: | |
476 return kFFEffectType_RampForce_ID; | |
477 | |
478 case SDL_HAPTIC_SQUARE: | |
479 return kFFEffectType_Square_ID; | |
480 | |
481 case SDL_HAPTIC_SINE: | |
482 return kFFEffectType_Sine_ID; | |
483 | |
484 case SDL_HAPTIC_TRIANGLE; | |
485 return kFFEffectType_Triangle_ID; | |
486 | |
487 case SDL_HAPTIC_SAWTOOTHUP: | |
488 return kFFEffectType_SawtoothUp_ID; | |
489 | |
490 case SDL_HAPTIC_SAWTOOTHDOWN: | |
491 return kFFEffectType_SawtoothDown_ID; | |
492 | |
493 case SDL_HAPTIC_SPRING: | |
494 return kFFEffectType_Spring_ID; | |
495 | |
496 case SDL_HAPTIC_DAMPER: | |
497 return kFFEffectType_Damper_ID; | |
498 | |
499 case SDL_HAPTIC_INERTIA: | |
500 return kFFEffectType_Inertia_ID; | |
501 | |
502 case SDL_HAPTIC_FRICTION: | |
503 return kFFEffectType_Friction_ID; | |
504 | |
505 case SDL_HAPTIC_CUSTOM: | |
506 return kFFEffectType_CustomForce_ID; | |
507 | |
508 default: | |
509 SDL_SetError("Haptic: Unknown effect type."); | |
510 return NULL; | |
511 } | |
512 } | |
513 | |
514 | |
515 /* | |
516 * Creates a new haptic effect. | |
517 */ | |
518 int | |
519 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect, | |
520 SDL_HapticEffect * base) | |
521 { | |
522 HRESULT ret; | |
523 CFUUIDRef type; | |
524 | |
525 /* Alloc the effect. */ | |
526 effect->hweffect = (struct haptic_hweffect *) | |
527 SDL_malloc(sizeof(struct haptic_hweffect)); | |
528 if (effect->hweffect == NULL) { | |
529 SDL_OutOfMemory(); | |
530 return -1; | |
531 } | |
532 | |
533 /* Get the type. */ | |
534 type = SDL_SYS_HapticEffectType(effect); | |
535 if (type == NULL) { | |
536 SDL_free(effect->hweffect); | |
537 effect->hweffect = NULL; | |
538 return -1; | |
539 } | |
540 | |
541 /* Get the effect. */ | |
542 if (SDL_SYS_ToFFEFFECT( &effect->hweffect->effect, &haptic_effect->effect ) < 0) { | |
543 /* TODO cleanup alloced stuff. */ | |
544 return -1; | |
545 } | |
546 | |
547 ret = FFDeviceCreateEffect( haptic->hwdata->device, type, | |
548 &effect->hweffect->effect, &effect->hweffect->ref ); | |
549 } | |
550 | |
551 | |
552 /* | |
553 * Updates an effect. | |
554 */ | |
555 int SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, | |
556 struct haptic_effect * effect, SDL_HapticEffect * data) | |
557 { | |
558 /* TODO */ | |
559 return -1; | |
560 } | |
561 | |
562 | |
563 /* | |
564 * Runs an effect. | |
565 */ | |
566 int | |
567 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect * effect, | |
568 Uint32 iterations) | |
569 { | |
570 HRESULT ret; | |
571 Uint32 iter; | |
572 | |
573 /* Check if it's infinite. */ | |
574 if (iterations == SDL_HAPTIC_INFINITY) { | |
575 iter = INFINITE; | |
576 } | |
577 else | |
578 iter = iterations; | |
579 | |
580 /* Run the effect. */ | |
581 ret = FFEffectStart(effect->hweffect->ref, iter, 0); | |
582 if (ret != FF_OK) { | |
583 SDL_SetError("Haptic: Unable to run the effect."); | |
584 return -1; | |
585 } | |
586 | |
587 return 0; | |
588 } | |
589 | |
590 | |
591 /* | |
592 * Stops an effect. | |
593 */ | |
594 int | |
595 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect * effect) | |
596 { | |
597 HRESULT ret; | |
598 | |
599 ret = FFEffectStop(effect->hweffect->ref); | |
600 if (ret != FF_OK) { | |
601 SDL_SetError("Haptic: Unable to stop the effect."); | |
602 return -1; | |
603 } | |
604 | |
605 return 0; | |
606 } | |
607 | |
608 | |
609 /* | |
610 * Frees the effect. | |
611 */ | |
612 void | |
613 SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect * effect) | |
614 { | |
615 HRESULT ret; | |
616 | |
617 ret = FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref); | |
618 if (ret != FF_OK) { | |
619 SDL_SetError("Haptic: Error removing the effect from the device."); | |
620 } | |
621 SDL_free(effect->hweffect->effect.lpvTypeSpecificParams); | |
622 effect->hweffect->effect.lpvTypeSpecificParams = NULL; | |
623 SDL_free(effect->hweffect); | |
624 effect->hweffect = NULL; | |
625 } | |
626 | |
627 | |
628 /* | |
629 * Gets the status of a haptic effect. | |
630 */ | |
631 int | |
632 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect * effect) | |
633 { | |
634 HRESULT ret; | |
635 FFEffectStatusFlag status; | |
636 | |
637 ret = FFEffectGetEffectStatus(effect->hweffect.ref, &status); | |
638 if (ret != FF_OK) { | |
639 SDL_SetError("Haptic: Unable to get effect status."); | |
640 return -1; | |
641 } | |
642 | |
643 if (status == 0) return SDL_FALSE; | |
644 return SDL_TRUE; /* Assume it's playing or emulated. */ | |
645 } | |
646 | |
647 | |
648 /* | |
649 * Sets the gain. | |
650 */ | |
651 int | |
652 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) | |
653 { | |
654 HRESULT ret; | |
655 Uint32 val; | |
656 | |
657 val = gain * 100; /* Mac OS X uses 0 to 10,000 */ | |
658 ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device, FFPROP_FFGAIN, &val); | |
659 if (ret != FF_OK) { | |
660 SDL_SetError("Haptic: Error setting gain."); | |
661 return -1; | |
662 } | |
663 | |
664 return 0; | |
665 } | |
666 | |
667 | |
668 /* | |
669 * Sets the autocentering. | |
670 */ | |
671 int | |
672 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) | |
673 { | |
674 HRESULT ret; | |
675 Uint32 val; | |
676 | |
677 /* Mac OS X only has 0 (off) and 1 (on) */ | |
678 if (autocenter == 0) val = 0; | |
679 else val = 1; | |
680 | |
681 ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device, | |
682 FFPROP_FFAUTOCENTER, &val); | |
683 if (ret != FF_OK) { | |
684 SDL_SetError("Haptic: Error setting autocenter."); | |
685 return -1; | |
686 } | |
687 | |
688 return 0; | |
689 | |
690 } | |
691 | |
692 | |
693 #endif /* SDL_HAPTIC_LINUX */ |