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.