# Haptic routines

Haptic functions support force feedback and vibration on input devices.
These functions are declared in the main Allegro header file:

~~~~c
 #include <allegro5/allegro.h>
~~~~

Currently force feedback is fully supported on Linux and on Windows for 
DirectInput compatible devices. There is also minimal support for
Android. It is not yet supported on OSX, iOS, or on Windows for XInput 
compatible devices.

## API: ALLEGRO_HAPTIC

This is an abstract data type representing a haptic device that supports
force feedback or vibration.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

See also: [al_get_haptic_from_joystick]

## API: ALLEGRO_HAPTIC_CONSTANTS

This enum contains flags that are used to define haptic effects and
capabilities.  If the flag is set in the return value of
[al_get_haptic_capabilities], it means the device supports the given effect.
The value of these flags should be set into a [ALLEGRO_HAPTIC_EFFECT] struct
to determine what kind of haptic effect should be played.

* ALLEGRO_HAPTIC_RUMBLE    - simple vibration effects
* ALLEGRO_HAPTIC_PERIODIC  - periodic, wave-form effects
* ALLEGRO_HAPTIC_CONSTANT  - constant effects
* ALLEGRO_HAPTIC_SPRING    - spring effects
* ALLEGRO_HAPTIC_FRICTION  - friction effects
* ALLEGRO_HAPTIC_DAMPER    - damper effects
* ALLEGRO_HAPTIC_INERTIA   - inertia effects
* ALLEGRO_HAPTIC_RAMP      - ramp effects
* ALLEGRO_HAPTIC_SQUARE    - square wave periodic effect
* ALLEGRO_HAPTIC_TRIANGLE  - triangle wave periodic effect
* ALLEGRO_HAPTIC_SINE      - sine wave periodic effect
* ALLEGRO_HAPTIC_SAW_UP    - upwards saw wave periodic effect
* ALLEGRO_HAPTIC_SAW_DOWN  - downwards saw wave periodic effect
* ALLEGRO_HAPTIC_CUSTOM    - custom wave periodic effect
* ALLEGRO_HAPTIC_GAIN      - the haptic device supports gain setting
* ALLEGRO_HAPTIC_ANGLE     - the haptic device supports angle coordinates
* ALLEGRO_HAPTIC_RADIUS    - the haptic device supports radius coordinates
* ALLEGRO_HAPTIC_AZIMUTH   - the haptic device supports azimuth coordinates
* ALLEGRO_HAPTIC_AUTOCENTER

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

See also: [al_get_haptic_capabilities], [ALLEGRO_HAPTIC_EFFECT]

## API: ALLEGRO_HAPTIC_EFFECT

This struct models a particular haptic or vibration effect. It needs to be
filled in correctly and uploaded to a haptic device before the device can
play it back.

*Fields:*

type
:   The type of the haptic effect. May be one of the ALLEGRO_HAPTIC_CONSTANTS
    constants between or equal to ALLEGRO_HAPTIC_RUMBLE and
    ALLEGRO_HAPTIC_RAMP.

    * If `type` is set to ALLEGRO_HAPTIC_RUMBLE, then the effect is a simple
      "rumble" or vibration effect that shakes the device. In some cases,
      such as on a mobile platform, the whole device may shake.

    * If `type` is set to ALLEGRO_HAPTIC_PERIODIC, the effect is a shake or
      vibration of which the intensity is a periodic wave form.

    * If `type` is set to ALLEGRO_HAPTIC_CONSTANT, the effect is a constant
      pressure, motion or push-back in a certain direction of the axes of
      the device.

    * If `type` is set to ALLEGRO_HAPTIC_SPRING, the effect is a springy kind
      of resistance against motion of the axes of the haptic device.

    * If `type` is set to ALLEGRO_HAPTIC_FRICTION, the effect is a friction
      kind of resistance against motion of the axes of the haptic device.

    * If `type` is set to ALLEGRO_HAPTIC_DAMPER, the effect is a damper kind
      of resistance against motion of the axes of the haptic device.

    * If `type` is set to ALLEGRO_HAPTIC_INERTIA, the effect causes inertia
      or slowness of motions on the axes of the haptic device.

    * If `type` is set to ALLEGRO_HAPTIC_RAMP, the effect causes a pressure
      or push-back that ramps up or down depending on the position of the
      axis.

