src/haptic/SDL_haptic.c
 author Alex Szpakowski Tue, 15 Jul 2014 02:01:43 -0300 branch iOS-improvements changeset 9489 6cd0275146b3 parent 8974 f813b8b10b55 child 9619 b94b6d0bff0f permissions -rw-r--r--
iOS now respects SDL_HINT_ACCELEROMETER_AS_JOYSTICK.
```     1 /*
```
```     2   Simple DirectMedia Layer
```
```     3   Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
```
```     4
```
```     5   This software is provided 'as-is', without any express or implied
```
```     6   warranty.  In no event will the authors be held liable for any damages
```
```     7   arising from the use of this software.
```
```     8
```
```     9   Permission is granted to anyone to use this software for any purpose,
```
```    10   including commercial applications, and to alter it and redistribute it
```
```    11   freely, subject to the following restrictions:
```
```    12
```
```    13   1. The origin of this software must not be misrepresented; you must not
```
```    14      claim that you wrote the original software. If you use this software
```
```    15      in a product, an acknowledgment in the product documentation would be
```
```    16      appreciated but is not required.
```
```    17   2. Altered source versions must be plainly marked as such, and must not be
```
```    18      misrepresented as being the original software.
```
```    19   3. This notice may not be removed or altered from any source distribution.
```
```    20 */
```
```    21 #include "../SDL_internal.h"
```
```    22
```
```    23 #include "SDL_syshaptic.h"
```
```    24 #include "SDL_haptic_c.h"
```
```    25 #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */
```
```    26 #include "SDL_assert.h"
```
```    27
```
```    28 SDL_Haptic *SDL_haptics = NULL;
```
```    29
```
```    30
```
```    31 /*
```
```    32  * Initializes the Haptic devices.
```
```    33  */
```
```    34 int
```
```    35 SDL_HapticInit(void)
```
```    36 {
```
```    37     int status;
```
```    38
```
```    39     status = SDL_SYS_HapticInit();
```
```    40     if (status >= 0) {
```
```    41         status = 0;
```
```    42     }
```
```    43
```
```    44     return status;
```
```    45 }
```
```    46
```
```    47
```
```    48 /*
```
```    49  * Checks to see if the haptic device is valid
```
```    50  */
```
```    51 static int
```
```    52 ValidHaptic(SDL_Haptic * haptic)
```
```    53 {
```
```    54     int valid;
```
```    55     SDL_Haptic *hapticlist;
```
```    56
```
```    57     valid = 0;
```
```    58     if (haptic != NULL) {
```
```    59         hapticlist = SDL_haptics;
```
```    60         while ( hapticlist )
```
```    61         {
```
```    62             if (hapticlist == haptic) {
```
```    63                 valid = 1;
```
```    64                 break;
```
```    65             }
```
```    66             hapticlist = hapticlist->next;
```
```    67         }
```
```    68     }
```
```    69
```
```    70     /* Create the error here. */
```
```    71     if (valid == 0) {
```
```    72         SDL_SetError("Haptic: Invalid haptic device identifier");
```
```    73     }
```
```    74
```
```    75     return valid;
```
```    76 }
```
```    77
```
```    78
```
```    79 /*
```
```    80  * Returns the number of available devices.
```
```    81  */
```
```    82 int
```
```    83 SDL_NumHaptics(void)
```
```    84 {
```
```    85     return SDL_SYS_NumHaptics();
```
```    86 }
```
```    87
```
```    88
```
```    89 /*
```
```    90  * Gets the name of a Haptic device by index.
```
```    91  */
```
```    92 const char *
```
```    93 SDL_HapticName(int device_index)
```
```    94 {
```
```    95     if ((device_index < 0) || (device_index >= SDL_NumHaptics())) {
```
```    96         SDL_SetError("Haptic: There are %d haptic devices available",
```
```    97                      SDL_NumHaptics());
```
```    98         return NULL;
```
```    99     }
```
```   100     return SDL_SYS_HapticName(device_index);
```
```   101 }
```
```   102
```
```   103
```
```   104 /*
```
```   105  * Opens a Haptic device.
```
```   106  */
```
```   107 SDL_Haptic *
```
```   108 SDL_HapticOpen(int device_index)
```
```   109 {
```
```   110     SDL_Haptic *haptic;
```
```   111     SDL_Haptic *hapticlist;
```
```   112
```
```   113     if ((device_index < 0) || (device_index >= SDL_NumHaptics())) {
```
```   114         SDL_SetError("Haptic: There are %d haptic devices available",
```
```   115                      SDL_NumHaptics());
```
```   116         return NULL;
```
```   117     }
```
```   118
```
```   119     hapticlist = SDL_haptics;
```
```   120     /* If the haptic is already open, return it
```
```   121     * TODO: Should we create haptic instance IDs like the Joystick API?
```
```   122     */
```
```   123     while ( hapticlist )
```
```   124     {
```
```   125         if (device_index == hapticlist->index) {
```
```   126             haptic = hapticlist;
```
```   127             ++haptic->ref_count;
```
```   128             return haptic;
```
```   129         }
```
```   130         hapticlist = hapticlist->next;
```
```   131     }
```
```   132
```
```   133     /* Create the haptic device */
```
```   134     haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic));
```
```   135     if (haptic == NULL) {
```
```   136         SDL_OutOfMemory();
```
```   137         return NULL;
```
```   138     }
```
```   139
```
```   140     /* Initialize the haptic device */
```
```   141     SDL_memset(haptic, 0, (sizeof *haptic));
```
```   142     haptic->rumble_id = -1;
```
```   143     haptic->index = device_index;
```
```   144     if (SDL_SYS_HapticOpen(haptic) < 0) {
```
```   145         SDL_free(haptic);
```
```   146         return NULL;
```
```   147     }
```
```   148
```
```   149     /* Add haptic to list */
```
```   150     ++haptic->ref_count;
```
```   151     /* Link the haptic in the list */
```
```   152     haptic->next = SDL_haptics;
```
```   153     SDL_haptics = haptic;
```
```   154
```
```   155     /* Disable autocenter and set gain to max. */
```
```   156     if (haptic->supported & SDL_HAPTIC_GAIN)
```
```   157         SDL_HapticSetGain(haptic, 100);
```
```   158     if (haptic->supported & SDL_HAPTIC_AUTOCENTER)
```
```   159         SDL_HapticSetAutocenter(haptic, 0);
```
```   160
```
```   161     return haptic;
```
```   162 }
```
```   163
```
```   164
```
```   165 /*
```
```   166  * Returns 1 if the device has been opened.
```
```   167  */
```
```   168 int
```
```   169 SDL_HapticOpened(int device_index)
```
```   170 {
```
```   171     int opened;
```
```   172     SDL_Haptic *hapticlist;
```
```   173
```
```   174     /* Make sure it's valid. */
```
```   175     if ((device_index < 0) || (device_index >= SDL_NumHaptics())) {
```
```   176         SDL_SetError("Haptic: There are %d haptic devices available",
```
```   177                      SDL_NumHaptics());
```
```   178         return 0;
```
```   179     }
```
```   180
```
```   181     opened = 0;
```
```   182     hapticlist = SDL_haptics;
```
```   183     /* TODO Should this use an instance ID? */
```
```   184     while ( hapticlist )
```
```   185     {
```
```   186         if (hapticlist->index == (Uint8) device_index) {
```
```   187             opened = 1;
```
```   188             break;
```
```   189         }
```
```   190         hapticlist = hapticlist->next;
```
```   191     }
```
```   192     return opened;
```
```   193 }
```
```   194
```
```   195
```
```   196 /*
```
```   197  * Returns the index to a haptic device.
```
```   198  */
```
```   199 int
```
```   200 SDL_HapticIndex(SDL_Haptic * haptic)
```
```   201 {
```
```   202     if (!ValidHaptic(haptic)) {
```
```   203         return -1;
```
```   204     }
```
```   205
```
```   206     return haptic->index;
```
```   207 }
```
```   208
```
```   209
```
```   210 /*
```
```   211  * Returns SDL_TRUE if mouse is haptic, SDL_FALSE if it isn't.
```
```   212  */
```
```   213 int
```
```   214 SDL_MouseIsHaptic(void)
```
```   215 {
```
```   216     if (SDL_SYS_HapticMouse() < 0)
```
```   217         return SDL_FALSE;
```
```   218     return SDL_TRUE;
```
```   219 }
```
```   220
```
```   221
```
```   222 /*
```
```   223  * Returns the haptic device if mouse is haptic or NULL elsewise.
```
```   224  */
```
```   225 SDL_Haptic *
```
```   226 SDL_HapticOpenFromMouse(void)
```
```   227 {
```
```   228     int device_index;
```
```   229
```
```   230     device_index = SDL_SYS_HapticMouse();
```
```   231
```
```   232     if (device_index < 0) {
```
```   233         SDL_SetError("Haptic: Mouse isn't a haptic device.");
```
```   234         return NULL;
```
```   235     }
```
```   236
```
```   237     return SDL_HapticOpen(device_index);
```
```   238 }
```
```   239
```
```   240
```
```   241 /*
```
```   242  * Returns SDL_TRUE if joystick has haptic features.
```
```   243  */
```
```   244 int
```
```   245 SDL_JoystickIsHaptic(SDL_Joystick * joystick)
```
```   246 {
```
```   247     int ret;
```
```   248
```
```   249     /* Must be a valid joystick */
```
```   250     if (!SDL_PrivateJoystickValid(joystick)) {
```
```   251         return -1;
```
```   252     }
```
```   253
```
```   254     ret = SDL_SYS_JoystickIsHaptic(joystick);
```
```   255
```
```   256     if (ret > 0)
```
```   257         return SDL_TRUE;
```
```   258     else if (ret == 0)
```
```   259         return SDL_FALSE;
```
```   260     else
```
```   261         return -1;
```
```   262 }
```
```   263
```
```   264
```
```   265 /*
```
```   266  * Opens a haptic device from a joystick.
```
```   267  */
```
```   268 SDL_Haptic *
```
```   269 SDL_HapticOpenFromJoystick(SDL_Joystick * joystick)
```
```   270 {
```
```   271     SDL_Haptic *haptic;
```
```   272     SDL_Haptic *hapticlist;
```
```   273
```
```   274     /* Make sure there is room. */
```
```   275     if (SDL_NumHaptics() <= 0) {
```
```   276         SDL_SetError("Haptic: There are %d haptic devices available",
```
```   277                      SDL_NumHaptics());
```
```   278         return NULL;
```
```   279     }
```
```   280
```
```   281     /* Must be a valid joystick */
```
```   282     if (!SDL_PrivateJoystickValid(joystick)) {
```
```   283         SDL_SetError("Haptic: Joystick isn't valid.");
```
```   284         return NULL;
```
```   285     }
```
```   286
```
```   287     /* Joystick must be haptic */
```
```   288     if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) {
```
```   289         SDL_SetError("Haptic: Joystick isn't a haptic device.");
```
```   290         return NULL;
```
```   291     }
```
```   292
```
```   293     hapticlist = SDL_haptics;
```
```   294     /* Check to see if joystick's haptic is already open */
```
```   295     while ( hapticlist )
```
```   296     {
```
```   297         if (SDL_SYS_JoystickSameHaptic(hapticlist, joystick)) {
```
```   298             haptic = hapticlist;
```
```   299             ++haptic->ref_count;
```
```   300             return haptic;
```
```   301         }
```
```   302         hapticlist = hapticlist->next;
```
```   303     }
```
```   304
```
```   305     /* Create the haptic device */
```
```   306     haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic));
```
```   307     if (haptic == NULL) {
```
```   308         SDL_OutOfMemory();
```
```   309         return NULL;
```
```   310     }
```
```   311
```
```   312     /* Initialize the haptic device */
```
```   313     SDL_memset(haptic, 0, sizeof(SDL_Haptic));
```
```   314     haptic->rumble_id = -1;
```
```   315     if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) {
```
```   316         SDL_free(haptic);
```
```   317         return NULL;
```
```   318     }
```
```   319
```
```   320     /* Add haptic to list */
```
```   321     ++haptic->ref_count;
```
```   322     /* Link the haptic in the list */
```
```   323     haptic->next = SDL_haptics;
```
```   324     SDL_haptics = haptic;
```
```   325
```
```   326     return haptic;
```
```   327 }
```
```   328
```
```   329
```
```   330 /*
```
```   331  * Closes a SDL_Haptic device.
```
```   332  */
```
```   333 void
```
```   334 SDL_HapticClose(SDL_Haptic * haptic)
```
```   335 {
```
```   336     int i;
```
```   337     SDL_Haptic *hapticlist;
```
```   338     SDL_Haptic *hapticlistprev;
```
```   339
```
```   340     /* Must be valid */
```
```   341     if (!ValidHaptic(haptic)) {
```
```   342         return;
```
```   343     }
```
```   344
```
```   345     /* Check if it's still in use */
```
```   346     if (--haptic->ref_count > 0) {
```
```   347         return;
```
```   348     }
```
```   349
```
```   350     /* Close it, properly removing effects if needed */
```
```   351     for (i = 0; i < haptic->neffects; i++) {
```
```   352         if (haptic->effects[i].hweffect != NULL) {
```
```   353             SDL_HapticDestroyEffect(haptic, i);
```
```   354         }
```
```   355     }
```
```   356     SDL_SYS_HapticClose(haptic);
```
```   357
```
```   358     /* Remove from the list */
```
```   359     hapticlist = SDL_haptics;
```
```   360     hapticlistprev = NULL;
```
```   361     while ( hapticlist )
```
```   362     {
```
```   363         if (haptic == hapticlist)
```
```   364         {
```
```   365             if ( hapticlistprev )
```
```   366             {
```
```   367                 /* unlink this entry */
```
```   368                 hapticlistprev->next = hapticlist->next;
```
```   369             }
```
```   370             else
```
```   371             {
```
```   372                 SDL_haptics = haptic->next;
```
```   373             }
```
```   374
```
```   375             break;
```
```   376         }
```
```   377         hapticlistprev = hapticlist;
```
```   378         hapticlist = hapticlist->next;
```
```   379     }
```
```   380
```
```   381     /* Free */
```
```   382     SDL_free(haptic);
```
```   383 }
```
```   384
```
```   385 /*
```
```   386  * Cleans up after the subsystem.
```
```   387  */
```
```   388 void
```
```   389 SDL_HapticQuit(void)
```
```   390 {
```
```   391     SDL_SYS_HapticQuit();
```
```   392     SDL_assert(SDL_haptics == NULL);
```
```   393     SDL_haptics = NULL;
```
```   394 }
```
```   395
```
```   396 /*
```
```   397  * Returns the number of effects a haptic device has.
```
```   398  */
```
```   399 int
```
```   400 SDL_HapticNumEffects(SDL_Haptic * haptic)
```
```   401 {
```
```   402     if (!ValidHaptic(haptic)) {
```
```   403         return -1;
```
```   404     }
```
```   405
```
```   406     return haptic->neffects;
```
```   407 }
```
```   408
```
```   409
```
```   410 /*
```
```   411  * Returns the number of effects a haptic device can play.
```
```   412  */
```
```   413 int
```
```   414 SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic)
```
```   415 {
```
```   416     if (!ValidHaptic(haptic)) {
```
```   417         return -1;
```
```   418     }
```
```   419
```
```   420     return haptic->nplaying;
```
```   421 }
```
```   422
```
```   423
```
```   424 /*
```
```   425  * Returns supported effects by the device.
```
```   426  */
```
```   427 unsigned int
```
```   428 SDL_HapticQuery(SDL_Haptic * haptic)
```
```   429 {
```
```   430     if (!ValidHaptic(haptic)) {
```
```   431         return 0; /* same as if no effects were supported */
```
```   432     }
```
```   433
```
```   434     return haptic->supported;
```
```   435 }
```
```   436
```
```   437
```
```   438 /*
```
```   439  * Returns the number of axis on the device.
```
```   440  */
```
```   441 int
```
```   442 SDL_HapticNumAxes(SDL_Haptic * haptic)
```
```   443 {
```
```   444     if (!ValidHaptic(haptic)) {
```
```   445         return -1;
```
```   446     }
```
```   447
```
```   448     return haptic->naxes;
```
```   449 }
```
```   450
```
```   451 /*
```
```   452  * Checks to see if the device can support the effect.
```
```   453  */
```
```   454 int
```
```   455 SDL_HapticEffectSupported(SDL_Haptic * haptic, SDL_HapticEffect * effect)
```
```   456 {
```
```   457     if (!ValidHaptic(haptic)) {
```
```   458         return -1;
```
```   459     }
```
```   460
```
```   461     if ((haptic->supported & effect->type) != 0)
```
```   462         return SDL_TRUE;
```
```   463     return SDL_FALSE;
```
```   464 }
```
```   465
```
```   466 /*
```
```   467  * Creates a new haptic effect.
```
```   468  */
```
```   469 int
```
```   470 SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect)
```
```   471 {
```
```   472     int i;
```
```   473
```
```   474     /* Check for device validity. */
```
```   475     if (!ValidHaptic(haptic)) {
```
```   476         return -1;
```
```   477     }
```
```   478
```
```   479     /* Check to see if effect is supported */
```
```   480     if (SDL_HapticEffectSupported(haptic, effect) == SDL_FALSE) {
```
```   481         return SDL_SetError("Haptic: Effect not supported by haptic device.");
```
```   482     }
```
```   483
```
```   484     /* See if there's a free slot */
```
```   485     for (i = 0; i < haptic->neffects; i++) {
```
```   486         if (haptic->effects[i].hweffect == NULL) {
```
```   487
```
```   488             /* Now let the backend create the real effect */
```
```   489             if (SDL_SYS_HapticNewEffect(haptic, &haptic->effects[i], effect)
```
```   490                 != 0) {
```
```   491                 return -1;      /* Backend failed to create effect */
```
```   492             }
```
```   493
```
```   494             SDL_memcpy(&haptic->effects[i].effect, effect,
```
```   495                        sizeof(SDL_HapticEffect));
```
```   496             return i;
```
```   497         }
```
```   498     }
```
```   499
```
```   500     return SDL_SetError("Haptic: Device has no free space left.");
```
```   501 }
```
```   502
```
```   503 /*
```
```   504  * Checks to see if an effect is valid.
```
```   505  */
```
```   506 static int
```
```   507 ValidEffect(SDL_Haptic * haptic, int effect)
```
```   508 {
```
```   509     if ((effect < 0) || (effect >= haptic->neffects)) {
```
```   510         SDL_SetError("Haptic: Invalid effect identifier.");
```
```   511         return 0;
```
```   512     }
```
```   513     return 1;
```
```   514 }
```
```   515
```
```   516 /*
```
```   517  * Updates an effect.
```
```   518  */
```
```   519 int
```
```   520 SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect,
```
```   521                        SDL_HapticEffect * data)
```
```   522 {
```
```   523     if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) {
```
```   524         return -1;
```
```   525     }
```
```   526
```
```   527     /* Can't change type dynamically. */
```
```   528     if (data->type != haptic->effects[effect].effect.type) {
```
```   529         return SDL_SetError("Haptic: Updating effect type is illegal.");
```
```   530     }
```
```   531
```
```   532     /* Updates the effect */
```
```   533     if (SDL_SYS_HapticUpdateEffect(haptic, &haptic->effects[effect], data) <
```
```   534         0) {
```
```   535         return -1;
```
```   536     }
```
```   537
```
```   538     SDL_memcpy(&haptic->effects[effect].effect, data,
```
```   539                sizeof(SDL_HapticEffect));
```
```   540     return 0;
```
```   541 }
```
```   542
```
```   543
```
```   544 /*
```
```   545  * Runs the haptic effect on the device.
```
```   546  */
```
```   547 int
```
```   548 SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, Uint32 iterations)
```
```   549 {
```
```   550     if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) {
```
```   551         return -1;
```
```   552     }
```
```   553
```
```   554     /* Run the effect */
```
```   555     if (SDL_SYS_HapticRunEffect(haptic, &haptic->effects[effect], iterations)
```
```   556         < 0) {
```
```   557         return -1;
```
```   558     }
```
```   559
```
```   560     return 0;
```
```   561 }
```
```   562
```
```   563 /*
```
```   564  * Stops the haptic effect on the device.
```
```   565  */
```
```   566 int
```
```   567 SDL_HapticStopEffect(SDL_Haptic * haptic, int effect)
```
```   568 {
```
```   569     if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) {
```
```   570         return -1;
```
```   571     }
```
```   572
```
```   573     /* Stop the effect */
```
```   574     if (SDL_SYS_HapticStopEffect(haptic, &haptic->effects[effect]) < 0) {
```
```   575         return -1;
```
```   576     }
```
```   577
```
```   578     return 0;
```
```   579 }
```
```   580
```
```   581 /*
```
```   582  * Gets rid of a haptic effect.
```
```   583  */
```
```   584 void
```
```   585 SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect)
```
```   586 {
```
```   587     if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) {
```
```   588         return;
```
```   589     }
```
```   590
```
```   591     /* Not allocated */
```
```   592     if (haptic->effects[effect].hweffect == NULL) {
```
```   593         return;
```
```   594     }
```
```   595
```
```   596     SDL_SYS_HapticDestroyEffect(haptic, &haptic->effects[effect]);
```
```   597 }
```
```   598
```
```   599 /*
```
```   600  * Gets the status of a haptic effect.
```
```   601  */
```
```   602 int
```
```   603 SDL_HapticGetEffectStatus(SDL_Haptic * haptic, int effect)
```
```   604 {
```
```   605     if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) {
```
```   606         return -1;
```
```   607     }
```
```   608
```
```   609     if ((haptic->supported & SDL_HAPTIC_STATUS) == 0) {
```
```   610         return SDL_SetError("Haptic: Device does not support status queries.");
```
```   611     }
```
```   612
```
```   613     return SDL_SYS_HapticGetEffectStatus(haptic, &haptic->effects[effect]);
```
```   614 }
```
```   615
```
```   616 /*
```
```   617  * Sets the global gain of the device.
```
```   618  */
```
```   619 int
```
```   620 SDL_HapticSetGain(SDL_Haptic * haptic, int gain)
```
```   621 {
```
```   622     const char *env;
```
```   623     int real_gain, max_gain;
```
```   624
```
```   625     if (!ValidHaptic(haptic)) {
```
```   626         return -1;
```
```   627     }
```
```   628
```
```   629     if ((haptic->supported & SDL_HAPTIC_GAIN) == 0) {
```
```   630         return SDL_SetError("Haptic: Device does not support setting gain.");
```
```   631     }
```
```   632
```
```   633     if ((gain < 0) || (gain > 100)) {
```
```   634         return SDL_SetError("Haptic: Gain must be between 0 and 100.");
```
```   635     }
```
```   636
```
```   637     /* We use the envvar to get the maximum gain. */
```
```   638     env = SDL_getenv("SDL_HAPTIC_GAIN_MAX");
```
```   639     if (env != NULL) {
```
```   640         max_gain = SDL_atoi(env);
```
```   641
```
```   642         /* Check for sanity. */
```
```   643         if (max_gain < 0)
```
```   644             max_gain = 0;
```
```   645         else if (max_gain > 100)
```
```   646             max_gain = 100;
```
```   647
```
```   648         /* We'll scale it linearly with SDL_HAPTIC_GAIN_MAX */
```
```   649         real_gain = (gain * max_gain) / 100;
```
```   650     } else {
```
```   651         real_gain = gain;
```
```   652     }
```
```   653
```
```   654     if (SDL_SYS_HapticSetGain(haptic, real_gain) < 0) {
```
```   655         return -1;
```
```   656     }
```
```   657
```
```   658     return 0;
```
```   659 }
```
```   660
```
```   661 /*
```
```   662  * Makes the device autocenter, 0 disables.
```
```   663  */
```
```   664 int
```
```   665 SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
```
```   666 {
```
```   667     if (!ValidHaptic(haptic)) {
```
```   668         return -1;
```
```   669     }
```
```   670
```
```   671     if ((haptic->supported & SDL_HAPTIC_AUTOCENTER) == 0) {
```
```   672         return SDL_SetError("Haptic: Device does not support setting autocenter.");
```
```   673     }
```
```   674
```
```   675     if ((autocenter < 0) || (autocenter > 100)) {
```
```   676         return SDL_SetError("Haptic: Autocenter must be between 0 and 100.");
```
```   677     }
```
```   678
```
```   679     if (SDL_SYS_HapticSetAutocenter(haptic, autocenter) < 0) {
```
```   680         return -1;
```
```   681     }
```
```   682
```
```   683     return 0;
```
```   684 }
```
```   685
```
```   686 /*
```
```   687  * Pauses the haptic device.
```
```   688  */
```
```   689 int
```
```   690 SDL_HapticPause(SDL_Haptic * haptic)
```
```   691 {
```
```   692     if (!ValidHaptic(haptic)) {
```
```   693         return -1;
```
```   694     }
```
```   695
```
```   696     if ((haptic->supported & SDL_HAPTIC_PAUSE) == 0) {
```
```   697         return SDL_SetError("Haptic: Device does not support setting pausing.");
```
```   698     }
```
```   699
```
```   700     return SDL_SYS_HapticPause(haptic);
```
```   701 }
```
```   702
```
```   703 /*
```
```   704  * Unpauses the haptic device.
```
```   705  */
```
```   706 int
```
```   707 SDL_HapticUnpause(SDL_Haptic * haptic)
```
```   708 {
```
```   709     if (!ValidHaptic(haptic)) {
```
```   710         return -1;
```
```   711     }
```
```   712
```
```   713     if ((haptic->supported & SDL_HAPTIC_PAUSE) == 0) {
```
```   714         return 0;               /* Not going to be paused, so we pretend it's unpaused. */
```
```   715     }
```
```   716
```
```   717     return SDL_SYS_HapticUnpause(haptic);
```
```   718 }
```
```   719
```
```   720 /*
```
```   721  * Stops all the currently playing effects.
```
```   722  */
```
```   723 int
```
```   724 SDL_HapticStopAll(SDL_Haptic * haptic)
```
```   725 {
```
```   726     if (!ValidHaptic(haptic)) {
```
```   727         return -1;
```
```   728     }
```
```   729
```
```   730     return SDL_SYS_HapticStopAll(haptic);
```
```   731 }
```
```   732
```
```   733 /*
```
```   734  * Checks to see if rumble is supported.
```
```   735  */
```
```   736 int
```
```   737 SDL_HapticRumbleSupported(SDL_Haptic * haptic)
```
```   738 {
```
```   739     if (!ValidHaptic(haptic)) {
```
```   740         return -1;
```
```   741     }
```
```   742
```
```   743     /* Most things can use SINE, but XInput only has LEFTRIGHT. */
```
```   744     return ((haptic->supported & (SDL_HAPTIC_SINE|SDL_HAPTIC_LEFTRIGHT)) != 0);
```
```   745 }
```
```   746
```
```   747 /*
```
```   748  * Initializes the haptic device for simple rumble playback.
```
```   749  */
```
```   750 int
```
```   751 SDL_HapticRumbleInit(SDL_Haptic * haptic)
```
```   752 {
```
```   753     SDL_HapticEffect *efx = &haptic->rumble_effect;
```
```   754
```
```   755     if (!ValidHaptic(haptic)) {
```
```   756         return -1;
```
```   757     }
```
```   758
```
```   759     /* Already allocated. */
```
```   760     if (haptic->rumble_id >= 0) {
```
```   761         return 0;
```
```   762     }
```
```   763
```
```   764     SDL_zerop(efx);
```
```   765     if (haptic->supported & SDL_HAPTIC_SINE) {
```
```   766         efx->type = SDL_HAPTIC_SINE;
```
```   767         efx->periodic.period = 1000;
```
```   768         efx->periodic.magnitude = 0x4000;
```
```   769         efx->periodic.length = 5000;
```
```   770         efx->periodic.attack_length = 0;
```
```   771         efx->periodic.fade_length = 0;
```
```   772     } else if (haptic->supported & SDL_HAPTIC_LEFTRIGHT) {  /* XInput? */
```
```   773         efx->type = SDL_HAPTIC_LEFTRIGHT;
```
```   774         efx->leftright.length = 5000;
```
```   775         efx->leftright.large_magnitude = 0x4000;
```
```   776         efx->leftright.small_magnitude = 0x4000;
```
```   777     } else {
```
```   778         return SDL_SetError("Device doesn't support rumble");
```
```   779     }
```
```   780
```
```   781     haptic->rumble_id = SDL_HapticNewEffect(haptic, &haptic->rumble_effect);
```
```   782     if (haptic->rumble_id >= 0) {
```
```   783         return 0;
```
```   784     }
```
```   785     return -1;
```
```   786 }
```
```   787
```
```   788 /*
```
```   789  * Runs simple rumble on a haptic device
```
```   790  */
```
```   791 int
```
```   792 SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length)
```
```   793 {
```
```   794     SDL_HapticEffect *efx;
```
```   795     Sint16 magnitude;
```
```   796
```
```   797     if (!ValidHaptic(haptic)) {
```
```   798         return -1;
```
```   799     }
```
```   800
```
```   801     if (haptic->rumble_id < 0) {
```
```   802         return SDL_SetError("Haptic: Rumble effect not initialized on haptic device");
```
```   803     }
```
```   804
```
```   805     /* Clamp strength. */
```
```   806     if (strength > 1.0f) {
```
```   807         strength = 1.0f;
```
```   808     } else if (strength < 0.0f) {
```
```   809         strength = 0.0f;
```
```   810     }
```
```   811     magnitude = (Sint16)(32767.0f*strength);
```
```   812
```
```   813     efx = &haptic->rumble_effect;
```
```   814     if (efx->type == SDL_HAPTIC_SINE) {
```
```   815         efx->periodic.magnitude = magnitude;
```
```   816         efx->periodic.length = length;
```
```   817     } else if (efx->type == SDL_HAPTIC_LEFTRIGHT) {
```
```   818         efx->leftright.small_magnitude = efx->leftright.large_magnitude = magnitude;
```
```   819         efx->leftright.length = length;
```
```   820     } else {
```
```   821         SDL_assert(0 && "This should have been caught elsewhere");
```
```   822     }
```
```   823
```
```   824     if (SDL_HapticUpdateEffect(haptic, haptic->rumble_id, &haptic->rumble_effect) < 0) {
```
```   825         return -1;
```
```   826     }
```
```   827
```
```   828     return SDL_HapticRunEffect(haptic, haptic->rumble_id, 1);
```
```   829 }
```
```   830
```
```   831 /*
```
```   832  * Stops the simple rumble on a haptic device.
```
```   833  */
```
```   834 int
```
```   835 SDL_HapticRumbleStop(SDL_Haptic * haptic)
```
```   836 {
```
```   837     if (!ValidHaptic(haptic)) {
```
```   838         return -1;
```
```   839     }
```
```   840
```
```   841     if (haptic->rumble_id < 0) {
```
```   842         return SDL_SetError("Haptic: Rumble effect not initialized on haptic device");
```
```   843     }
```
```   844
```
```   845     return SDL_HapticStopEffect(haptic, haptic->rumble_id);
```
```   846 }
```
```   847
```
{"ft_lang_label":"__label__en","ft_lang_prob":0.5184516,"math_prob":0.8337076,"size":14290,"snap":"2020-10-2020-16","text_gpt3_token_len":4042,"char_repetition_ratio":0.25136498,"word_repetition_ratio":0.0729702,"special_character_ratio":0.33526942,"punctuation_ratio":0.15215398,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.96332705,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-02-18T10:15:57Z\",\"WARC-Record-ID\":\"<urn:uuid:1f801174-75b1-4800-9376-408307a8359c>\",\"Content-Length\":\"126912\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:fcc3bd87-2a59-4412-9fb9-471a287079a5>\",\"WARC-Concurrent-To\":\"<urn:uuid:583004a7-b2cd-4354-9ca5-8eb6196cdc2f>\",\"WARC-IP-Address\":\"192.241.223.99\",\"WARC-Target-URI\":\"https://hg.libsdl.org/SDL/file/6cd0275146b3/src/haptic/SDL_haptic.c\",\"WARC-Payload-Digest\":\"sha1:25OIPUNDHXROJ6MK3B5GSB2ZZJAENJVB\",\"WARC-Block-Digest\":\"sha1:SAGZSWU2ZTSDEPZ2DHN5FSWQXJVGB2Y7\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-10/CC-MAIN-2020-10_segments_1581875143646.38_warc_CC-MAIN-20200218085715-20200218115715-00326.warc.gz\"}"}