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.