src/haptic/darwin/SDL_syshaptic.c
branchgsoc2008_force_feedback
changeset 2541 f2649eaa552e
parent 2538 1f9c20580ab4
child 2542 4e055fa7acb9
equal deleted inserted replaced
2540:56cf872c723a 2541:f2649eaa552e
    70 /*
    70 /*
    71  * Prototypes.
    71  * Prototypes.
    72  */
    72  */
    73 static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type);
    73 static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type);
    74 static int HIDGetDeviceProduct(io_service_t dev, char * name);
    74 static int HIDGetDeviceProduct(io_service_t dev, char * name);
       
    75 
       
    76 
       
    77 /* 
       
    78  * Like strerror but for force feedback errors.
       
    79  */
       
    80 static const char *
       
    81 FFStrError(HRESULT err)
       
    82 {
       
    83    switch (err) {
       
    84       case FFERR_DEVICEFULL:
       
    85          return "device full";
       
    86       case FFERR_DEVICENOTREG:
       
    87          return "device not registered";
       
    88       case FFERR_DEVICEPAUSED:
       
    89          return "device paused";
       
    90       case FFERR_DEVICERELEASED:
       
    91          return "device released";
       
    92       case FFERR_EFFECTPLAYING:
       
    93          return "effect playing";
       
    94       case FFERR_EFFECTTYPEMISMATCH:
       
    95          return "effect type mismatch";
       
    96       case FFERR_EFFECTTYPENOTSUPPORTED:
       
    97          return "effect type not supported";
       
    98       case FFERR_GENERIC:
       
    99          return "undetermined error";
       
   100       case FFERR_HASEFFECTS:
       
   101          return "device has effects";
       
   102       case FFERR_INCOMPLETEEFFECT:
       
   103          return "incomplete effect";
       
   104       case FFERR_INTERNAL:
       
   105          return "internal fault";
       
   106       case FFERR_INVALIDDOWNLOADID:
       
   107          return "invalid download id";
       
   108       case FFERR_INVALIDPARAM:
       
   109          return "invalid parameter";
       
   110       case FFERR_MOREDATA:
       
   111          return "more data";
       
   112       case FFERR_NOINTERFACE:
       
   113          return "interface not supported";
       
   114       case FFERR_NOTDOWNLOADED:
       
   115          return "effect is not downloaded";
       
   116       case FFERR_NOTINITIALIZED:
       
   117          return "object has not been initialized";
       
   118       case FFERR_OUTOFMEMORY:
       
   119          return "out of memory";
       
   120       case FFERR_UNPLUGGED:
       
   121          return "device is unplugged";
       
   122       case FFERR_UNSUPPORTED:
       
   123          return "function call unsupported";
       
   124       case FFERR_UNSUPPORTEDAXIS:
       
   125          return "axis unsupported";
       
   126 
       
   127       default:
       
   128          return "unknown error";
       
   129    }
       
   130 }
    75 
   131 
    76 
   132 
    77 /*
   133 /*
    78  * Initializes the haptic subsystem.
   134  * Initializes the haptic subsystem.
    79  */
   135  */
   242    /* Check if supports gain. */
   298    /* Check if supports gain. */
   243    ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFGAIN,
   299    ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_FFGAIN,
   244                                           &val, sizeof(val));
   300                                           &val, sizeof(val));
   245    if (ret == FF_OK) supported |= SDL_HAPTIC_GAIN;
   301    if (ret == FF_OK) supported |= SDL_HAPTIC_GAIN;
   246    else if (ret != FFERR_UNSUPPORTED) {
   302    else if (ret != FFERR_UNSUPPORTED) {
   247       SDL_SetError("Haptic: Unable to get if device supports gain.");
   303       SDL_SetError("Haptic: Unable to get if device supports gain: %s.",
       
   304                    FFStrError(ret););
   248       return 0;
   305       return 0;
   249    }
   306    }
   250 
   307 
   251    /* Checks if supports autocenter. */
   308    /* Checks if supports autocenter. */
   252    ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_AUTOCENTER,
   309    ret = FFDeviceGetForceFeedbackProperty(device, FFPROP_AUTOCENTER,
   253                                           &val, sizeof(val));
   310                                           &val, sizeof(val));
   254    if (ret == FF_OK) supported |= SDL_HAPTIC_AUTOCENTER;
   311    if (ret == FF_OK) supported |= SDL_HAPTIC_AUTOCENTER;
   255    else if (ret != FFERR_UNSUPPORTED) {
   312    else if (ret != FFERR_UNSUPPORTED) {
   256       SDL_SetError("Haptic: Unable to get if device supports autocenter.");
   313       SDL_SetError("Haptic: Unable to get if device supports autocenter: %s.",
       
   314                    FFStrError(ret));
   257       return 0;
   315       return 0;
   258    }
   316    }
   259 
   317 
   260    /* Check for axes, we have an artificial limit on axes */
   318    /* Check for axes, we have an artificial limit on axes */
   261    *naxes = ((features.numFfAxes) > 3) ?
   319    *naxes = ((features.numFfAxes) > 3) ?
   271  * Opens the haptic device from the file descriptor.
   329  * Opens the haptic device from the file descriptor.
   272  */
   330  */
   273 static int
   331 static int
   274 SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
   332 SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
   275 {
   333 {
       
   334    HRESULT ret;
       
   335 
   276    /* Allocate the hwdata */
   336    /* Allocate the hwdata */
   277    haptic->hwdata = (struct haptic_hwdata *)
   337    haptic->hwdata = (struct haptic_hwdata *)
   278          SDL_malloc(sizeof(*haptic->hwdata));
   338          SDL_malloc(sizeof(*haptic->hwdata));
   279    if (haptic->hwdata == NULL) {
   339    if (haptic->hwdata == NULL) {
   280       SDL_OutOfMemory();
   340       SDL_OutOfMemory();
   281       goto creat_err;
   341       goto creat_err;
   282    }
   342    }
   283    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
   343    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
   284   
   344   
   285    /* Open the device */
   345    /* Open the device */
   286    if (FFCreateDevice( service, &haptic->hwdata->device ) != FF_OK) {
   346    ret = FFCreateDevice( service, &haptic->hwdata->device);
   287       SDL_SetError("Haptic: Unable to create device from service.");
   347    if (ret != FF_OK) {
       
   348       SDL_SetError("Haptic: Unable to create device from service: %s.",
       
   349                    FFStrError(ret));
   288       goto creat_err;
   350       goto creat_err;
   289    }
   351    }
   290 
   352 
   291    /* Get supported features. */
   353    /* Get supported features. */
   292    haptic->supported = GetSupportedFeatures(haptic->hwdata->device,
   354    haptic->supported = GetSupportedFeatures(haptic->hwdata->device,
   838    }
   900    }
   839 
   901 
   840    /* Create the actual effect. */
   902    /* Create the actual effect. */
   841    ret = FFDeviceCreateEffect(haptic->hwdata->device, type,
   903    ret = FFDeviceCreateEffect(haptic->hwdata->device, type,
   842          &effect->hweffect->effect, &effect->hweffect->ref);
   904          &effect->hweffect->effect, &effect->hweffect->ref);
   843 
       
   844    if (ret != FF_OK) {
   905    if (ret != FF_OK) {
   845       SDL_SetError("Haptic: Unable to create effect.");
   906       SDL_SetError("Haptic: Unable to create effect: %s.", FFStrError(ret));
   846       goto err_effectdone;
   907       goto err_effectdone;
   847    }
   908    }
   848 
   909 
   849    return 0;
   910    return 0;
   850 
   911 
   883    /* Create the actual effect. */
   944    /* Create the actual effect. */
   884    ret = FFEffectSetParameters(haptic->hwdata->device, effect->hweffect->ref,
   945    ret = FFEffectSetParameters(haptic->hwdata->device, effect->hweffect->ref,
   885                                &temp, flags);
   946                                &temp, flags);
   886 
   947 
   887    if (ret != FF_OK) {
   948    if (ret != FF_OK) {
   888       SDL_SetError("Haptic: Unable to update effect.");
   949       SDL_SetError("Haptic: Unable to update effect: %s.", FFStrError(ret));
   889       goto err_update;
   950       goto err_update;
   890    }
   951    }
   891 
   952 
   892    /* Copy it over. */
   953    /* Copy it over. */
   893    SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, data->type);
   954    SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, data->type);
   919       iter = iterations;
   980       iter = iterations;
   920 
   981 
   921    /* Run the effect. */
   982    /* Run the effect. */
   922    ret = FFEffectStart(effect->hweffect->ref, iter, 0);
   983    ret = FFEffectStart(effect->hweffect->ref, iter, 0);
   923    if (ret != FF_OK) {
   984    if (ret != FF_OK) {
   924       SDL_SetError("Haptic: Unable to run the effect.");
   985       SDL_SetError("Haptic: Unable to run the effect: %s.", FFStrError(ret));
   925       return -1;
   986       return -1;
   926    }
   987    }
   927 
   988 
   928    return 0;
   989    return 0;
   929 }
   990 }
   937 {
   998 {
   938    HRESULT ret;
   999    HRESULT ret;
   939 
  1000 
   940    ret = FFEffectStop(effect->hweffect->ref);
  1001    ret = FFEffectStop(effect->hweffect->ref);
   941    if (ret != FF_OK) {
  1002    if (ret != FF_OK) {
   942       SDL_SetError("Haptic: Unable to stop the effect.");
  1003       SDL_SetError("Haptic: Unable to stop the effect: %s.", FFStrError(ret));
   943       return -1;
  1004       return -1;
   944    }
  1005    }
   945 
  1006 
   946    return 0;
  1007    return 0;
   947 }
  1008 }
   955 {
  1016 {
   956    HRESULT ret;
  1017    HRESULT ret;
   957 
  1018 
   958    ret = FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref);
  1019    ret = FFDeviceReleaseEffect(haptic->hwdata->device, effect->hweffect->ref);
   959    if (ret != FF_OK) {
  1020    if (ret != FF_OK) {
   960       SDL_SetError("Haptic: Error removing the effect from the device.");
  1021       SDL_SetError("Haptic: Error removing the effect from the device: %s.",
       
  1022                    FFStrError(ret));
   961    }
  1023    }
   962    SDL_free(effect->hweffect->effect.lpvTypeSpecificParams);
  1024    SDL_free(effect->hweffect->effect.lpvTypeSpecificParams);
   963    effect->hweffect->effect.lpvTypeSpecificParams = NULL;
  1025    effect->hweffect->effect.lpvTypeSpecificParams = NULL;
   964    SDL_free(effect->hweffect);
  1026    SDL_free(effect->hweffect);
   965    effect->hweffect = NULL;
  1027    effect->hweffect = NULL;
   975    HRESULT ret;
  1037    HRESULT ret;
   976    FFEffectStatusFlag status;
  1038    FFEffectStatusFlag status;
   977 
  1039 
   978    ret = FFEffectGetEffectStatus(effect->hweffect->ref, &status);
  1040    ret = FFEffectGetEffectStatus(effect->hweffect->ref, &status);
   979    if (ret != FF_OK) {
  1041    if (ret != FF_OK) {
   980       SDL_SetError("Haptic: Unable to get effect status.");
  1042       SDL_SetError("Haptic: Unable to get effect status: %s.", FFStrError(ret));
   981       return -1;
  1043       return -1;
   982    }
  1044    }
   983 
  1045 
   984    if (status == 0) return SDL_FALSE;
  1046    if (status == 0) return SDL_FALSE;
   985    return SDL_TRUE; /* Assume it's playing or emulated. */
  1047    return SDL_TRUE; /* Assume it's playing or emulated. */
   996    Uint32 val;
  1058    Uint32 val;
   997 
  1059 
   998    val = gain * 100; /* Mac OS X uses 0 to 10,000 */
  1060    val = gain * 100; /* Mac OS X uses 0 to 10,000 */
   999    ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device, FFPROP_FFGAIN, &val);
  1061    ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device, FFPROP_FFGAIN, &val);
  1000    if (ret != FF_OK) {
  1062    if (ret != FF_OK) {
  1001       SDL_SetError("Haptic: Error setting gain.");
  1063       SDL_SetError("Haptic: Error setting gain: %s.", FFStrError(ret));
  1002       return -1;
  1064       return -1;
  1003    }
  1065    }
  1004 
  1066 
  1005    return 0;
  1067    return 0;
  1006 }
  1068 }
  1020    else val = 1;
  1082    else val = 1;
  1021 
  1083 
  1022    ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
  1084    ret = FFDeviceSetForceFeedbackProperty(haptic->hwdata->device,
  1023                FFPROP_AUTOCENTER, &val);
  1085                FFPROP_AUTOCENTER, &val);
  1024    if (ret != FF_OK) {
  1086    if (ret != FF_OK) {
  1025       SDL_SetError("Haptic: Error setting autocenter.");
  1087       SDL_SetError("Haptic: Error setting autocenter: %s.", FFStrError(ret));
  1026       return -1;
  1088       return -1;
  1027    }
  1089    }
  1028   
  1090   
  1029    return 0;
  1091    return 0;
  1030 
  1092 
  1031 }
  1093 }
  1032 
  1094 
  1033 
  1095 
  1034 #endif /* SDL_HAPTIC_LINUX */
  1096 #endif /* SDL_HAPTIC_IOKIT */