direction
:   The direction of location in 3D space where the effect should
    be played. Allegro haptic devices model directions in 3D space using
    spherical coordinates. However, the haptic device may not support
    localized effects, or may not support all coordinate components.

    In Allegro's coordinate system, the value in `direction.angle` determines
    the planar angle between the effect and the direction of the user who
    holds the device, expressed in radians. This angle increases clockwise
    away from the user. So, an effect with an angle 0.0 takes place in the 
    direction of the user of the haptic device, an angle of π/2 is
    to the left of the user, an angle of π means the direction away from 
    the user, and an angle of 3π/2 means to the right of the user.

    If [al_get_haptic_capabilities] has the flag ALLEGRO_HAPTIC_ANGLE set,
    then setting `direction.angle` is supported. Otherwise, it is
    unsupported, and you should set it to 0.

    The value in `direction.radius` is a relative value between 0.0 and 1.0
    that determines the relative distance from the center of the haptic
    device at which the effect will play back. A value of 0 means that the
    effect should play back at the center of the device. A value of 1.0 means
    that the effect should play back away from the center as far as is
    possible.

    If [al_get_haptic_capabilities] has the flag ALLEGRO_HAPTIC_RADIUS set,
    then setting `direction.radius` is supported. Otherwise, it is
    unsupported, and you should set it to 0.

    The value in `direction.azimuth` determines the elevation angle between
    the effect and the plane in which the user is holding the device,
    expressed in radians. An effect with an azimuth 0.0 plays back in the
    plane in which the user is holding the device, an azimuth +π/2 means 
    the effect plays back vertically above the user plane, and an azimuth 
    -π/2 means the effect plays back vertically below the user plane.

    If [al_get_haptic_capabilities] has the flag ALLEGRO_HAPTIC_AZIMUTH set,
    then setting `direction.azimuth` is supported. Otherwise, it is
    unsupported, and you should set it to 0.

replay
:   Determines how the effect should be played back. `replay.length` is the
    duration in seconds of the effect, and `replay.delay` is the time in
    seconds that the effect playback should be delayed when playback is
    started with [al_play_haptic_effect].

