Mercurial > sdl-ios-xcode
comparison src/haptic/darwin/SDL_syshaptic.c @ 2527:924a32719b6f gsoc2008_force_feedback
Handle axes for darwin now.
Support for periodic effect sort of.
More cleaning up.
author | Edgar Simo <bobbens@gmail.com> |
---|---|
date | Fri, 18 Jul 2008 08:03:24 +0000 |
parents | 0877146be013 |
children | 50414589501e |
comparison
equal
deleted
inserted
replaced
2526:2d88b82ce781 | 2527:924a32719b6f |
---|---|
129 /* | 129 /* |
130 * Gets supported features. | 130 * Gets supported features. |
131 */ | 131 */ |
132 static unsigned int | 132 static unsigned int |
133 GetSupportedFeatures(FFDeviceObjectReference device, | 133 GetSupportedFeatures(FFDeviceObjectReference device, |
134 int *neffects, int *nplaying) | 134 int *neffects, int *nplaying, int *naxes) |
135 { | 135 { |
136 HRESULT ret; | 136 HRESULT ret; |
137 FFCAPABILITIES features; | 137 FFCAPABILITIES features; |
138 unsigned int supported; | 138 unsigned int supported; |
139 Uint32 val; | 139 Uint32 val; |
180 else if (ret != FFERR_UNSUPPORTED) { | 180 else if (ret != FFERR_UNSUPPORTED) { |
181 SDL_SetError("Haptic: Unable to get if device supports autocenter."); | 181 SDL_SetError("Haptic: Unable to get if device supports autocenter."); |
182 return 0; | 182 return 0; |
183 } | 183 } |
184 | 184 |
185 /* Check for axes, we have an artificial limit on axes */ | |
186 *axes = ((features.numFfAxes) > 3) ? | |
187 3 : features.numFfAxes; | |
188 | |
185 /* Always supported features. */ | 189 /* Always supported features. */ |
186 supported |= SDL_HAPTIC_STATUS; | 190 supported |= SDL_HAPTIC_STATUS; |
187 return supported; | 191 return supported; |
188 } | 192 } |
189 | 193 |
209 goto creat_err; | 213 goto creat_err; |
210 } | 214 } |
211 | 215 |
212 /* Get supported features. */ | 216 /* Get supported features. */ |
213 haptic->supported = GetSupportedFeatures(haptic->hwdata->device, | 217 haptic->supported = GetSupportedFeatures(haptic->hwdata->device, |
214 &haptic->neffects, &haptic->nplaying); | 218 &haptic->neffects, &haptic->nplaying, |
219 &haptic->naxes); | |
215 if (haptic->supported == 0) { /* Error since device supports nothing. */ | 220 if (haptic->supported == 0) { /* Error since device supports nothing. */ |
216 goto open_err; | 221 goto open_err; |
217 } | 222 } |
218 haptic->effects = (struct haptic_effect *) | 223 haptic->effects = (struct haptic_effect *) |
219 SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); | 224 SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); |
340 */ | 345 */ |
341 static int | 346 static int |
342 SDL_SYS_SetDirection( FFEFFECT * effect, SDL_HapticDirection *dir, int axes ) | 347 SDL_SYS_SetDirection( FFEFFECT * effect, SDL_HapticDirection *dir, int axes ) |
343 { | 348 { |
344 LONG *rglDir; | 349 LONG *rglDir; |
345 dir = SDL_malloc( sizeof(LONG) * axes ); | 350 |
346 if (dir == NULL) { | 351 /* Handle no axes a part. */ |
352 if (dest->cAxes == 0) { | |
353 effect->rglDirection = NULL; | |
354 return 0; | |
355 } | |
356 | |
357 /* Has axes. */ | |
358 rglDir = SDL_malloc( sizeof(LONG) * axes ); | |
359 if (rglDir == NULL) { | |
347 SDL_OutOfMemory(); | 360 SDL_OutOfMemory(); |
348 return -1; | 361 return -1; |
349 } | 362 } |
350 SDL_memset( dir, 0, sizeof(LONG) * axes ); | 363 SDL_memset( rglDir, 0, sizeof(LONG) * axes ); |
351 effect->rglDirection = rglDir; | 364 effect->rglDirection = rglDir; |
352 | 365 |
353 switch (dir->type) { | 366 switch (dir->type) { |
354 case SDL_HAPTIC_POLAR: | 367 case SDL_HAPTIC_POLAR: |
355 effect->dwFlags |= FFEFF_POLAR; | 368 effect->dwFlags |= FFEFF_POLAR; |
374 } | 387 } |
375 } | 388 } |
376 | 389 |
377 #define CONVERT(x) (((x)*10000) / 0xFFFF ) | 390 #define CONVERT(x) (((x)*10000) / 0xFFFF ) |
378 /* | 391 /* |
379 * Creates the FFStruct | 392 * Creates the FFEFFECT from a SDL_HapticEffect. |
380 */ | 393 */ |
381 static int | 394 static int |
382 SDL_SYS_ToFFEFFECT( FFEFFECT * dest, SDL_HapticEffect * src ) | 395 SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src ) |
383 { | 396 { |
384 FFCONSTANTFORCE *constant; | 397 FFCONSTANTFORCE *constant; |
385 FFPERIODIC *periodic; | 398 FFPERIODIC *periodic; |
386 FFCONDITION *condition; | 399 FFCONDITION *condition; |
387 FFRAMPFORCE *ramp; | 400 FFRAMPFORCE *ramp; |
389 FFENVELOPE *envelope; | 402 FFENVELOPE *envelope; |
390 SDL_HapticConstant *hap_constant; | 403 SDL_HapticConstant *hap_constant; |
391 SDL_HapticPeriodic *hap_periodic; | 404 SDL_HapticPeriodic *hap_periodic; |
392 SDL_HapticCondition *hap_condition; | 405 SDL_HapticCondition *hap_condition; |
393 SDL_HapticRamp *hap_ramp; | 406 SDL_HapticRamp *hap_ramp; |
407 DWORD *axes; | |
394 | 408 |
395 /* Set global stuff. */ | 409 /* Set global stuff. */ |
396 SDL_memset(dest, 0, sizeof(FFEFFECT)); | 410 SDL_memset(dest, 0, sizeof(FFEFFECT)); |
397 dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */ | 411 dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */ |
398 dest->dwSamplePeriod = 0; /* Not used by us. */ | 412 dest->dwSamplePeriod = 0; /* Not used by us. */ |
406 } | 420 } |
407 SDL_memset(envelope, 0, sizeof(FFENVELOPE)); | 421 SDL_memset(envelope, 0, sizeof(FFENVELOPE)); |
408 dest->lpEnvelope = envelope; | 422 dest->lpEnvelope = envelope; |
409 envelope->dwSize = sizeof(FFENVELOPE); /* Always should be this. */ | 423 envelope->dwSize = sizeof(FFENVELOPE); /* Always should be this. */ |
410 | 424 |
425 /* Axes. */ | |
426 dest->cAxes = haptic->naxes; | |
427 if (dest->cAxes > 0) { | |
428 axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); | |
429 if (axes == NULL) { | |
430 SDL_OutOfMemory(); | |
431 return -1; | |
432 } | |
433 axes[0] = FFJOFS_X; /* Always at least one axis. */ | |
434 if (dest->cAxes > 1) { | |
435 axes[1] = FFJOFS_Y; | |
436 } | |
437 if (dest->cAxes > 2) { | |
438 axes[2] = FFJOFS_Z; | |
439 } | |
440 dest->rgdwAxes = axes; | |
441 } | |
442 | |
443 | |
411 switch (src->type) { | 444 switch (src->type) { |
412 case SDL_HAPTIC_CONSTANT: | 445 case SDL_HAPTIC_CONSTANT: |
413 hap_constant = &src->constant; | 446 hap_constant = &src->constant; |
414 constant = SDL_malloc( sizeof(FFCONSTANTFORCE) ); | 447 constant = SDL_malloc( sizeof(FFCONSTANTFORCE) ); |
448 if (constant == NULL) { | |
449 SDL_OutOfMemory(); | |
450 return -1; | |
451 } | |
415 | 452 |
416 /* Specifics */ | 453 /* Specifics */ |
417 constant->lMagnitude = CONVERT(hap_constant->level); | 454 constant->lMagnitude = CONVERT(hap_constant->level); |
418 dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE); | 455 dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE); |
419 dest->lpvTypeSpecificParams = constant; | 456 dest->lpvTypeSpecificParams = constant; |
421 /* Generics */ | 458 /* Generics */ |
422 dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ | 459 dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ |
423 dest->dwTriggerButton = FFJOFS_BUTTON(hap_constant->button); | 460 dest->dwTriggerButton = FFJOFS_BUTTON(hap_constant->button); |
424 dest->dwTriggerRepeatInterval = hap_constant->interval; | 461 dest->dwTriggerRepeatInterval = hap_constant->interval; |
425 dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ | 462 dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ |
426 | |
427 /* Axes */ | |
428 dest->cAxes = 2; /* TODO handle */ | |
429 dest->rgdwAxes = 0; | |
430 | 463 |
431 /* Direction. */ | 464 /* Direction. */ |
432 if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { | 465 if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { |
433 return -1; | 466 return -1; |
434 } | 467 } |
439 envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); | 472 envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); |
440 envelope->dwFadeTime = hap_constant->fade_length * 1000; | 473 envelope->dwFadeTime = hap_constant->fade_length * 1000; |
441 | 474 |
442 break; | 475 break; |
443 | 476 |
444 /* TODO finish */ | |
445 | |
446 case SDL_HAPTIC_SINE: | 477 case SDL_HAPTIC_SINE: |
447 case SDL_HAPTIC_SQUARE: | 478 case SDL_HAPTIC_SQUARE: |
448 case SDL_HAPTIC_TRIANGLE: | 479 case SDL_HAPTIC_TRIANGLE: |
449 case SDL_HAPTIC_SAWTOOTHUP: | 480 case SDL_HAPTIC_SAWTOOTHUP: |
450 case SDL_HAPTIC_SAWTOOTHDOWN: | 481 case SDL_HAPTIC_SAWTOOTHDOWN: |
451 hap_periodic = &src->periodic; | 482 hap_periodic = &src->periodic; |
483 periodic = SDL_malloc(sizeof(FFPERIODIC)); | |
484 if (periodic == NULL) { | |
485 SDL_OutOfMemory(); | |
486 return -1; | |
487 } | |
488 | |
489 /* Specifics */ | |
490 periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); | |
491 periodic->lOffset = CONVERT(hap_periodic->offset); | |
492 periodic->dwPhase = hap_periodic->phase; | |
493 periodic->dwPeriod = hap_periodic->period * 1000; | |
494 dest->cbTypeSpecificParams = sizeof(FFPERIODIC); | |
495 dest->lpvTypeSpecificParams = periodic; | |
496 | |
497 /* Generics */ | |
498 dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ | |
499 dest->dwTriggerButton = FFJOFS_BUTTON(hap_periodic->button); | |
500 dest->dwTriggerRepeatInterval = hap_periodic->interval; | |
501 dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ | |
502 | |
503 /* Direction. */ | |
504 if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) < 0) { | |
505 return -1; | |
506 } | |
507 | |
508 /* Envelope */ | |
509 envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level); | |
510 envelope->dwAttackTime = hap_periodic->attack_length * 1000; | |
511 envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level); | |
512 envelope->dwFadeTime = hap_periodic->fade_length * 1000; | |
452 | 513 |
453 break; | 514 break; |
454 | 515 |
455 case SDL_HAPTIC_SPRING: | 516 case SDL_HAPTIC_SPRING: |
456 case SDL_HAPTIC_DAMPER: | 517 case SDL_HAPTIC_DAMPER: |
474 return 0; | 535 return 0; |
475 } | 536 } |
476 | 537 |
477 | 538 |
478 /* | 539 /* |
540 * Frees an FFEFFECT allocated by SDL_SYS_ToFFEFFECT. | |
541 */ | |
542 void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect ) | |
543 { | |
544 if (effect->lpEnvelope != NULL) { | |
545 SDL_free(effect->lpEnvelope); | |
546 effect->lpEnvelope = NULL; | |
547 } | |
548 if (effect->rgdwAxes != NULL) { | |
549 SDL_free(effect->rgdwAxes); | |
550 effect->rgdwAxes = NULL; | |
551 } | |
552 if (effect->lpvTypeSpecificParams != NULL) { | |
553 SDL_free(effect->lpvTypeSpecificParams); | |
554 effect->lpvTypeSpecificParams = NULL; | |
555 } | |
556 if (effect->rglDirection != NULL) { | |
557 SDL_free(effect->rglDirection); | |
558 effect->rglDirection = NULL; | |
559 } | |
560 } | |
561 | |
562 | |
563 /* | |
479 * Gets the effect type from the generic SDL haptic effect wrapper. | 564 * Gets the effect type from the generic SDL haptic effect wrapper. |
480 */ | 565 */ |
481 CFUUIDRef SDL_SYS_HapticEffectType(struct haptic_effect * effect) | 566 CFUUIDRef SDL_SYS_HapticEffectType(struct haptic_effect * effect) |
482 { | 567 { |
483 switch (effect->effect.type) { | 568 switch (effect->effect.type) { |
537 /* Alloc the effect. */ | 622 /* Alloc the effect. */ |
538 effect->hweffect = (struct haptic_hweffect *) | 623 effect->hweffect = (struct haptic_hweffect *) |
539 SDL_malloc(sizeof(struct haptic_hweffect)); | 624 SDL_malloc(sizeof(struct haptic_hweffect)); |
540 if (effect->hweffect == NULL) { | 625 if (effect->hweffect == NULL) { |
541 SDL_OutOfMemory(); | 626 SDL_OutOfMemory(); |
542 return -1; | 627 goto err_hweffect; |
543 } | 628 } |
544 | 629 |
545 /* Get the type. */ | 630 /* Get the type. */ |
546 type = SDL_SYS_HapticEffectType(effect); | 631 type = SDL_SYS_HapticEffectType(effect); |
547 if (type == NULL) { | 632 if (type == NULL) { |
633 goto err_hweffect; | |
634 } | |
635 | |
636 /* Get the effect. */ | |
637 if (SDL_SYS_ToFFEFFECT(haptic, &effect->hweffect->effect, &effect->effect ) < 0) { | |
638 goto err_effectdone; | |
639 } | |
640 | |
641 /* Create the actual effect. */ | |
642 ret = FFDeviceCreateEffect( haptic->hwdata->device, type, | |
643 &effect->hweffect->effect, &effect->hweffect->ref ); | |
644 | |
645 if (ret != FF_OK) { | |
646 SDL_SetError("Haptic: Unable to create effect."); | |
647 goto err_effectdone; | |
648 } | |
649 | |
650 return 0; | |
651 | |
652 err_effectdone: | |
653 SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect); | |
654 err_hweffect: | |
655 if (effect->hweffect != NULL) { | |
548 SDL_free(effect->hweffect); | 656 SDL_free(effect->hweffect); |
549 effect->hweffect = NULL; | 657 effect->hweffect = NULL; |
550 return -1; | 658 } |
551 } | 659 return -1; |
552 | |
553 /* Get the effect. */ | |
554 if (SDL_SYS_ToFFEFFECT( &effect->hweffect->effect, &effect->effect ) < 0) { | |
555 /* TODO cleanup alloced stuff. */ | |
556 return -1; | |
557 } | |
558 | |
559 ret = FFDeviceCreateEffect( haptic->hwdata->device, type, | |
560 &effect->hweffect->effect, &effect->hweffect->ref ); | |
561 } | 660 } |
562 | 661 |
563 | 662 |
564 /* | 663 /* |
565 * Updates an effect. | 664 * Updates an effect. |