Improved error checking in the haptic system, preventing crashes in some cases.
authorSam Lantinga <slouken@libsdl.org>
Sat, 27 Jul 2013 02:45:26 -0700
changeset 75246d8fd70e1477
parent 7523 9e9ab1dc3811
child 7525 e5ae3502a25e
Improved error checking in the haptic system, preventing crashes in some cases.

Edgar Simo 2012-05-06 02:33:39 EDT

I recall that driver being buggy back in the day, but looking over the code there's a number of things being done wrong which I've fixed and it should now properly error out instead of crashing. Also make sure you initialize the haptic subsystem before using haptic commands (which I now more explicitly try to enforce).
src/haptic/SDL_haptic.c
     1.1 --- a/src/haptic/SDL_haptic.c	Sun Jul 14 18:17:28 2013 -0700
     1.2 +++ b/src/haptic/SDL_haptic.c	Sat Jul 27 02:45:26 2013 -0700
     1.3 @@ -149,18 +149,23 @@
     1.4          return NULL;
     1.5      }
     1.6  
     1.7 +    /* Add haptic to list */
     1.8 +    for (i = 0; SDL_haptics[i]; i++)
     1.9 +        /* Skip to next haptic */ ;
    1.10 +    if (i >= SDL_numhaptics) {
    1.11 +        SDL_free(haptic);
    1.12 +        SDL_SetError("Haptic: Trying to add device past the number originally detected");
    1.13 +        return NULL;
    1.14 +    }
    1.15 +    SDL_haptics[i] = haptic;
    1.16 +    ++haptic->ref_count;
    1.17 +
    1.18      /* Disable autocenter and set gain to max. */
    1.19      if (haptic->supported & SDL_HAPTIC_GAIN)
    1.20          SDL_HapticSetGain(haptic, 100);
    1.21      if (haptic->supported & SDL_HAPTIC_AUTOCENTER)
    1.22          SDL_HapticSetAutocenter(haptic, 0);
    1.23  
    1.24 -    /* Add haptic to list */
    1.25 -    ++haptic->ref_count;
    1.26 -    for (i = 0; SDL_haptics[i]; i++)
    1.27 -        /* Skip to next haptic */ ;
    1.28 -    SDL_haptics[i] = haptic;
    1.29 -
    1.30      return haptic;
    1.31  }
    1.32  
    1.33 @@ -173,6 +178,13 @@
    1.34  {
    1.35      int i, opened;
    1.36  
    1.37 +    /* Make sure it's valid. */
    1.38 +    if ((device_index < 0) || (device_index >= SDL_numhaptics)) {
    1.39 +        SDL_SetError("Haptic: There are %d haptic devices available",
    1.40 +                     SDL_numhaptics);
    1.41 +        return -1;
    1.42 +    }
    1.43 +
    1.44      opened = 0;
    1.45      for (i = 0; SDL_haptics[i]; i++) {
    1.46          if (SDL_haptics[i]->index == (Uint8) device_index) {
    1.47 @@ -262,6 +274,13 @@
    1.48      int i;
    1.49      SDL_Haptic *haptic;
    1.50  
    1.51 +    /* Make sure there is room. */
    1.52 +    if (SDL_numhaptics <= 0) {
    1.53 +        SDL_SetError("Haptic: There are %d haptic devices available",
    1.54 +                     SDL_numhaptics);
    1.55 +        return NULL;
    1.56 +    }
    1.57 +
    1.58      /* Must be a valid joystick */
    1.59      if (!SDL_PrivateJoystickValid(joystick)) {
    1.60          SDL_SetError("Haptic: Joystick isn't valid.");
    1.61 @@ -299,10 +318,15 @@
    1.62      }
    1.63  
    1.64      /* Add haptic to list */
    1.65 -    ++haptic->ref_count;
    1.66      for (i = 0; SDL_haptics[i]; i++)
    1.67          /* Skip to next haptic */ ;
    1.68 +    if (i >= SDL_numhaptics) {
    1.69 +        SDL_free(haptic);
    1.70 +        SDL_SetError("Haptic: Trying to add device past the number originally detected");
    1.71 +        return NULL;
    1.72 +    }
    1.73      SDL_haptics[i] = haptic;
    1.74 +    ++haptic->ref_count;
    1.75  
    1.76      return haptic;
    1.77  }
    1.78 @@ -757,6 +781,7 @@
    1.79  int
    1.80  SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length)
    1.81  {
    1.82 +    int ret;
    1.83      SDL_HapticPeriodic *efx;
    1.84  
    1.85      if (!ValidHaptic(haptic)) {
    1.86 @@ -779,7 +804,10 @@
    1.87      efx = &haptic->rumble_effect.periodic;
    1.88      efx->magnitude = (Sint16)(32767.0f*strength);
    1.89      efx->length = length;
    1.90 -    SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect);
    1.91 +    ret = SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect);
    1.92 +    if (ret) {
    1.93 +        return ret;
    1.94 +    }
    1.95  
    1.96      return SDL_HapticRunEffect(haptic, haptic->rumble_id, 1);
    1.97  }