data
:   Determines in detail the parameters of the haptic effect to play back.

    If `type` is set to ALLEGRO_HAPTIC_RUMBLE, then
    `data.rumble.strong_magnitude` must be set to a relative magnitude
    between 0.0 and 1.0 to determine how intensely the "large" rumble motor
    of the haptic device will vibrate, and `data.rumble.weak_magnitude` must
    be set to relative magnitude between 0.0 and 1.0  to determine how
    intensely the "weak" ruble motor of the haptic device will vibrate.
    Not all devices have a "weak" motor, in which case the value set in
    `data.rumble.weak_magnitude` will be ignored.

    If `type` is set to ALLEGRO_HAPTIC_PERIODIC, then
    data.periodic.waveform must be set to one of ALLEGRO_HAPTIC_SQUARE,
    ALLEGRO_HAPTIC_TRIANGLE, ALLEGRO_HAPTIC_SINE, ALLEGRO_HAPTIC_SAW_UP,
    ALLEGRO_HAPTIC_SAW_DOWN, ALLEGRO_HAPTIC_CUSTOM. This will then determine
    the wave form of the vibration effect that will be played on the haptic
    device.

    In these cases, `data.periodic.period` must be set to the period in
    seconds of the wave form. The field `data.periodic.magnitude` must be set
    to the relative magnitude of intensity between -1.0 and 1.0 at which the
    wave form of the vibration will be played back. The field
    `data.periodic.offset` must be filled in with the offset from origin in
    seconds of the wave form of vibration, and the field
    `data.periodic.phase` is the phase of the wave form of vibration in
    seconds.

    If `data.periodic.waveform` is set to ALLEGRO_HAPTIC_CUSTOM, then
    `data.periodic.custom_data` must point to an array of
    `data.periodic.custom_len` doubles, each with values between -1.0 and
    1.0.  This value array will determine the shape of the wave form of the
    haptic effect.  ALLEGRO_HAPTIC_CUSTOM is not supported on some platforms,
    so use [al_get_haptic_capabilities] to check if it's available. If it isn't,
    you may want to play back a non-custom wave effect as a substitute instead.

    If `type` is set to ALLEGRO_HAPTIC_CONSTANT, then `data.constant.level`
    must be set to a relative intensity value between 0.0 and 1.0 to
    determine the intensity of the effect.

    If `type` is set to any of ALLEGRO_HAPTIC_SPRING,
    ALLEGRO_HAPTIC_FRICTION, ALLEGRO_HAPTIC_DAMPER, ALLEGRO_HAPTIC_INERTIA,
    ALLEGRO_HAPTIC_RAMP, then the `data.condition` struct should be filled in.
    To explain this better, it's best to keep in mind that these kinds of
    effects are most useful for steering-wheel kind of devices, where
    resistance or inertia should be applied when turning the device's wheel a
    certain distance to the left or right.

    The field `data.condition.right_saturation` must be filled in with a
    relative magnitude between -1.0 and 1.0 to determine the intensity of
    resistance or inertia on the "right" side of the axis. Likewise,
    `data.condition.left_saturation` must be filled in with a relative
    magnitude between -1.0 and 1.0 to determine the intensity of
    resistance or inertia on the "left" side of the axis.

    The field `data.condition.deadband` must be filled in with a relative
    value between 0.0 and 1.0 to determine the relative width of the "dead
    band" of the haptic effect. As long as the axis of the haptic device
    remains in the "dead band" area, the effect will not be applied. A value
    of 0.0 means there is no dead band, and a value of 1.0 means it applied
    over the whole range of the axis in question.

    The field `data.condition.center` must be filled in with a relative value
    between -1.0 and 1.0 to determine the relative position of the "center"
    of the effect around which the dead band is centered.  It should be set to
    0.0 in case the center should not be shifted.

    The field `data.condition.right_coef` and
    `data.condition.right_left_coef` must be filled in with a relative
    coefficient, that will detemine how quickly the effect ramps up on the
    right and left side. If set to 1.0, then the effect will be immediately
    at full intensity when outside of the dead band. If set to 0.0 the effect
    will not be felt at all.

    If `type` is set to ALLEGRO_HAPTIC_RAMP, then `data.ramp.start_level`
    should be set to a relative magnitude value between -1.0 and 1.0 to
    determine the initial intensity of the haptic effect. The field
    `data.ramp.end_level` should be set to a relative magnitude value between
    -1.0 and 1.0 to determine the final intensity of the haptic effect at the
    end of playback.

    If `type` is set to any of ALLEGRO_HAPTIC_PERIODIC,
    ALLEGRO_HAPTIC_CONSTANT, ALLEGRO_HAPTIC_RAMP, then `data.envelope`
    determines the "envelope" of the effect. That is, it determines the
    duration and intensity for the ramp-up attack or "fade in" and the
    ramp-down or "fade out" of the effect.

    In these cases the field `data.envelope.attack_level` must be set to a
    relative value between 0.0 and 1.0 that determines the intensity the
    effect should have when it starts playing (after `replay.delay` seconds
    have passed since the playback was started). The field
    `data.envelope.attack_length` must be set to the time in seconds that the
    effect should ramp up to the maximum intensity as set by the other
    parameters. If `data.envelope.attack_length` is 0, then the
    effect will play immediately at full intensity.

    The field `data.envelope.fade_level` must be set to a relative value
    between 0.0 and 1.0 that determines the intensity the effect should have
    when it stops playing after `replay.length + replay.delay` seconds have
    passed since the playback of the effect started. The field
    `data.envelope.fade_length` must be set to the time in seconds that the
    effect should fade out before it finishes playing. If
    `data.envelope.fade_length` is 0, then the effect will not fade out.

    If you don't want to use an envelope, then set all four fields of
    `data.envelope` to 0.0. The effect will then play back at full intensity
    throughout its playback.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: ALLEGRO_HAPTIC_EFFECT_ID

This struct is used as a handle to control playback of a haptic effect and should
be considered opaque. Its implementation is visible merely to allow allocation
by the users of the Allegro library.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_install_haptic

Installs the haptic (force feedback) device subsystem. This must be called
before using any other haptic-related functions. Returns true if the haptics
subsystem could be initialized correctly, false in case of error.

For portability you should first open a display before calling 
[al_install_haptic]. On some platforms, such as DirectInput under 
Windows, [al_install_haptic] will only work if at least one active 
display is available. This display must stay available until
[al_uninstall_haptic] is called.

If you need to close and reopen your active display for example, then you should
call [al_uninstall_haptic] before closing the display, and
[al_install_haptic] after opening it again.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_uninstall_haptic

Uninstalls the haptic device subsystem. This is useful since on some
platforms haptic effects are bound to the active display.

If you need to close and reopen your active display for example, then you should
call [al_uninstall_haptic] before closing the display, and
[al_install_haptic] after opening it again.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_haptic_installed

Returns true if the haptic device subsystem is installed, false if not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_mouse_haptic

Returns true if the mouse has haptic capabilities, false if not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_keyboard_haptic

