Mercurial > sdl-ios-xcode
comparison src/haptic/win32/SDL_syshaptic.c @ 2566:94ff09afa478 gsoc2008_force_feedback
Basic haptic support for windows should work. Needs testing (probably won't compile).
author | Edgar Simo <bobbens@gmail.com> |
---|---|
date | Thu, 31 Jul 2008 11:06:16 +0000 |
parents | 3696b9ce8a37 |
children | 5ad98a77bacb |
comparison
equal
deleted
inserted
replaced
2565:698c776c642f | 2566:94ff09afa478 |
---|---|
460 dinput = NULL; | 460 dinput = NULL; |
461 } | 461 } |
462 | 462 |
463 | 463 |
464 /* | 464 /* |
465 * Converts an SDL trigger button to an DIEFFECT trigger button. | |
466 */ | |
467 static DWORD | |
468 DIGetTriggerButton( Uint16 button ) | |
469 { | |
470 DWORD dwTriggerButton; | |
471 | |
472 dwTriggerButton = DIEB_NOTRIGGER; | |
473 | |
474 if (button != 0) { | |
475 dwTriggerButton = DIJOFS_BUTTON(button - 1); | |
476 } | |
477 | |
478 return dwTriggerButton; | |
479 } | |
480 | |
481 | |
482 /* | |
465 * Sets the direction. | 483 * Sets the direction. |
466 */ | 484 */ |
467 static int | 485 static int |
468 SDL_SYS_SetDirection( FFEFFECT * effect, SDL_HapticDirection *dir, int naxes ) | 486 SDL_SYS_SetDirection( DIEFFECT * effect, SDL_HapticDirection *dir, int naxes ) |
469 { | 487 { |
470 LONG *rglDir; | 488 LONG *rglDir; |
471 | 489 |
472 /* Handle no axes a part. */ | 490 /* Handle no axes a part. */ |
473 if (naxes == 0) { | 491 if (naxes == 0) { |
484 SDL_memset( rglDir, 0, sizeof(LONG) * naxes ); | 502 SDL_memset( rglDir, 0, sizeof(LONG) * naxes ); |
485 effect->rglDirection = rglDir; | 503 effect->rglDirection = rglDir; |
486 | 504 |
487 switch (dir->type) { | 505 switch (dir->type) { |
488 case SDL_HAPTIC_POLAR: | 506 case SDL_HAPTIC_POLAR: |
489 effect->dwFlags |= FFEFF_POLAR; | 507 effect->dwFlags |= DIEFF_POLAR; |
490 rglDir[0] = dir->dir[0]; | 508 rglDir[0] = dir->dir[0]; |
491 return 0; | 509 return 0; |
492 case SDL_HAPTIC_CARTESIAN: | 510 case SDL_HAPTIC_CARTESIAN: |
493 effect->dwFlags |= FFEFF_CARTESIAN; | 511 effect->dwFlags |= DIEFF_CARTESIAN; |
494 rglDir[0] = dir->dir[0]; | 512 rglDir[0] = dir->dir[0]; |
495 rglDir[1] = dir->dir[1]; | 513 rglDir[1] = dir->dir[1]; |
496 rglDir[2] = dir->dir[2]; | 514 rglDir[2] = dir->dir[2]; |
497 return 0; | 515 return 0; |
498 case SDL_HAPTIC_SPHERICAL: | 516 case SDL_HAPTIC_SPHERICAL: |
499 effect->dwFlags |= FFEFF_SPHERICAL; | 517 effect->dwFlags |= DIEFF_SPHERICAL; |
500 rglDir[0] = dir->dir[0]; | 518 rglDir[0] = dir->dir[0]; |
501 rglDir[1] = dir->dir[1]; | 519 rglDir[1] = dir->dir[1]; |
502 rglDir[2] = dir->dir[2]; | 520 rglDir[2] = dir->dir[2]; |
503 return 0; | 521 return 0; |
504 | 522 |
508 } | 526 } |
509 } | 527 } |
510 | 528 |
511 #define CONVERT(x) (((x)*10000) / 0xFFFF ) | 529 #define CONVERT(x) (((x)*10000) / 0xFFFF ) |
512 /* | 530 /* |
513 * Creates the FFEFFECT from a SDL_HapticEffect. | 531 * Creates the DIEFFECT from a SDL_HapticEffect. |
514 */ | 532 */ |
515 static int | 533 static int |
516 SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src ) | 534 SDL_SYS_ToDIEFFECT( SDL_Haptic * haptic, DIEFFECT * dest, SDL_HapticEffect * src ) |
517 { | 535 { |
518 int i; | 536 int i; |
519 FFCONSTANTFORCE *constant; | 537 DICONSTANTFORCE *constant; |
520 FFPERIODIC *periodic; | 538 DIPERIODIC *periodic; |
521 FFCONDITION *condition; /* Actually an array of conditions - one per axis. */ | 539 DICONDITION *condition; /* Actually an array of conditions - one per axis. */ |
522 FFRAMPFORCE *ramp; | 540 DIRAMPFORCE *ramp; |
523 FFCUSTOMFORCE *custom; | 541 DICUSTOMFORCE *custom; |
524 FFENVELOPE *envelope; | 542 DIENVELOPE *envelope; |
525 SDL_HapticConstant *hap_constant; | 543 SDL_HapticConstant *hap_constant; |
526 SDL_HapticPeriodic *hap_periodic; | 544 SDL_HapticPeriodic *hap_periodic; |
527 SDL_HapticCondition *hap_condition; | 545 SDL_HapticCondition *hap_condition; |
528 SDL_HapticRamp *hap_ramp; | 546 SDL_HapticRamp *hap_ramp; |
529 SDL_HapticCustom *hap_custom; | 547 SDL_HapticCustom *hap_custom; |
530 DWORD *axes; | 548 DWORD *axes; |
531 | 549 |
532 /* Set global stuff. */ | 550 /* Set global stuff. */ |
533 SDL_memset(dest, 0, sizeof(FFEFFECT)); | 551 SDL_memset(dest, 0, sizeof(DIEFFECT)); |
534 dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */ | 552 dest->dwSize = sizeof(DIEFFECT); /* Set the structure size. */ |
535 dest->dwSamplePeriod = 0; /* Not used by us. */ | 553 dest->dwSamplePeriod = 0; /* Not used by us. */ |
536 dest->dwGain = 10000; /* Gain is set globally, not locally. */ | 554 dest->dwGain = 10000; /* Gain is set globally, not locally. */ |
537 | 555 |
538 /* Envelope. */ | 556 /* Envelope. */ |
539 envelope = SDL_malloc( sizeof(FFENVELOPE) ); | 557 envelope = SDL_malloc( sizeof(DIENVELOPE) ); |
540 if (envelope == NULL) { | 558 if (envelope == NULL) { |
541 SDL_OutOfMemory(); | 559 SDL_OutOfMemory(); |
542 return -1; | 560 return -1; |
543 } | 561 } |
544 SDL_memset(envelope, 0, sizeof(FFENVELOPE)); | 562 SDL_memset(envelope, 0, sizeof(DIENVELOPE)); |
545 dest->lpEnvelope = envelope; | 563 dest->lpEnvelope = envelope; |
546 envelope->dwSize = sizeof(FFENVELOPE); /* Always should be this. */ | 564 envelope->dwSize = sizeof(DIENVELOPE); /* Always should be this. */ |
547 | 565 |
548 /* Axes. */ | 566 /* Axes. */ |
549 dest->cAxes = haptic->naxes; | 567 dest->cAxes = haptic->naxes; |
550 if (dest->cAxes > 0) { | 568 if (dest->cAxes > 0) { |
551 axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); | 569 axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); |
552 if (axes == NULL) { | 570 if (axes == NULL) { |
553 SDL_OutOfMemory(); | 571 SDL_OutOfMemory(); |
554 return -1; | 572 return -1; |
555 } | 573 } |
556 axes[0] = FFJOFS_X; /* Always at least one axis. */ | 574 axes[0] = DIJOFS_X; /* Always at least one axis. */ |
557 if (dest->cAxes > 1) { | 575 if (dest->cAxes > 1) { |
558 axes[1] = FFJOFS_Y; | 576 axes[1] = DIJOFS_Y; |
559 } | 577 } |
560 if (dest->cAxes > 2) { | 578 if (dest->cAxes > 2) { |
561 axes[2] = FFJOFS_Z; | 579 axes[2] = DIJOFS_Z; |
562 } | 580 } |
563 dest->rgdwAxes = axes; | 581 dest->rgdwAxes = axes; |
564 } | 582 } |
565 | 583 |
566 | 584 |
567 /* The big type handling switch, even bigger then linux's version. */ | 585 /* The big type handling switch, even bigger then linux's version. */ |
568 switch (src->type) { | 586 switch (src->type) { |
569 case SDL_HAPTIC_CONSTANT: | 587 case SDL_HAPTIC_CONSTANT: |
570 hap_constant = &src->constant; | 588 hap_constant = &src->constant; |
571 constant = SDL_malloc( sizeof(FFCONSTANTFORCE) ); | 589 constant = SDL_malloc( sizeof(DICONSTANTFORCE) ); |
572 if (constant == NULL) { | 590 if (constant == NULL) { |
573 SDL_OutOfMemory(); | 591 SDL_OutOfMemory(); |
574 return -1; | 592 return -1; |
575 } | 593 } |
576 SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE)); | 594 SDL_memset(constant, 0, sizeof(DICONSTANTFORCE)); |
577 | 595 |
578 /* Specifics */ | 596 /* Specifics */ |
579 constant->lMagnitude = CONVERT(hap_constant->level); | 597 constant->lMagnitude = CONVERT(hap_constant->level); |
580 dest->cbTypeSpecificParams = sizeof(FFCONSTANTFORCE); | 598 dest->cbTypeSpecificParams = sizeof(DICONSTANTFORCE); |
581 dest->lpvTypeSpecificParams = constant; | 599 dest->lpvTypeSpecificParams = constant; |
582 | 600 |
583 /* Generics */ | 601 /* Generics */ |
584 dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ | 602 dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ |
585 dest->dwTriggerButton = FFJOFS_BUTTON(hap_constant->button); | 603 dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button); |
586 dest->dwTriggerRepeatInterval = hap_constant->interval; | 604 dest->dwTriggerRepeatInterval = hap_constant->interval; |
587 dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ | 605 dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ |
588 | 606 |
589 /* Direction. */ | 607 /* Direction. */ |
590 if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { | 608 if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { |
591 return -1; | 609 return -1; |
592 } | 610 } |
593 | 611 |
594 /* Envelope */ | 612 /* Envelope */ |
595 envelope->dwAttackLevel = CONVERT(hap_constant->attack_level); | 613 if ((hap_constant->attack_length==0) && (hap_constant->fade_length==0)) { |
596 envelope->dwAttackTime = hap_constant->attack_length * 1000; | 614 SDL_free(dest->lpEnvelope); |
597 envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); | 615 dest->lpEnvelope = NULL; |
598 envelope->dwFadeTime = hap_constant->fade_length * 1000; | 616 } |
617 else { | |
618 envelope->dwAttackLevel = CONVERT(hap_constant->attack_level); | |
619 envelope->dwAttackTime = hap_constant->attack_length * 1000; | |
620 envelope->dwFadeLevel = CONVERT(hap_constant->fade_level); | |
621 envelope->dwFadeTime = hap_constant->fade_length * 1000; | |
622 } | |
599 | 623 |
600 break; | 624 break; |
601 | 625 |
602 case SDL_HAPTIC_SINE: | 626 case SDL_HAPTIC_SINE: |
603 case SDL_HAPTIC_SQUARE: | 627 case SDL_HAPTIC_SQUARE: |
604 case SDL_HAPTIC_TRIANGLE: | 628 case SDL_HAPTIC_TRIANGLE: |
605 case SDL_HAPTIC_SAWTOOTHUP: | 629 case SDL_HAPTIC_SAWTOOTHUP: |
606 case SDL_HAPTIC_SAWTOOTHDOWN: | 630 case SDL_HAPTIC_SAWTOOTHDOWN: |
607 hap_periodic = &src->periodic; | 631 hap_periodic = &src->periodic; |
608 periodic = SDL_malloc(sizeof(FFPERIODIC)); | 632 periodic = SDL_malloc(sizeof(DIPERIODIC)); |
609 if (periodic == NULL) { | 633 if (periodic == NULL) { |
610 SDL_OutOfMemory(); | 634 SDL_OutOfMemory(); |
611 return -1; | 635 return -1; |
612 } | 636 } |
613 SDL_memset(periodic, 0, sizeof(FFPERIODIC)); | 637 SDL_memset(periodic, 0, sizeof(DIPERIODIC)); |
614 | 638 |
615 /* Specifics */ | 639 /* Specifics */ |
616 periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); | 640 periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); |
617 periodic->lOffset = CONVERT(hap_periodic->offset); | 641 periodic->lOffset = CONVERT(hap_periodic->offset); |
618 periodic->dwPhase = hap_periodic->phase; | 642 periodic->dwPhase = hap_periodic->phase; |
619 periodic->dwPeriod = hap_periodic->period * 1000; | 643 periodic->dwPeriod = hap_periodic->period * 1000; |
620 dest->cbTypeSpecificParams = sizeof(FFPERIODIC); | 644 dest->cbTypeSpecificParams = sizeof(DIPERIODIC); |
621 dest->lpvTypeSpecificParams = periodic; | 645 dest->lpvTypeSpecificParams = periodic; |
622 | 646 |
623 /* Generics */ | 647 /* Generics */ |
624 dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ | 648 dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ |
625 dest->dwTriggerButton = FFJOFS_BUTTON(hap_periodic->button); | 649 dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button); |
626 dest->dwTriggerRepeatInterval = hap_periodic->interval; | 650 dest->dwTriggerRepeatInterval = hap_periodic->interval; |
627 dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ | 651 dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ |
628 | 652 |
629 /* Direction. */ | 653 /* Direction. */ |
630 if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) < 0) { | 654 if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) < 0) { |
631 return -1; | 655 return -1; |
632 } | 656 } |
633 | 657 |
634 /* Envelope */ | 658 /* Envelope */ |
635 envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level); | 659 if ((hap_periodic->attack_length==0) && (hap_periodic->fade_length==0)) { |
636 envelope->dwAttackTime = hap_periodic->attack_length * 1000; | 660 SDL_free(dest->lpEnvelope); |
637 envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level); | 661 dest->lpEnvelope = NULL; |
638 envelope->dwFadeTime = hap_periodic->fade_length * 1000; | 662 } |
663 else { | |
664 envelope->dwAttackLevel = CONVERT(hap_periodic->attack_level); | |
665 envelope->dwAttackTime = hap_periodic->attack_length * 1000; | |
666 envelope->dwFadeLevel = CONVERT(hap_periodic->fade_level); | |
667 envelope->dwFadeTime = hap_periodic->fade_length * 1000; | |
668 } | |
639 | 669 |
640 break; | 670 break; |
641 | 671 |
642 case SDL_HAPTIC_SPRING: | 672 case SDL_HAPTIC_SPRING: |
643 case SDL_HAPTIC_DAMPER: | 673 case SDL_HAPTIC_DAMPER: |
644 case SDL_HAPTIC_INERTIA: | 674 case SDL_HAPTIC_INERTIA: |
645 case SDL_HAPTIC_FRICTION: | 675 case SDL_HAPTIC_FRICTION: |
646 hap_condition = &src->condition; | 676 hap_condition = &src->condition; |
647 condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes); | 677 condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes); |
648 if (condition == NULL) { | 678 if (condition == NULL) { |
649 SDL_OutOfMemory(); | 679 SDL_OutOfMemory(); |
650 return -1; | 680 return -1; |
651 } | 681 } |
652 SDL_memset(condition, 0, sizeof(FFCONDITION)); | 682 SDL_memset(condition, 0, sizeof(DICONDITION)); |
653 | 683 |
654 /* Specifics */ | 684 /* Specifics */ |
655 for (i=0; i<dest->cAxes; i++) { | 685 for (i=0; i<dest->cAxes; i++) { |
656 condition[i].lOffset = CONVERT(hap_condition->center[i]); | 686 condition[i].lOffset = CONVERT(hap_condition->center[i]); |
657 condition[i].lPositiveCoefficient = CONVERT(hap_condition->right_coeff[i]); | 687 condition[i].lPositiveCoefficient = CONVERT(hap_condition->right_coeff[i]); |
658 condition[i].lNegativeCoefficient = CONVERT(hap_condition->left_coeff[i]); | 688 condition[i].lNegativeCoefficient = CONVERT(hap_condition->left_coeff[i]); |
659 condition[i].dwPositiveSaturation = CONVERT(hap_condition->right_sat[i]); | 689 condition[i].dwPositiveSaturation = CONVERT(hap_condition->right_sat[i]); |
660 condition[i].dwNegativeSaturation = CONVERT(hap_condition->left_sat[i]); | 690 condition[i].dwNegativeSaturation = CONVERT(hap_condition->left_sat[i]); |
661 condition[i].lDeadBand = CONVERT(hap_condition->deadband[i]); | 691 condition[i].lDeadBand = CONVERT(hap_condition->deadband[i]); |
662 } | 692 } |
663 dest->cbTypeSpecificParams = sizeof(FFCONDITION) * dest->cAxes; | 693 dest->cbTypeSpecificParams = sizeof(DICONDITION) * dest->cAxes; |
664 dest->lpvTypeSpecificParams = condition; | 694 dest->lpvTypeSpecificParams = condition; |
665 | 695 |
666 /* Generics */ | 696 /* Generics */ |
667 dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ | 697 dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ |
668 dest->dwTriggerButton = FFJOFS_BUTTON(hap_condition->button); | 698 dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button); |
669 dest->dwTriggerRepeatInterval = hap_condition->interval; | 699 dest->dwTriggerRepeatInterval = hap_condition->interval; |
670 dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ | 700 dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ |
671 | 701 |
672 /* Direction. */ | 702 /* Direction. */ |
673 if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) < 0) { | 703 if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) < 0) { |
684 | 714 |
685 break; | 715 break; |
686 | 716 |
687 case SDL_HAPTIC_RAMP: | 717 case SDL_HAPTIC_RAMP: |
688 hap_ramp = &src->ramp; | 718 hap_ramp = &src->ramp; |
689 ramp = SDL_malloc(sizeof(FFRAMPFORCE)); | 719 ramp = SDL_malloc(sizeof(DIRAMPFORCE)); |
690 if (ramp == NULL) { | 720 if (ramp == NULL) { |
691 SDL_OutOfMemory(); | 721 SDL_OutOfMemory(); |
692 return -1; | 722 return -1; |
693 } | 723 } |
694 SDL_memset(ramp, 0, sizeof(FFRAMPFORCE)); | 724 SDL_memset(ramp, 0, sizeof(DIRAMPFORCE)); |
695 | 725 |
696 /* Specifics */ | 726 /* Specifics */ |
697 ramp->lStart = CONVERT(hap_ramp->start); | 727 ramp->lStart = CONVERT(hap_ramp->start); |
698 ramp->lEnd = CONVERT(hap_ramp->end); | 728 ramp->lEnd = CONVERT(hap_ramp->end); |
699 dest->cbTypeSpecificParams = sizeof(FFRAMPFORCE); | 729 dest->cbTypeSpecificParams = sizeof(DIRAMPFORCE); |
700 dest->lpvTypeSpecificParams = ramp; | 730 dest->lpvTypeSpecificParams = ramp; |
701 | 731 |
702 /* Generics */ | 732 /* Generics */ |
703 dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ | 733 dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ |
704 dest->dwTriggerButton = FFJOFS_BUTTON(hap_ramp->button); | 734 dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button); |
705 dest->dwTriggerRepeatInterval = hap_ramp->interval; | 735 dest->dwTriggerRepeatInterval = hap_ramp->interval; |
706 dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ | 736 dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ |
707 | 737 |
708 /* Direction. */ | 738 /* Direction. */ |
709 if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) { | 739 if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) { |
710 return -1; | 740 return -1; |
711 } | 741 } |
712 | 742 |
713 /* Envelope */ | 743 /* Envelope */ |
714 envelope->dwAttackLevel = CONVERT(hap_ramp->attack_level); | 744 if ((hap_ramp->attack_length==0) && (hap_ramp->fade_length==0)) { |
715 envelope->dwAttackTime = hap_ramp->attack_length * 1000; | 745 SDL_free(dest->lpEnvelope); |
716 envelope->dwFadeLevel = CONVERT(hap_ramp->fade_level); | 746 dest->lpEnvelope = NULL; |
717 envelope->dwFadeTime = hap_ramp->fade_length * 1000; | 747 } |
748 else { | |
749 envelope->dwAttackLevel = CONVERT(hap_ramp->attack_level); | |
750 envelope->dwAttackTime = hap_ramp->attack_length * 1000; | |
751 envelope->dwFadeLevel = CONVERT(hap_ramp->fade_level); | |
752 envelope->dwFadeTime = hap_ramp->fade_length * 1000; | |
753 } | |
718 | 754 |
719 break; | 755 break; |
720 | 756 |
721 case SDL_HAPTIC_CUSTOM: | 757 case SDL_HAPTIC_CUSTOM: |
722 hap_custom = &src->custom; | 758 hap_custom = &src->custom; |
723 custom = SDL_malloc(sizeof(FFCUSTOMFORCE)); | 759 custom = SDL_malloc(sizeof(DICUSTOMFORCE)); |
724 if (custom == NULL) { | 760 if (custom == NULL) { |
725 SDL_OutOfMemory(); | 761 SDL_OutOfMemory(); |
726 return -1; | 762 return -1; |
727 } | 763 } |
728 SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE)); | 764 SDL_memset(custom, 0, sizeof(DICUSTOMFORCE)); |
729 | 765 |
730 /* Specifics */ | 766 /* Specifics */ |
731 custom->cChannels = hap_custom->channels; | 767 custom->cChannels = hap_custom->channels; |
732 custom->dwSamplePeriod = hap_custom->period * 1000; | 768 custom->dwSamplePeriod = hap_custom->period * 1000; |
733 custom->cSamples = hap_custom->samples; | 769 custom->cSamples = hap_custom->samples; |
734 custom->rglForceData = SDL_malloc(sizeof(LONG)*custom->cSamples*custom->cChannels); | 770 custom->rglForceData = SDL_malloc(sizeof(LONG)*custom->cSamples*custom->cChannels); |
735 for (i=0; i<hap_custom->samples*hap_custom->channels; i++) { /* Copy data. */ | 771 for (i=0; i<hap_custom->samples*hap_custom->channels; i++) { /* Copy data. */ |
736 custom->rglForceData[i] = CONVERT(hap_custom->data[i]); | 772 custom->rglForceData[i] = CONVERT(hap_custom->data[i]); |
737 } | 773 } |
738 dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE); | 774 dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE); |
739 dest->lpvTypeSpecificParams = custom; | 775 dest->lpvTypeSpecificParams = custom; |
740 | 776 |
741 /* Generics */ | 777 /* Generics */ |
742 dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ | 778 dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ |
743 dest->dwTriggerButton = FFJOFS_BUTTON(hap_custom->button); | 779 dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button); |
744 dest->dwTriggerRepeatInterval = hap_custom->interval; | 780 dest->dwTriggerRepeatInterval = hap_custom->interval; |
745 dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ | 781 dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ |
746 | 782 |
747 /* Direction. */ | 783 /* Direction. */ |
748 if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) { | 784 if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) { |
749 return -1; | 785 return -1; |
750 } | 786 } |
751 | 787 |
752 /* Envelope */ | 788 /* Envelope */ |
753 envelope->dwAttackLevel = CONVERT(hap_custom->attack_level); | 789 if ((hap_custom->attack_length==0) && (hap_custom->fade_length==0)) { |
754 envelope->dwAttackTime = hap_custom->attack_length * 1000; | 790 SDL_free(dest->lpEnvelope); |
755 envelope->dwFadeLevel = CONVERT(hap_custom->fade_level); | 791 dest->lpEnvelope = NULL; |
756 envelope->dwFadeTime = hap_custom->fade_length * 1000; | 792 } |
793 else { | |
794 envelope->dwAttackLevel = CONVERT(hap_custom->attack_level); | |
795 envelope->dwAttackTime = hap_custom->attack_length * 1000; | |
796 envelope->dwFadeLevel = CONVERT(hap_custom->fade_level); | |
797 envelope->dwFadeTime = hap_custom->fade_length * 1000; | |
798 } | |
757 | 799 |
758 break; | 800 break; |
759 | 801 |
760 | 802 |
761 default: | 803 default: |
766 return 0; | 808 return 0; |
767 } | 809 } |
768 | 810 |
769 | 811 |
770 /* | 812 /* |
771 * Frees an FFEFFECT allocated by SDL_SYS_ToFFEFFECT. | 813 * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT. |
772 */ | 814 */ |
773 static void | 815 static void |
774 SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type ) | 816 SDL_SYS_HapticFreeDIEFFECT( DIEFFECT * effect, int type ) |
775 { | 817 { |
776 FFCUSTOMFORCE *custom; | 818 DICUSTOMFORCE *custom; |
777 | 819 |
778 if (effect->lpEnvelope != NULL) { | 820 if (effect->lpEnvelope != NULL) { |
779 SDL_free(effect->lpEnvelope); | 821 SDL_free(effect->lpEnvelope); |
780 effect->lpEnvelope = NULL; | 822 effect->lpEnvelope = NULL; |
781 } | 823 } |
783 SDL_free(effect->rgdwAxes); | 825 SDL_free(effect->rgdwAxes); |
784 effect->rgdwAxes = NULL; | 826 effect->rgdwAxes = NULL; |
785 } | 827 } |
786 if (effect->lpvTypeSpecificParams != NULL) { | 828 if (effect->lpvTypeSpecificParams != NULL) { |
787 if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ | 829 if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ |
788 custom = (FFCUSTOMFORCE*) effect->lpvTypeSpecificParams; | 830 custom = (DICUSTOMFORCE*) effect->lpvTypeSpecificParams; |
789 SDL_free(custom->rglForceData); | 831 SDL_free(custom->rglForceData); |
790 custom->rglForceData = NULL; | 832 custom->rglForceData = NULL; |
791 } | 833 } |
792 SDL_free(effect->lpvTypeSpecificParams); | 834 SDL_free(effect->lpvTypeSpecificParams); |
793 effect->lpvTypeSpecificParams = NULL; | 835 effect->lpvTypeSpecificParams = NULL; |
872 if (type == NULL) { | 914 if (type == NULL) { |
873 goto err_hweffect; | 915 goto err_hweffect; |
874 } | 916 } |
875 | 917 |
876 /* Get the effect. */ | 918 /* Get the effect. */ |
877 if (SDL_SYS_ToFFEFFECT(haptic, &effect->hweffect->effect, base) < 0) { | 919 if (SDL_SYS_ToDIEFFECT(haptic, &effect->hweffect->effect, base) < 0) { |
878 goto err_effectdone; | 920 goto err_effectdone; |
879 } | 921 } |
880 | 922 |
881 /* Create the actual effect. */ | 923 /* Create the actual effect. */ |
882 ret = FFDeviceCreateEffect(haptic->hwdata->device, type, | 924 ret = IDirectInputDevice2_CreateEffect(haptic->hwdata->device, type, |
883 &effect->hweffect->effect, &effect->hweffect->ref); | 925 &effect->hweffect->effect, &effect->hweffect->ref, NULL); |
884 if (ret != FF_OK) { | 926 if (FAILED(ret)) { |
885 SDL_SetError("Haptic: Unable to create effect: %s.", FFStrError(ret)); | 927 DI_SetError("Unable to create effect",ret); |
886 goto err_effectdone; | 928 goto err_effectdone; |
887 } | 929 } |
888 | 930 |
889 return 0; | 931 return 0; |
890 | 932 |
891 err_effectdone: | 933 err_effectdone: |
892 SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, base->type); | 934 SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, base->type); |
893 err_hweffect: | 935 err_hweffect: |
894 if (effect->hweffect != NULL) { | 936 if (effect->hweffect != NULL) { |
895 SDL_free(effect->hweffect); | 937 SDL_free(effect->hweffect); |
896 effect->hweffect = NULL; | 938 effect->hweffect = NULL; |
897 } | 939 } |
905 int | 947 int |
906 SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, | 948 SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, |
907 struct haptic_effect * effect, SDL_HapticEffect * data) | 949 struct haptic_effect * effect, SDL_HapticEffect * data) |
908 { | 950 { |
909 HRESULT ret; | 951 HRESULT ret; |
910 FFEffectParameterFlag flags; | 952 DWORD flags; |
911 FFEFFECT temp; | 953 DIEFFECT temp; |
912 | 954 |
913 /* Get the effect. */ | 955 /* Get the effect. */ |
914 SDL_memset(&temp, 0, sizeof(FFEFFECT)); | 956 SDL_memset(&temp, 0, sizeof(DIEFFECT)); |
915 if (SDL_SYS_ToFFEFFECT(haptic, &temp, data) < 0) { | 957 if (SDL_SYS_ToDIEFFECT(haptic, &temp, data) < 0) { |
916 goto err_update; | 958 goto err_update; |
917 } | 959 } |
918 | 960 |
919 /* Set the flags. Might be worthwhile to diff temp with loaded effect and | 961 /* Set the flags. Might be worthwhile to diff temp with loaded effect and |
920 * only change those parameters. */ | 962 * only change those parameters. */ |
921 flags = FFEP_ALLPARAMS; | 963 flags = DIEP_DIRECTION | |
964 DIEP_DURATION | | |
965 DIEP_ENVELOPE | | |
966 DIEP_STARTDELAY | | |
967 DIEP_TRIGGERBUTTON | | |
968 DIEP_TRIGGERREPEATINTERVAL | | |
969 DIEP_TYPESPECIFICPARAMS; | |
922 | 970 |
923 /* Create the actual effect. */ | 971 /* Create the actual effect. */ |
924 ret = FFEffectSetParameters(effect->hweffect->ref, &temp, flags); | 972 ret = IDirectInputDevice2_SetParameters(effect->hweffect->ref, &temp, flags); |
925 if (ret != FF_OK) { | 973 if (ret != FF_OK) { |
926 SDL_SetError("Haptic: Unable to update effect: %s.", FFStrError(ret)); | 974 SDL_SetError("Haptic: Unable to update effect: %s.", FFStrError(ret)); |
927 goto err_update; | 975 goto err_update; |
928 } | 976 } |
929 | 977 |
930 /* Copy it over. */ | 978 /* Copy it over. */ |
931 SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, data->type); | 979 SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, data->type); |
932 SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(FFEFFECT)); | 980 SDL_memcpy(&effect->hweffect->effect, &temp, sizeof(DIEFFECT)); |
933 | 981 |
934 return 0; | 982 return 0; |
935 | 983 |
936 err_update: | 984 err_update: |
937 SDL_SYS_HapticFreeFFEFFECT(&temp, data->type); | 985 SDL_SYS_HapticFreeDIEFFECT(&temp, data->type); |
938 return -1; | 986 return -1; |
939 } | 987 } |
940 | 988 |
941 | 989 |
942 /* | 990 /* |
945 int | 993 int |
946 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect * effect, | 994 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect * effect, |
947 Uint32 iterations) | 995 Uint32 iterations) |
948 { | 996 { |
949 HRESULT ret; | 997 HRESULT ret; |
950 Uint32 iter; | 998 DWORD iter; |
951 | 999 |
952 /* Check if it's infinite. */ | 1000 /* Check if it's infinite. */ |
953 if (iterations == SDL_HAPTIC_INFINITY) { | 1001 if (iterations == SDL_HAPTIC_INFINITY) { |
954 iter = FF_INFINITE; | 1002 iter = INFINITE; |
955 } | 1003 } |
956 else | 1004 else |
957 iter = iterations; | 1005 iter = iterations; |
958 | 1006 |
959 /* Run the effect. */ | 1007 /* Run the effect. */ |
960 ret = FFEffectStart(effect->hweffect->ref, iter, 0); | 1008 ret = IDirectInputEffect_Start( effect->hweffect->ref, iter, 0 ); |
961 if (ret != FF_OK) { | 1009 if (FAILED(ret)) { |
962 SDL_SetError("Haptic: Unable to run the effect: %s.", FFStrError(ret)); | 1010 DI_SetError("Running the effect",ret); |
963 return -1; | 1011 return -1; |
964 } | 1012 } |
965 | 1013 |
966 return 0; | 1014 return 0; |
967 } | 1015 } |
973 int | 1021 int |
974 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect * effect) | 1022 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect * effect) |
975 { | 1023 { |
976 HRESULT ret; | 1024 HRESULT ret; |
977 | 1025 |
978 ret = FFEffectStop(effect->hweffect->ref); | 1026 ret = IDirectInputEffect_Stop(effect->hweffect->ref); |
979 if (ret != FF_OK) { | 1027 if (FAILED(ret)) { |
980 SDL_SetError("Haptic: Unable to stop the effect: %s.", FFStrError(ret)); | 1028 DI_SetError("Unable to stop effect",ret); |
981 return -1; | 1029 return -1; |
982 } | 1030 } |
983 | 1031 |
984 return 0; | 1032 return 0; |
985 } | 1033 } |
991 void | 1039 void |
992 SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect * effect) | 1040 SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect * effect) |
993 { | 1041 { |
994 HRESULT ret; | 1042 HRESULT ret; |
995 | 1043 |
996 ret = FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref); | 1044 ret = IDirectInputEffect_Unload(effect->hweffect->ref); |
997 if (ret != FF_OK) { | 1045 if (FAILED(ret)) { |
998 SDL_SetError("Haptic: Error removing the effect from the device: %s.", | 1046 DI_SetError("Removing effect from the device",ret); |
999 FFStrError(ret)); | 1047 } |
1000 } | 1048 SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, effect->effect.type); |
1001 SDL_free(effect->hweffect->effect.lpvTypeSpecificParams); | |
1002 effect->hweffect->effect.lpvTypeSpecificParams = NULL; | |
1003 SDL_free(effect->hweffect); | 1049 SDL_free(effect->hweffect); |
1004 effect->hweffect = NULL; | 1050 effect->hweffect = NULL; |
1005 } | 1051 } |
1006 | 1052 |
1007 | 1053 |
1009 * Gets the status of a haptic effect. | 1055 * Gets the status of a haptic effect. |
1010 */ | 1056 */ |
1011 int | 1057 int |
1012 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect * effect) | 1058 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect * effect) |
1013 { | 1059 { |
1060 SDL_SetError("Haptic: Status not supported."); | |
1061 return -1; | |
1014 } | 1062 } |
1015 | 1063 |
1016 | 1064 |
1017 /* | 1065 /* |
1018 * Sets the gain. | 1066 * Sets the gain. |