304 { |
304 { |
305 int i; |
305 int i; |
306 |
306 |
307 if (haptic->hwdata) { |
307 if (haptic->hwdata) { |
308 |
308 |
|
309 /* Free the effects. */ |
|
310 for (i=0; i<haptic->neffects; i++) { |
|
311 if (haptic->effects[i].hweffect != NULL) { |
|
312 SDL_SYS_HapticFreeFFEFFECT(&haptic->effects[i].hweffect->effect); |
|
313 SDL_free(haptic->effects[i].hweffect); |
|
314 } |
|
315 } |
|
316 SDL_free(haptic->effects); |
|
317 haptic->neffects = 0; |
|
318 |
309 /* Clean up */ |
319 /* Clean up */ |
310 FFReleaseDevice(haptic->hwdata->device); |
320 FFReleaseDevice(haptic->hwdata->device); |
311 |
321 |
312 /* Free */ |
322 /* Free */ |
313 SDL_free(haptic->hwdata); |
323 SDL_free(haptic->hwdata); |
314 haptic->hwdata = NULL; |
324 haptic->hwdata = NULL; |
315 for (i=0; i<haptic->neffects; i++) { |
|
316 if (haptic->effects[i].hweffect != NULL) |
|
317 SDL_free(haptic->effects[i].hweffect->effect.lpvTypeSpecificParams); |
|
318 } |
|
319 SDL_free(haptic->effects); |
|
320 haptic->neffects = 0; |
|
321 } |
325 } |
322 } |
326 } |
323 |
327 |
324 |
328 |
325 /* |
329 /* |
329 SDL_SYS_HapticQuit(void) |
333 SDL_SYS_HapticQuit(void) |
330 { |
334 { |
331 int i; |
335 int i; |
332 |
336 |
333 for (i=0; i < SDL_numhaptics; i++) { |
337 for (i=0; i < SDL_numhaptics; i++) { |
|
338 /* Opened and not closed haptics are leaked, this is on purpose. |
|
339 * Close your haptic devices after usage. */ |
|
340 |
|
341 /* Free the io_service_t */ |
334 IOObjectRelease(SDL_hapticlist[i].dev); |
342 IOObjectRelease(SDL_hapticlist[i].dev); |
335 /* TODO free effects. */ |
|
336 } |
343 } |
337 } |
344 } |
338 |
345 |
339 |
346 |
340 /* |
347 /* |
389 * Creates the FFEFFECT from a SDL_HapticEffect. |
396 * Creates the FFEFFECT from a SDL_HapticEffect. |
390 */ |
397 */ |
391 static int |
398 static int |
392 SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src ) |
399 SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src ) |
393 { |
400 { |
|
401 int i; |
394 FFCONSTANTFORCE *constant; |
402 FFCONSTANTFORCE *constant; |
395 FFPERIODIC *periodic; |
403 FFPERIODIC *periodic; |
396 FFCONDITION *condition; |
404 FFCONDITION *condition; /* Actually an array of conditions - one per axis. */ |
397 FFRAMPFORCE *ramp; |
405 FFRAMPFORCE *ramp; |
398 FFCUSTOMFORCE *custom; |
406 FFCUSTOMFORCE *custom; |
399 FFENVELOPE *envelope; |
407 FFENVELOPE *envelope; |
400 SDL_HapticConstant *hap_constant; |
408 SDL_HapticConstant *hap_constant; |
401 SDL_HapticPeriodic *hap_periodic; |
409 SDL_HapticPeriodic *hap_periodic; |
436 } |
444 } |
437 dest->rgdwAxes = axes; |
445 dest->rgdwAxes = axes; |
438 } |
446 } |
439 |
447 |
440 |
448 |
|
449 /* The big type handling switch, even bigger then linux's version. */ |
441 switch (src->type) { |
450 switch (src->type) { |
442 case SDL_HAPTIC_CONSTANT: |
451 case SDL_HAPTIC_CONSTANT: |
443 hap_constant = &src->constant; |
452 hap_constant = &src->constant; |
444 constant = SDL_malloc( sizeof(FFCONSTANTFORCE) ); |
453 constant = SDL_malloc( sizeof(FFCONSTANTFORCE) ); |
445 if (constant == NULL) { |
454 if (constant == NULL) { |
513 case SDL_HAPTIC_SPRING: |
522 case SDL_HAPTIC_SPRING: |
514 case SDL_HAPTIC_DAMPER: |
523 case SDL_HAPTIC_DAMPER: |
515 case SDL_HAPTIC_INERTIA: |
524 case SDL_HAPTIC_INERTIA: |
516 case SDL_HAPTIC_FRICTION: |
525 case SDL_HAPTIC_FRICTION: |
517 hap_condition = &src->condition; |
526 hap_condition = &src->condition; |
|
527 condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes); |
|
528 if (condition == NULL) { |
|
529 SDL_OutOfMemory(); |
|
530 return -1; |
|
531 } |
|
532 |
|
533 /* Specifics */ |
|
534 for (i=0; i<dest->cAxes; i++) { |
|
535 condition[i].lOffset = CONVERT(hap_constant->center[i]); |
|
536 condition[i].lPositiveCoefficient = CONVERT(hap_constant->right_coeff[i]); |
|
537 condition[i].lNegativeCoefficient = CONVERT(hap_constant->left_coeff[i]); |
|
538 condition[i].dwPositiveSaturation = CONVERT(hap_constant->right_sat[i]); |
|
539 condition[i].dwNegativeSaturation = CONVERT(hap_constant->left_sat[i]); |
|
540 condition[i].lDeadBand = CONVERT(hap_constant->deadband[i]); |
|
541 } |
|
542 dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes; |
|
543 dest->lpvTypeSpecificParams = condition; |
|
544 |
|
545 /* Generics */ |
|
546 dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ |
|
547 dest->dwTriggerButton = FFJOFS_BUTTON(hap_constant->button); |
|
548 dest->dwTriggerRepeatInterval = hap_constant->interval; |
|
549 dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ |
|
550 |
|
551 /* Direction. */ |
|
552 if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { |
|
553 return -1; |
|
554 } |
|
555 |
|
556 /* Envelope */ |
|
557 envelope->dwAttackLevel = CONVERT(hap_constant->attack_level); |
|
558 envelope->dwAttackTime = hap_constant->attack_length * 1000; |
|
559 envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); |
|
560 envelope->dwFadeTime = hap_constant->fade_length * 1000; |
518 |
561 |
519 break; |
562 break; |
520 |
563 |
521 case SDL_HAPTIC_RAMP: |
564 case SDL_HAPTIC_RAMP: |
522 hap_ramp = &src->ramp; |
565 hap_ramp = &src->ramp; |