Returns true if the keyboard has haptic capabilities, false if not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_display_haptic

Returns true if the display has haptic capabilities, false if not. This
mainly concerns force feedback that shakes a hand held device, such as
a phone or a tablet.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_joystick_haptic

Returns true if the joystick has haptic capabilities, false if not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_touch_input_haptic

Returns true if the touch input device has haptic capabilities, false if not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_from_mouse

If the mouse has haptic capabilities, returns the associated haptic device
handle.  Otherwise returns NULL.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_from_keyboard

If the keyboard has haptic capabilities, returns the associated haptic device
handle.  Otherwise returns NULL.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_from_display

If the display has haptic capabilities, returns the associated haptic device
handle.  Otherwise returns NULL.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_from_joystick

If the joystick has haptic capabilities, returns the associated haptic device
handle.  Otherwise returns NULL. It's neccesary to call this again every time
the joystick configuration changes, such as through hot plugging. In that case,
the old haptic device must be released using [al_release_haptic].

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_from_touch_input

If the touch input device has haptic capabilities, returns the associated
haptic device handle. Otherwise returns NULL.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_release_haptic

Releases the haptic device and its resources when it's not needed anymore.
Should also be used in case the joystick configuration changed, such as when
a joystick is hot plugged. This function also automatically releases all 
haptic effects that are still uploaded to the device and that have not been
released manually using [al_release_haptic_effect].

Returns true on success or false if the haptic device couldn't be released
for any reason, such as NULL being passed, the device not being active or
failure in the driver.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_haptic_active

Returns true if the haptic device can currently be used, false if not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_capabilities

Returns an integer with or'ed values from [ALLEGRO_HAPTIC_CONSTANTS], which,
if set, indicate that the haptic device supports the given feature.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_haptic_capable

Returns true if the haptic device supports the feature indicated by
the query parameter, false if the feature is not supported. 
The query parameter must be one of the values of [ALLEGRO_HAPTIC_CONSTANTS]. 

Since: 5.1.9

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

See also: [al_get_haptic_capabilities]

## API: al_set_haptic_gain

Sets the gain of the haptic device if supported. Gain is much like volume for
sound, it is as if every effect's intensity is multiplied by it. Gain is a
value between 0.0 and 1.0. Returns true if set sucessfully, false if not.
Only works if [al_get_haptic_capabilities] returns a value that has
[ALLEGRO_HAPTIC_GAIN][ALLEGRO_HAPTIC_CONSTANTS] set.  If not, this
function returns false, and all
effects will be played without any gain influence.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_gain

Returns the current gain of the device. Gain is much like volume for sound,
it is as if every effect's intensity is multiplied by it. Gain is a value
between 0.0 and 1.0. Only works correctly if [al_get_haptic_capabilities]
returns a value that has [ALLEGRO_HAPTIC_GAIN][ALLEGRO_HAPTIC_CONSTANTS]
 set. If this is not set, this
function will simply return 1.0 and all effects will be played without any
gain influence.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_set_haptic_autocenter

Turns on or off the automatic centering feature of the haptic device if 
supported. Depending on the device automatic centering may ensure that the 
axes of the device are centered again automatically after playing
a haptic effect. The intensity parameter should be passed with a value 
between 0.0 and 1.0. The value 0.0 means automatic centering is 
disabled, and 1.0 means full strength automatic centering. Any value
in between those two extremes will result in partial automatic 
centering. Some platforms do not support partial automatic 
centering. If that is the case, a value of less than 0.5 will turn 
it off, while a value equal to or higher to 0.5 will turn it on.
Returns true if set sucessfully, false if not.
Can only work if [al_get_haptic_capabilities] returns a value that has
[ALLEGRO_HAPTIC_AUTOCENTER][ALLEGRO_HAPTIC_CONSTANTS] set.  If not, this
function returns false.

Since: 5.1.9

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_autocenter

Returns the current automatic centering intensity of the device. 
Depending on the device automatic centering may ensure that the 
axes of the device are centered again automatically after playing
a haptic effect. The return value can be between 0.0 and 1.0. 
The value 0.0 means automatic centering is disabled, and 1.0 means 
automatic centering is enabled at full strength. Any value
in between those two extremes means partial automatic 
centering is enabled. Some platforms do not support partial automatic 
centering. If that is the case, a value of less than 0.5 means it is turned 
off, while a value equal to or higher to 0.5 means it is turned on.
Can only work if [al_get_haptic_capabilities] returns a 
value that has [ALLEGRO_HAPTIC_AUTOCENTER][ALLEGRO_HAPTIC_CONSTANTS]
set. If not, this function returns 0.0.

Since: 5.1.9

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_max_haptic_effects

Returns the maximum amount of haptic effects that can be uploaded to the
device.  This depends on the operating system, driver, platform and the 
device itself. This may return a value as low as 1.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_haptic_effect_ok

Returns true if the haptic device can play the haptic effect as given, false
if not.  The haptic effect must have been filled in completely and correctly.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_upload_haptic_effect

Uploads the haptic effect to the device.  The haptic effect must have been
filled in completely and correctly.  You must also pass in a pointer to a
user allocated [ALLEGRO_HAPTIC_EFFECT_ID].  This `id` can be used to control
playback of the effect.  Returns true if the effect was successfully uploaded,
false if not. 

The function [al_get_max_haptic_effects] returns how many effects can
be uploaded to the device at the same time.

The same haptic effect can be uploaded several times, as long as care is
taken to pass in a different [ALLEGRO_HAPTIC_EFFECT_ID].

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_play_haptic_effect

Plays back a previously uploaded haptic effect. The play_id must be a valid
[ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect],
[al_upload_and_play_haptic_effect] or [al_rumble_haptic].

The haptic effect will be played back loop times in sequence. If loop is less
than or equal to 1, then the effect will be played once only.

This function returns immediately and doesn't wait for the playback to
finish. It returns true if the playback was started sucessfully or false if
not.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_upload_and_play_haptic_effect

Uploads the haptic effect to the device and starts playback immediately. Returns
true if the upload and playback were successful, false if either failed. 

In case false is returned, the haptic effect will be automatically 
released as if [al_release_haptic_effect] had been called, so there 
is no need to call it again manually in this case. However, 
if true is returned, it is necessary to call [al_release_haptic_effect]
when the effect isn't needed anymore, to prevent the amount of available 
effects on the haptic devicefrom running out.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

See also: [al_upload_haptic_effect], [al_play_haptic_effect]

## API: al_stop_haptic_effect

Stops playing a previously uploaded haptic effect. The play_id must be a
valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect],
[al_upload_and_play_haptic_effect] or [al_rumble_haptic].

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_is_haptic_effect_playing

Returns true if the haptic effect is currently playing. Returns false if the
effect has been stopped or if it has already finished playing, or if it has not been
played yet. The play_id must be a valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained
from [al_upload_haptic_effect], [al_upload_and_play_haptic_effect] or
[al_rumble_haptic].

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_get_haptic_effect_duration

Returns the estimated duration in seconds of a single loop of the given haptic 
effect. The effect's `effect.replay` must have been filled in correctly 
before using this function.

Since: 5.1.9

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_release_haptic_effect

Releases a previously uploaded haptic effect from the device it has been
uploaded to, allowing for other effects to be uploaded. The play_id must be 
a valid [ALLEGRO_HAPTIC_EFFECT_ID] obtained from [al_upload_haptic_effect],
[al_upload_and_play_haptic_effect] or [al_rumble_haptic].

This function is called automatically when you call [al_release_haptic] 
on a [ALLEGRO_HAPTIC] for all effects that are still uploaded to the device.
Therefore this function is most useful if you want to upload and release
haptic effects dynamically, for example as a way to circumvent the limit 
imposed by [al_get_max_haptic_effects].

Returns true on success, false if the effect couldn't be released for any
reason such as when NULL is passed, the effect is not active or failure
to release the effect by the driver.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.

## API: al_rumble_haptic

Uploads a simple rumble effect to the haptic device and starts playback
immediately.  The parameter `intensity` is a relative magnitude between 0.0
and 1.0 that determines the intensity of the rumble effect. The `duration`
determines the duration of the effect in seconds.

You must also pass in a pointer to a user allocated
[ALLEGRO_HAPTIC_EFFECT_ID].  It it is stored a reference to be used to
control playback of the effect.  Returns true if the rumble effect was
successfully uploaded and started, false if not.

In case false is returned, the rumble effect will be automatically 
released as if [al_release_haptic_effect] had been called, so there 
is no need to call it again manually in this case. However, 
if true is returned, it is necessary to call [al_release_haptic_effect]
when the effect isn't needed anymore, to prevent the amount of available 
effects on the haptic device from running out.

Since: 5.1.8

> *[Unstable API]:* Perhaps could be simplified due to limited support for all the
exposed features across all of the platforms. Awaiting feedback from users.
