#al5base.AL_POINTER
Generic pointer.
#al5base.AL_INT8
Signed 8bit integer values.
#al5base.AL_UINT8
Unsigned 8bit integer values.
#al5base.AL_INT16
Signed 16bit integer values.
#al5base.AL_UINT16
Unsigned 16bit integer values.
#al5base.AL_INT32
Signed 32bit integer values.
#al5base.AL_UINT32
Unsigned 32bit integer values.
#al5base.AL_INT64
Signed 64bit integer values.
#al5base.AL_UINT64
Unsigned 64bit integer values.
#al5base.AL_BOOL
Boolean result.

#al5base.AL_CHAR
Signed 8bit integer.

Note that it isn't Pascal's CHAR type!
#al5base.AL_UCHAR
Unsigned 8bit integer values.
#al5base.AL_SHORT
Signed 16bit integer values.
#al5base.AL_USHORT
Unsigned 16bit integer values.
#al5base.AL_INT 
Signed 32bit integer values.
#al5base.AL_UINT
Unsigned 32bit integer values.
#al5base.AL_LONG
Signed 32/64bit integer values.
#al5base.AL_ULONG
Unsigned 32/64bit integer values.
#al5base.AL_SIZE_T
size_t equivalent.
#al5base.AL_INTPTR_T
Fake pointer type.  It's needed to use pointers as integer values in some low-level operations.
@seealso(AL_DATA_PTR_T)
#al5base.AL_UINTPTR_T
Fake pointer type.  It's needed to use pointers as integer values in some low-level operations.
@seealso(AL_DATA_PTR_T)
#al5base.AL_OFF_T
Another 64bit integer to store sizes.
#al5base.AL_FLOAT
Float value.
#al5base.AL_DOUBLE
Double value.
#al5base.AL_STR
Strings.  Used in parameters to convert Pascal's @code(STRING) to C's @code(char *).
@seealso(al5strings)

#al5base.AL_VOIDptr
Pointer.
#al5base.AL_STRptr
Pointer to text strings.  Used to convert Pascal's @code(STRING) to C @code(char *).
@seealso(al5strings)
#al5base.AL_INTptr
Pointer to integer.
#al5base.AL_FLOATptr
Pointer to float.

#al5base.AL_DATA_PTR_T
Special @italic(union) record used to store a integer and a pointer in the same variable.

This is a workaround because some Pascal compilers doesn't allow to cast a @code(POINTER) as @code(INTEGER) and vice-versa.  This is needed in some low-level operations.
@seealso(ALLEGRO_USER_EVENT)
@member int_value The data as an integer value with same size than @link(AL_POINTER);
@member uint_value The data as an unsigned integer value with same size than @link(AL_POINTER);
@member ptr_value The data as a generic pointer.



#allegro5.ALLEGRO_PAS_VERSION_STR
Allegro.pas version string.  Note this is @bold(not) the Allegro's version.
@seealso(al_get_allegro_version)
@seealso(ALLEGRO_VERSION_INT)
#allegro5.ALLEGRO_VERSION
Major version of Allegro.
@seealso(ALLEGRO_VERSION_INT)
@seealso(ALLEGRO_PAS_VERSION_STR)
#allegro5.ALLEGRO_SUB_VERSION
Minor version of Allegro.
@seealso(ALLEGRO_VERSION_INT)
@seealso(ALLEGRO_PAS_VERSION_STR)
#allegro5.ALLEGRO_WIP_VERSION
Revision number of Allegro.
@seealso(ALLEGRO_VERSION_INT)
@seealso(ALLEGRO_PAS_VERSION_STR)
#allegro5.ALLEGRO_DATE_STR
Release year for Allegro.pas.
@seealso(ALLEGRO_VERSION_INT)
@seealso(ALLEGRO_PAS_VERSION_STR)
#allegro5.ALLEGRO_DATE
Release date for Allegro.pas as integer with digits: yyyymmdd.
@seealso(ALLEGRO_VERSION_INT)
@seealso(ALLEGRO_PAS_VERSION_STR)
#allegro5.ALLEGRO_VERSION_INT
Packs Allegro's version number in a simple @link(AL_INT) number.

Note this is @bold(not) the actual Allegro version, you should use @link(al_get_allegro_version) to get this.  @code(ALLEGRO_VERSION_INT) just has a value that identifies all compatible Allegro DLL/so/dylib files.
@seealso(al_get_allegro_version)
@seealso(ALLEGRO_PAS_VERSION_STR)
@seealso(ALLEGRO_VERSION)
@seealso(ALLEGRO_SUB_VERSION)
@seealso(ALLEGRO_WIP_VERSION)

#allegro5.ALLEGRO_USER_MAIN
Description of user main function for @link(al_run_main).

#allegro5.al_get_allegro_version
Returns the compiled version of the Allegro library @(i.e. the dll/so/dylib
file@), packed into a single integer as groups of 8 bits.

You can use code like this to extract the version number:
@longcode(!
VAR
  Version: LONGINT;
  Major, Minor, Revision, Release: INTEGER;
  VersionStr: STRING;
BEGIN
  Version := al_get_allegro_version;
  Major    :=  Version SHR 24;
  Minor    := (Version SHR 16) AND 255;
  Revision := (Version SHR  8) AND 255;
  Release  :=  Version         AND 255;
  VersionStr := Format ('%d.%d.%d[%d]', [Major, Minor, Revision, Release])
END;
!)
The release number is 0 for an unofficial version and 1 or greater for an
official release. For example "5.0.2[1]" would be the (first) official 5.0.2
release while "5.0.2[0]" would be a compile of a version from the "5.0.2"
branch before the official release.

Remember this version number isn't for Allegro.pas but for Allegro.  In most cases will @bold(not) be the same than @link(ALLEGRO_VERSION_INT).
@seealso(ALLEGRO_VERSION_INT)
#allegro5.al_run_main
This function is useful in cases where you don't have a @code(main) function
but want to run Allegro (mostly useful in a wrapper library).  Under Windows
and Linux this is no problem because you simply can call
@link(al_install_system).  But some other system (like OSX) don't allow calling
@code(al_install_system) in the main thread.  @code(al_run_main) will know what
to do in that case.

The passed @code(argc) and @code(argv) will simply be passed on to
@code(user_main) and the return value of @code(user_main) will be returned.

@bold(Note)

This is used because the way the C language works.  I didn't test
if Pascal do need this kind of stuff.  Future versions of Allegro.pas would not
include this function, so don't use it unless your really need to (and tell me
if you really need it to remove this warning from documentation).

#allegro5.ALLEGRO_PI
Just to be sure that PI number is available.
#allegro5.ALLEGRO_TAU
The @italic(tau) number.

This is the full circle, which is more convenient in most cases.  For more information read @html(<a href="https://tauday.com/tau-manifesto">The Tau manifesto</a>).

#allegro5.AL_ID
This function can be used to create a packed 32 bit integer from 8 bit
characters, on both 32 and 64 bit machines.  These can be used for various
 things, like custom datafile objects or system IDs. Example:
@longcode(!
VAR
  OSTYPE_LINUX: LONGINT;
BEGIN
  OSTYPE_LINUX := AL_ID('TUX ');
END;
!)



#allegro5.ALLEGRO_TIMEOUT
Represents a timeout value.

The size of the structure is known so it can be statically allocated.  The
contents are private. @seealso(al_init_timeout)

#allegro5.al_get_time
Returns the number of seconds since the Allegro library was initialised.
The return value is undefined if Allegro is uninitialised. The resolution
depends on the used driver, but typically can be in the order of microseconds.
@seealso(al_rest)

#allegro5.al_rest
Waits for the specified number of seconds. This tells the system to pause the
current thread for the given amount of time. With some operating systems, the
accuracy can be in the order of 10ms. That is, even @code(al_rest @(0.000001@))
might pause for something like 10ms. Also see the other timer rutines (i.e.
@link(al_create_timer)) for easier ways to time your program without using up
all CPU.
@seealso(al_get_time) @seealso(al_init_timeout)

#allegro5.al_init_timeout
Sets timeout value of some number of seconds after the function call.

For compatibility with all platforms, seconds must be 2,147,483.647 seconds or
less.
@seealso(ALLEGRO_TIMEOUT) @seealso(al_wait_for_event_until)



#allegro5.ALLEGRO_COLOR
An @code(ALLEGRO_COLOR) structure describes a color in a device independent
way.  Use @link(al_map_rgb) et al. and @link(al_unmap_rgb) et al. to translate
from and to various color representations.

#allegro5.ALLEGRO_PIXEL_FORMAT
Pixel formats. Each pixel format specifies the exact size and bit layout of a
pixel in memory. Components are specified from high bits to low bits, so for
example a fully opaque red pixel in @code(ARGB_8888) format is @code($FFFF0000).

@bold(Note)

  The pixel format is independent of endianness. That is, in the above example
  you can always get the red component with @code(@(pixel AND $00ff0000@) SHR
  16). But you can not rely on this code:  @code(@(pixel + 2@)^) it will return
  the red component on little endian systems, but the green component on big
  endian systems.

Also note that Allegro's naming is different from OpenGL naming here, where a
format of @code(GL_RGBA8) merely defines the component order and the exact
layout including endianness treatment is specified separately. Usually
@code(GL_RGBA8) will correspond to @code(ALLEGRO_PIXEL_ABGR_8888) though on
little endian systems, so care must be taken (note the reversal of
RGBA <-> ABGR).

The only exception to this @code(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE) which will
always have the components as 4 bytes corresponding to red, green, blue and
alpha, in this order, independent of the endianness.

Some of the pixel formats represent compressed bitmap formats. Compressed bitmaps take up less space in the GPU memory than bitmaps with regular (uncompressed) pixel formats. This smaller footprint means that you can load more resources into GPU memory, and they will be drawn somewhat faster. The compression is lossy, however, so it is not appropriate for all graphical styles: it tends to work best for images with smooth color gradations. It is possible to compress bitmaps at runtime by passing the appropriate bitmap format in @link(al_set_new_bitmap_format) and then creating, loading, cloning or converting a non-compressed bitmap. This, however, is not recommended as the compression quality differs between different GPU drivers. It is recommended to compress these bitmaps ahead of time using external tools and then load them compressed.

Unlike regular pixel formats, compressed pixel formats are not laid out in memory one pixel row at a time. Instead, the bitmap is subdivided into rectangular blocks of pixels that are then laid out in block rows. This means that regular locking functions cannot use compressed pixel formats as the destination format. Instead, you can use the blocked versions of the bitmap locking functions which do support these formats.

It is not recommended to use compressed bitmaps as target bitmaps, as that operation cannot be hardware accelerated. Due to proprietary algorithms used, it is typically impossible to create compressed memory bitmaps.
@seealso(al_set_new_bitmap_format) @seealso(al_get_bitmap_format)
#allegro5.ALLEGRO_PIXEL_FORMAT_ANY
Let the driver choose a format. This is the default format at program start.
#allegro5.ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE
Like the version without _LE, but the component order is guaranteed to
be red, green, blue, alpha. This only makes a difference on big endian
systems, on little endian it is just an alias.
#allegro5.ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8
A single 8-bit channel. A pixel value maps onto the red channel when
displayed, but it is undefined how it maps onto green, blue and alpha
channels. When drawing to bitmaps of this format, only the red channel
is taken into account. Allegro may have to use fallback methods to
render to bitmaps of this format. This pixel format is mainly intended
for storing the color indices of an indexed (paletted) image, usually in
conjunction with a pixel shader that maps indices to RGBA values.
#allegro5.ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1
Compressed using the DXT1 compression algorithm. Each 4x4 pixel block
is encoded in 64 bytes, resulting in 6-8x compression ratio. Only a
single bit of alpha per pixel is supported.
#allegro5.ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3
Compressed using the DXT3 compression algorithm. Each 4x4 pixel block
is encoded in 128 bytes, resulting in 4x compression ratio. This format
supports sharp alpha transitions.
#allegro5.ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5
Compressed using the DXT5 compression algorithm. Each 4x4 pixel block
is encoded in 128 bytes, resulting in 4x compression ratio. This format
supports smooth alpha transitions.

#allegro5.al_map_rgb
Converts r, g, b (ranging from 0-255) into an @link(ALLEGRO_COLOR), using 255
for alpha.
 @seealso(al_map_rgba) @seealso(al_map_rgba_f) @seealso(al_map_rgb_f)
#allegro5.al_map_rgba
Convert r, g, b, a (ranging from 0-255) into an @link(ALLEGRO_COLOR).
@seealso(al_map_rgb) @seealso(al_map_rgba_f) @seealso(al_map_rgb_f)
#allegro5.al_map_rgb_f
Convert r, g, b (ranging from 0.0f-1.0f) into an @link(ALLEGRO_COLOR), using
1.0f for alpha.
@seealso(al_map_rgba) @seealso(al_map_rgba_f) @seealso(al_map_rgb)
#allegro5.al_map_rgba_f
Convert r, g, b, a (ranging from 0.0f-1.0f) into an @link(ALLEGRO_COLOR).
seealso(al_map_rgba) @seealso(al_map_rgba_f) @seealso(al_map_rgb)
#allegro5.al_premul_rgba
This is a shortcut for @code(al_map_rgba @(r * a / 255, g * a / 255, b * a / 255, a@)).

By default Allegro uses pre-multiplied alpha for transparent blending of
bitmaps and primitives (see @link(al_load_bitmap_flags) for a discussion of
that feature). This means that if you want to tint a bitmap or primitive to be
transparent you need to multiply the color components by the alpha components
when you pass them to this function. For example:
@longcode(!
VAR
  c: ALLEGRO_COLOR;
  bmp: ALLEGRO_BITMAPptr;
BEGIN
  c := al_premul_rgba (255, 0, 0, 127);
{ Draw the bitmap tinted red and half-transparent. }
  al_draw_tinted_bitmap (bmp, c, 0, 0, 0);
END;
!)
@seealso(al_map_rgba) @seealso(al_premul_rgba_f)
#allegro5.al_premul_rgba_f
This is a shortcut for @code(al_map_rgba @(r * a, g * a, b * a, a@)).

By default Allegro uses pre-multiplied alpha for transparent blending of
bitmaps and primitives (see @link(al_load_bitmap_flags) for a discussion of
that feature). This means that if you want to tint a bitmap or primitive to be
transparent you need to multiply the color components by the alpha components
when you pass them to this function. For example:
@longcode(!
VAR
  c: ALLEGRO_COLOR;
  bmp: ALLEGRO_BITMAPptr;
BEGIN
  c := al_premul_rgba_f (1, 0, 0, 0.5);
{ Draw the bitmap tinted red and half-transparent. }
  al_draw_tinted_bitmap (bmp, c, 0, 0, 0);
END;
!)
@seealso(al_map_rgba_f) @seealso(al_premul_rgba)

#allegro5.al_unmap_rgb
Retrieves components of an @link(ALLEGRO_COLOR), ignoring alpha.  Components
will range from 0-255.
@seealso(al_unmap_rgba) @seealso(al_unmap_rgb_f)
#allegro5.al_unmap_rgba
Retrieves components of an @link(ALLEGRO_COLOR).  Components will range from
0-255.
@seealso(al_unmap_rgb) @seealso(al_unmap_rgba_f)
#allegro5.al_unmap_rgb_f
Retrieves components of an @link(ALLEGRO_COLOR), ignoring alpha.  Components
will range from 0.0f-1.0f.
@seealso(al_unmap_rgb) @seealso(al_unmap_rgba_f)
#allegro5.al_unmap_rgba_f
Retrieves components of an @link(ALLEGRO_COLOR).  Components will range from
0.0f-1.0f.
@seealso(al_unmap_rgba) @seealso(al_unmap_rgb_f)

#allegro5.al_get_pixel_size
Returns the number of bytes that a pixel of the given format occupies.  For
blocked pixel formats (e.g. compressed formats), this returns 0.
@seealso(ALLEGRO_PIXEL_FORMAT) @seealso(al_get_pixel_format_bits)
#allegro5.al_get_pixel_format_bits
Returns the number of bits that a pixel of the given format occupies.  For
blocked pixel formats (e.g. compressed formats), this returns 0.
@seealso(ALLEGRO_PIXEL_FORMAT) @seealso(al_get_pixel_size)
#allegro5.al_get_pixel_block_size
Returns the number of bytes that a block of pixels with this format occupies.
@seealso(ALLEGRO_PIXEL_FORMAT)
@seealso(al_get_pixel_block_width) @seealso(al_get_pixel_block_height)
#allegro5.al_get_pixel_block_width
Returns the width of the pixel block of this format.
@seealso(ALLEGRO_PIXEL_FORMAT)
@seealso(al_get_pixel_block_size) @seealso(al_get_pixel_block_height)
#allegro5.al_get_pixel_block_height
Returns the height of the pixel block of this format.
@seealso(ALLEGRO_PIXEL_FORMAT)
@seealso(al_get_pixel_block_width) @seealso(al_get_pixel_block_size)



#allegro5.al_set_new_bitmap_format
Sets the pixel format for newly created bitmaps.  The default format is @code(ALLEGRO_PIXEL_FORMAT_ANY) and means the display driver will choose the best format.
@seealso(al_create_bitmap) @seealso(ALLEGRO_PIXEL_FORMAT) @seealso(al_get_new_bitmap_format)
#allegro5.al_set_new_bitmap_flags
Sets the flags to use for newly created bitmaps. Valid flags are:
@definitionlist(
  @itemlabel(ALLEGRO_MEMORY_BITMAP)
  @item(Creates a bitmap residing in system memory. Operations on, and with, memory bitmaps will not be hardware accelerated. However, direct pixel access can be relatively quick compared to video bitmaps, which depend on the display driver in use.

    @italic(Note:) Allegro's software rendering routines are currently somewhat unoptimised.

    @italic(Note:) Combining @code(ALLEGRO_VIDEO_BITMAP) with @code(ALLEGRO_MEMORY_BITMAP) flags is invalid.)
  @itemlabel(ALLEGRO_VIDEO_BITMAP)
  @item(Creates a bitmap that resides in the video card memory. These types of bitmaps receive the greatest benefit from hardware acceleration.

    @italic(Note:) Creating a video bitmap will fail if there is no current display or the current display driver cannot create the bitmap. The latter will happen if for example the format or dimensions are not supported.

    @italic(Note:) Bitmaps created with this flag will be converted to memory bitmaps when the last display is destroyed. In most cases it is therefore easier to use the @code(ALLEGRO_CONVERT_BITMAP) flag instead.

    @italic(Note:) Combining @code(ALLEGRO_VIDEO_BITMAP) with @code(ALLEGRO_MEMORY_BITMAP) flags is invalid.)
  @itemlabel(ALLEGRO_CONVERT_BITMAP)
  @item(This is the default. It will try to create a video bitmap and if that fails create a memory bitmap. Bitmaps created with this flag when there is no active display will be converted to video bitmaps next time a display is created. They also will remain video bitmaps if the last display is destroyed and then another is created again.

    @italic(Note:) You can combine this flag with @code(ALLEGRO_MEMORY_BITMAP) or @code(ALLEGRO_VIDEO_BITMAP) to force the initial type (and fail in the latter case if no video bitmap can be created) - but usually neither of those combinations is very useful.

    You can use the display option @code(ALLEGRO_AUTO_CONVERT_BITMAPS) to control which displays will try to auto-convert bitmaps.)
  @itemlabel(ALLEGRO_NO_PRESERVE_TEXTURE)
  @item(Normally, every effort is taken to preserve the contents of bitmaps, since some platforms may forget them. This can take extra processing time. If you know it doesn't matter if a bitmap keeps its pixel data, for example when it's a temporary buffer, use this flag to tell Allegro not to attempt to preserve its contents.)
  @itemlabel(ALLEGRO_ALPHA_TEST)
  @item(This is a driver hint only. It tells the graphics driver to do alpha testing instead of alpha blending on bitmaps created with this flag. Alpha testing is usually faster and preferred if your bitmaps have only one level of alpha (0). This flag is currently not widely implemented @(i.e., only for memory bitmaps@).)
  @itemlabel(ALLEGRO_MIN_LINEAR)
  @item(When drawing a scaled down version of the bitmap, use linear filtering. This usually looks better. You can also combine it with the @code(ALLEGRO_MIPMAP) flag for even better quality.)
  @itemlabel(ALLEGRO_MAG_LINEAR)
  @item(When drawing a magnified version of a bitmap, use linear filtering. This will cause the picture to get blurry instead of creating a big rectangle for each pixel. It depends on how you want things to look like whether you want to use this or not.)
  @itemlabel(ALLEGRO_MIPMAP)
  @item(This can only be used for bitmaps whose width and height is a power of two. In that case, it will generate mipmaps and use them when drawing scaled down versions. For example if the bitmap is 64x64, then extra bitmaps of sizes 32x32, 16x16, 8x8, 4x4, 2x2 and 1x1 will be created always containing a scaled down version of the original.)
)
@seealso(al_create_bitmap) @seealso(al_add_new_bitmap_flag) @seealso(al_get_new_bitmap_flags) @seealso(al_get_bitmap_flags)
#allegro5.al_get_new_bitmap_format
Returns the format used for newly created bitmaps.
@seealso(ALLEGRO_PIXEL_FORMAT) @seealso(al_set_new_bitmap_format)
#allegro5.al_get_new_bitmap_flags
Returns the format used for newly created bitmaps.
@seealso(ALLEGRO_PIXEL_FORMAT) @seealso(al_set_new_bitmap_flags)
#allegro5.al_add_new_bitmap_flag
A convenience function which does the same as @longcode(!
  al_set_new_bitmap_flags (al_get_new_bitmap_flags OR flag);
!)
@seealso(al_set_new_bitmap_flags) @seealso(al_get_new_bitmap_flags) @seealso(al_get_bitmap_flags)

#allegro5.al_get_bitmap_format
Returns the pixel format of a bitmap.
@seealso(ALLEGRO_PIXEL_FORMAT) @seealso(al_set_new_bitmap_format)
#allegro5.al_get_bitmap_flags
Returns the flags user to create the bitmap.
@seealso(al_set_new_bitmap_flags)

#allegro5.al_create_bitmap
Creates a new bitmap using the bitmap format and flags for the current
thread. Blitting between bitmaps of differing formats, or blitting between
memory bitmaps and display bitmaps may be slow.

Unless you set the @code(ALLEGRO_MEMORY_BITMAP) flag, the bitmap is created for the
current display.  Blitting to another display may be slow.

If a display bitmap is created, there may be limitations on the allowed
dimensions. For example a DirectX or OpenGL backend usually has a maximum
allowed texture size - so if bitmap creation fails for very large
dimensions, you may want to re-try with a smaller bitmap. Some platforms
also dictate a minimum texture size, which is relevant if you plan to use
this bitmap with the primitives addon. If you try to create a bitmap smaller
than this, this call will not fail but the returned bitmap will be a section
of a larger bitmap with the minimum size. The minimun size that will work on all platforms is 32 by 32.

Some platforms do not directly support display bitmaps whose dimensions are
not powers of two. Allegro handles this by creating a larger bitmap that has
dimensions that are powers of two and then returning a section of that
bitmap with the dimensions you requested. This can be relevant if you plan
to use this bitmap with the primitives addon but shouldn't be an issue
otherwise.

If you create a bitmap without @code(ALLEGRO_MEMORY_BITMAP) set but there is no current display, a temporary memory bitmap will be created instead. You can later convert all such bitmap to video bitmap and assign to a display by calling @link(al_convert_memory_bitmaps).

On some platforms the contents of video bitmaps may be lost when your application loses focus. Allegro has an internal mechanism to restore the contents of these video bitmaps, but it is not foolproof (sometimes bitmap contents can get lost permanently) and has performance implications. If you are using a bitmap as an intermediate buffer this mechanism may be wasteful. In this case, if you do not want Allegro to manage the bitmap contents for you, you can disable this mechanism by creating the bitmap with the @code(ALLEGRO_NO_PRESERVE_TEXTURE) flag. The bitmap contents are lost when you get the @code(ALLEGRO_EVENT_DISPLAY_LOST) and @code(ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) and a should be restored when you get the @code(ALLEGRO_EVENT_DISPLAY_FOUND) and when you call @link(al_acknowledge_drawing_resume) (after @code(ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) event). You can use those events to implement your own bitmap content restoration mechanism if Allegro's does not work well enough for you (for example, you can reload them all from disk).

@italic(Note:) The contents of a newly created bitmap are undefined - you need to clear the bitmap or make sure all pixels get overwritten before drawing it.

When you are done with using the bitmap you must call @link(al_destroy_bitmap) on it to free any resources allocated for it.
@seealso(al_set_new_bitmap_format) @seealso(al_set_new_bitmap_flags)
@seealso(al_clone_bitmap) @seealso(al_create_sub_bitmap) @seealso(al_convert_memory_bitmaps)
@seealso(al_destroy_bitmap)
#allegro5.al_destroy_bitmap
Destroys the given bitmap, freeing all resources used by it. This function does nothing if the @code(bitmap) argument is @nil.

As a convenience, if the calling thread is currently targeting the bitmap then the bitmap will be untargeted first.  The new target bitmap is unspecified.

Otherwise, it is an error to destroy a bitmap while it (or a sub-bitmap) is the target bitmap of any thread.
@seealso(al_create_bitmap)

#allegro5.al_put_pixel
Draws a single pixel on the target bitmap.  This operation is slow on
non-memory bitmaps. Consider locking the bitmap if you are going to use this
function multiple times on the same bitmap.  This function is not affected by
the transformations or the color blenders.
@seealso(ALLEGRO_COLOR) @seealso(al_get_pixel) @seealso(al_put_blended_pixel) @seealso(al_lock_bitmap)
#allegro5.al_put_blended_pixel
Like @link(al_put_pixel), but the pixel color is blended using the current blenders before being drawn.
#allegro5.al_get_pixel
Gets a pixel's color value from the specified bitmap.  This operation is slow
on non-memory bitmaps.  Consider locking the bitmap if you are going to use
this function multiple times on the same bitmap.
@seealso(ALLEGRO_COLOR) @seealso(al_put_pixel) @seealso(al_lock_bitmap)

#allegro5.al_convert_mask_to_alpha
Converts the given mask color to an alpha channel in the bitmap.  Can be used
to convert older 4.2-style bitmaps with magic pink to alpha-ready bitmaps.
@seealso(ALLEGRO_COLOR)

#allegro5.al_set_clipping_rectangle
Sets the region of the target bitmap or display that pixels get clipped to.
The default is to clip pixels to the entire bitmap.
@seealso(al_get_clipping_rectangle) @seealso(al_reset_clipping_rectangle)
#allegro5.al_reset_clipping_rectangle
Equivalent to calling @code(al_set_clipping_rectangle @(0, 0, w, h@)) where
@code(w) and @code(h) are the width and height of the target bitmap respectively.

Does nothing if there is no target bitmap.
@seealso(al_set_clipping_rectangle)
#allegro5.al_get_clipping_rectangle
Gets the clipping rectangle of the target bitmap.
@seealso(al_set_clipping_rectangle)

#allegro5.al_create_sub_bitmap
Creates a sub-bitmap of the parent, at the specified coordinates and of the
specified size. A sub-bitmap is a bitmap that shares drawing memory with a
pre-existing (parent) bitmap, but possibly with a different size and clipping
settings.

The sub-bitmap may originate off or extend past the parent bitmap.

See the discussion in @link(al_get_backbuffer) about using sub-bitmaps of the
backbuffer.

The parent bitmap's clipping rectangles are ignored.

If a sub-bitmap was not or cannot be created then @nil is returned.

When you are done with using the sub-bitmap you must call
@link(al_destroy_bitmap) on it to free any resources allocated for it.

Note that destroying parents of sub-bitmaps will not destroy the sub-bitmaps;
instead the sub-bitmaps become invalid and should no longer be used for
drawing - they still must be destroyed with @code(al_destroy_bitmap) however.  It
does not matter whether you destroy a sub-bitmap before or after its parent
otherwise.
@seealso(al_create_bitmap) @seealso(al_is_sub_bitmap) @seealso(al_get_parent_bitmap)
#allegro5.al_is_sub_bitmap
Returns true if the specified bitmap is a sub-bitmap, false otherwise.
@seealso(al_create_sub_bitmap) @seealso(al_get_parent_bitmap)
#allegro5.al_get_parent_bitmap
Returns the bitmap this bitmap is a sub-bitmap of. Returns @nil if this
bitmap is not a sub-bitmap. This function always returns the real bitmap,
and never a sub-bitmap. This might NOT match what was passed to
@code(al_create_sub_bitmap). Consider this code, for instance:
@longcode(!
VAR
  a, b, c: ALLEGRO_BITMAPptr;
BEGIN
  a := al_create_bitmap (512, 512);
  b := al_create_sub_bitmap (a, 128, 128, 256, 256);
  c := al_create_sub_bitmap (b, 64, 64, 128, 128);
  IF (al_get_parent_bitmap (b) = a) AND (al_get_parent_bitmap (c) = a) THEN
    WriteLn ('b & c are sub-bitmaps of a')
END;
!)
The message will be printed because only @code(a) is a real bitmap, and both @code(b) and @code(c)
are its sub-bitmaps.
@seealso(al_create_sub_bitmap) @seealso(al_is_sub_bitmap)
#allegro5.al_get_bitmap_x
For a sub-bitmap, returns it's x position within the parent.
@seealso(al_create_sub_bitmap) @seealso(al_get_parent_bitmap) @seealso(al_get_bitmap_y)
#allegro5.al_get_bitmap_y
For a sub-bitmap, returns it's y position within the parent.
@seealso(al_create_sub_bitmap) @seealso(al_get_parent_bitmap) @seealso(al_get_bitmap_x)
#allegro5.al_reparent_bitmap
For a sub-bitmap, changes the parent, position and size.  This is the same as
destroying the bitmap and re-creating it with @code(al_create_sub_bitmap) -
except the bitmap pointer stays the same.  This has many uses, for example an
animation player could return a single bitmap which can just be re-parented to
different animation frames without having to re-draw the contents.  Or a sprite
atlas could re-arrange its sprites without having to invalidate all existing
bitmaps. @seealso(al_create_sub_bitmap) @seealso(al_get_parent_bitmap)

#allegro5.al_clone_bitmap
Creates a new bitmap with @code(al_create_bitmap), and copyes the pixel data from
the old bitmap across.  The newly created bitmap will be created with the current new bitmap flags, and not the ones that were used to create the original bitmap.  If the new bitmap is a memory bitmap, its projection
bitmap is reset to be orthographic.
@seealso(al_create_bitmap) @seealso(al_set_new_bitmap_format)
@seealso(al_set_new_bitmap_flags) @seealso(al_convert_bitmap)
#allegro5.al_convert_bitmap
Converts the bitmap to the current bitmap flags and format.  The bitmap will
be as if it was created new with @code(al_create_bitmap) but retain its
contents.  All of this bitmap's sub-bitmaps are also converted.  If the new
bitmap type is memory, then the bitmap's projection bitmap is reset to be
orthographic.

If this bitmap is a sub-bitmap, then it, its parent and all the sibling
sub-bitmaps are also converted.
@seealso(al_create_bitmap) @seealso(al_set_new_bitmap_format)
@seealso(al_set_new_bitmap_flags) @seealso(al_clone_bitmap)
#allegro5.al_convert_memory_bitmaps
If you create a bitmap when there is no current display (for example because
you have not called @link(al_create_display) in the current thread) and are
using the @code(ALLEGRO_CONVERT_BITMAP) bitmap flag (which is set by default)
then the bitmap will be created successfully, but as a memory bitmap.  This
function converts all such bitmaps to proper video bitmaps belonging to the
current display.

Note that video bitmaps get automatically converted back to memory bitmaps
when the last display is destroyed.

This operation will preserve all bitmap flags except
@code(ALLEGRO_VIDEO_BITMAP) and @code(ALLEGRO_MEMORY_BITMAP).
@seealso(al_convert_bitmap) @seealso(al_create_bitmap)



#allegro5.al_draw_bitmap
Draws an unscaled, unrotated bitmap at the given position to the current
target bitmap.  @code(flags) can be a combination of:
@unorderedlist(
  @item(@code(ALLEGRO_FLIP_HORIZONTAL) - flip the bitmap about the y-axis)
  @item(@code(ALLEGRO_FLIP_VERTICAL) - flip the bitmap about the x-axis)
)
@bold(Note)

The current target bitmap must be a different bitmap. Drawing a
bitmap to itself (or to a sub-bitmap of itself) or drawing a sub-bitmap to
its parent (or another sub-bitmap of its parent) are not currently
supported. To copy part of a bitmap into the same bitmap simply use a
temporary bitmap instead.

@bold(Note)

The backbuffer (or a sub-bitmap thereof) can not be
transformed, blended or tinted. If you need to draw the backbuffer draw it
to a temporary bitmap first with no active transformation (except
translation). Blending and tinting settings/parameters will be ignored. This
does not apply when drawing into a memory bitmap.
@param(bitmap Origin bitmap.)
@param(dx Destination x.)
@param(dy Destination y.)
@param(flags Read description above.)
@seealso(al_set_target_bitmap) @seealso(al_draw_bitmap_region)
@seealso(al_draw_scaled_bitmap) @seealso(al_draw_rotated_bitmap)
@seealso(al_draw_scaled_rotated_bitmap)
#allegro5.al_draw_bitmap_region
Draws a region of the given bitmap to the target bitmap.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be drawn where.
@param(bitmap Origin bitmap.)
@param(sx source x)
@param(sy source y)
@param(sw source width @(width of region to blit@))
@param(sh source height @(height of region to blit@))
@param(dx destination x)
@param(dy destination y)
@param(flags same as for @code(al_draw_bitmap))
@seealso(al_draw_bitmap) @seealso(al_draw_scaled_bitmap)
@seealso(al_draw_rotated_bitmap) @seealso(al_draw_scaled_rotated_bitmap)
#allegro5.al_draw_scaled_bitmap
Draws a scaled version of the given bitmap to the target bitmap.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be drawn where.
@param(bitmap Origin bitmap.)
@param(sx source x)
@param(sy source y)
@param(sw source width)
@param(sh source height)
@param(dx destination x)
@param(dy destination y)
@param(dw destination width)
@param(dh destination height)
@param(flags same as for al_draw_bitmap)
@seealso(al_draw_bitmap) @seealso(al_draw_bitmap_region)
@seealso(al_draw_rotated_bitmap) @seealso(al_draw_scaled_rotated_bitmap)
#allegro5.al_draw_rotated_bitmap
Draws a rotated version of the given bitmap to the target bitmap.

The point at @code(cx/cy) relative to the upper left corner of the bitmap will be drawn at @code(dx/dy) and the bitmap is rotated around this point. If @code(cx,cy) is @code(0,0) the bitmap will rotate around its upper left corner.

Example:
@longcode(!
VAR
  w, h: SINGLE;
BEGIN
  w := al_get_bitmap_width (bitmap);
  h := al_get_bitmap_height (bitmap);
  al_draw_rotated_bitmap (bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0)
END;
!)
The above code draws the bitmap centered on @code(x/y) and rotates it 90° clockwise.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be drawn where.
@param(bitmap Origin bitmap.)
@param(cx center x @(relative to the left of bitmap@))
@param(cy center y @(relative to the top or bitmap@))
@param(dx destination x)
@param(dy destination y)
@param(angle angle in radians by which to rotate clockwise)
@param(flags same as for al_draw_bitmap)
@seealso(al_draw_bitmap) @seealso(al_draw_bitmap_region)
@seealso(al_draw_scaled_bitmap) @seealso(al_draw_scaled_rotated_bitmap)
#allegro5.al_draw_scaled_rotated_bitmap
Like @link(al_draw_rotated_bitmap), but can also scale the bitmap.

The point at @code(cx/cy) in the bitmap will be drawn at @code(dx/dy) and the bitmap is
rotated and scaled around this point.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be drawn where.
@param(bitmap Origin bitmap.)
@param(cx center x @(relative to the left of bitmap@))
@param(cy center y @(relative to the top or bitmap@))
@param(dx destination x)
@param(dy destination y)
@param(xscale how much to scale on the x-axis @(e.g. 2 for twice the size@))
@param(yscale how much to scale on the y-axis)
@param(angle angle in radians by which to rotate clockwise)
@param(flags same as for al_draw_bitmap)
@seealso(al_draw_bitmap) @seealso(al_draw_bitmap_region)
@seealso(al_draw_scaled_bitmap)

#allegro5.al_draw_tinted_bitmap
Like @link(al_draw_bitmap) but multiplies all colors in the bitmap with the
given color. For example:
@longcode(!
al_draw_tinted_bitmap (bitmap, al_map_rgba_f (0.5, 0.5, 0.5, 0.5), x, y, 0);
!)
The above will draw the bitmap 50% transparently (r/g/b values need to be
pre-multiplied with the alpha component with the default blend mode).
@longcode(!
al_draw_tinted_bitmap(bitmap, al_map_rgba_f(1, 0, 0, 1), x, y, 0);
!)
The above will only draw the red component of the bitmap.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be
drawn where.
@seealso(al_draw_bitmap) @seealso(al_draw_tinted_bitmap_region) @seealso(al_draw_tinted_scaled_bitmap) @seealso(al_draw_tinted_rotated_bitmap) @seealso(al_draw_tinted_scaled_rotated_bitmap) @seealso(al_draw_tinted_scaled_rotated_bitmap_region)
#allegro5.al_draw_tinted_bitmap_region
Like @link(al_draw_bitmap_region) but multiplies all colors in the bitmap with the given color.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be
@seealso(al_draw_tinted_bitmap)
#allegro5.al_draw_tinted_scaled_bitmap
Like @link(al_draw_scaled_bitmap) but multiplies all colors in the bitmap with the given color.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be
@seealso(al_draw_tinted_bitmap)
#allegro5.al_draw_tinted_rotated_bitmap
Like @link(al_draw_rotated_bitmap) but multiplies all colors in the bitmap with the given color.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be
@seealso(al_draw_tinted_bitmap)
#allegro5.al_draw_tinted_scaled_rotated_bitmap
Like @link(al_draw_scaled_rotated_bitmap) but multiplies all colors in the bitmap with the given color.

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be
drawn where.
@seealso(al_draw_tinted_bitmap)
#allegro5.al_draw_tinted_scaled_rotated_bitmap_region
Like @link(al_draw_tinted_scaled_rotated_bitmap) but you specify an area within the bitmap to be drawn.

You can get the same effect with a sub bitmap:
@longcode(!
  al_draw_tinted_scaled_rotated_bitmap_region (
    bitmap, sx, sy, sw, sh, tint,
    cx, cy, dx, dy, xscale, yscale, angle, flags
  );

{ Next code draws the same: }
  sub_bitmap := al_create_sub_bitmap (bitmap, sx, sy, sw, sh);
  al_draw_tinted_scaled_rotated_bitmap (
    sub_bitmap, tint, cx, cy,
    dx, dy, xscale, yscale, angle, flags
  );
!)

See @link(al_draw_bitmap) for a note on restrictions on which bitmaps can be drawn where.
@seealso(al_draw_tinted_bitmap)



#allegro5.ALLEGRO_FILEptr
An opaque object representing an open file. This could be a real file on disk or a virtual file.

#allegro5.ALLEGRO_FILE_INTERFACE
A structure containing function pointers to handle a type of "file", real
or virtual. See the full discussion in @link(al_set_new_file_interface).

The @code(fi_open) function must allocate memory for whatever userdata
structure it needs.  The pointer to that memory must be returned; it will
then be associated with the file. The other functions can access that data
by calling @link(al_get_file_userdata) on the file handle. If
@code(fi_open) returns @nil then @link(al_fopen) will also return @nil.

The @code(fi_fclose) function must clean up and free the userdata, but
Allegro will free the @code(ALLEGRO_FILEptr) handle.

If @code(fi_fungetc) is @nil, then Allegro's default implementation of a
16 char long buffer will be used.
@seealso(al_set_new_file_interface) @seealso(al_fopen_interface)
@seealso(al_get_file_userdata)
#allegro5.al_fopen
Creates and opens a file (real or virtual) given the path and mode. The
current file interface is used to open the file.

Depending on the stream type and the mode string, files may be opened in
"text" mode. The handling of newlines is particularly important. For
example, using the default stdio-based streams on DOS and Windows
platforms, where the native end-of-line terminators are @code(CR+LF)
sequences, a call to @link(al_fgetc) may return just one character ('\n')
where there were two bytes (@code(CR+LF)) in the file. When writing out
'\n', two bytes would be written instead. (As an aside, '\n' is not
defined to be equal to @code(LF) either.)

Newline translations can be useful for text files but is disastrous for
binary files. To avoid this behaviour you need to open file streams in
binary mode by using a mode argument containing a "b", e.g. @code('rb'), @code('wb).
@param(path Path to the file to open.)
@param(mode Access mode to open the file in @('r', 'w', etc.@).)
@return(a file handle on success, or @nil on error.)
@seealso(al_fclose) @seealso(al_set_new_file_interface) @seealso(al_fopen_interface)
@seealso(al_fread) @seealso(al_fwrite)
#allegro5.al_fopen_interface
Opens a file using the specified interface, instead of the interface set
with @link(al_set_new_file_interface). @seealso(al_fopen)
#allegro5.al_create_file_handle
Creates an empty, opened file handle with some abstract user data. This
allows custom interfaces to extend the @link(ALLEGRO_FILEptr) struct with
their own data. You should close the handle with the standard
@link(al_fclose) function when you are finished with it.
@seealso(al_fopen) @seealso(al_fclose) @seealso(al_set_new_file_interface)
#allegro5.al_fclose
Closes the given file, writing any buffered output data (if any).
@return(@true on success, @false on failure.) @seealso(al_fopen)
#allegro5.al_fread
Reads @code(size) bytes into the buffer pointed to by @code(ptr), from the given file.
@return(The number of bytes actually read. If an error occurs, or the end-of-file is reached, the return value is a short byte count (or zero).

@code(al_fread) does not distinguish between @link(AL_EOF) and other errors. Use @link(al_feof) and @link(al_ferror) to determine which occurred.)
@seealso(AL_EOF) @seealso(al_fgetc) @seealso(al_fwrite) @seealso(al_fread16be) @seealso(al_fread16le) @seealso(al_fread32be) @seealso(al_fread32le)
#allegro5.al_fwrite
Write @code(size) bytes from the buffer pointed to by @code(ptr) into the given file.
@return(The number of bytes actually written. If an error occurs, the return value is a short byte count @(or zero@).)
@seealso(al_fputc) @seealso(al_fputs) @seealso(al_fread) @seealso(al_fwrite16be) @seealso(al_fwrite16le) @seealso(al_fwrite32be) @seealso(al_fwrite32le)
#allegro5.al_fflush
Flushes any pending writes to the given file.
@return(@true on success, @false otherwise.) @seealso(al_get_errno)
#allegro5.al_ftell
Returns the current position in the given file, or @code(-1) on error.

On some platforms this function may not support large files.
@seealso(al_fseek) @seealso(al_get_errno)
#allegro5.al_fseek
Sets the current position of the given file to a position relative to that
specified by @code(whence), plus @code(offset) number of bytes.

@code(whence) can be:@unorderedlist(
  @item(@code(ALLEGRO_SEEK_SET) - seek relative to beginning of file)
  @item(@code(ALLEGRO_SEEK_CUR) - seek relative to current file position)
  @item(@code(ALLEGRO_SEEK_END) - seek relative to end of file)
)
After a successful seek, the end-of-file indicator is cleared and all
pushback bytes are forgotten.

On some platforms this function may not support large files.
@return(@true on success, @false on failure.)
@seealso(al_ftell) @seealso(al_get_errno)
#allegro5.al_feof
Returns @true if the end-of-file indicator has been set on the file, i.e.
we have attempted to read @italic(past) the end of the file.

This does @italic(not) return @true if we simply are at the end of the file. The
following code correctly reads two bytes, even when the file contains
exactly two bytes:
@longcode(!
  b1 := al_fgetc (f);
  b2 := al_fgetc (f);
  IF al_feof (f) THEN
  { At least one byte was unsuccessfully read. }
    ReportError ();
!)
@seealso(AL_EOF) @seealso(al_ferror) @seealso(al_fclearerr)
#allegro5.al_ferror
Returns non-zero if the error indicator is set on the given file, i.e.
there was some sort of previous error. The error code may be system or
file interface specific.
@seealso(al_feof) @seealso(al_fclearerr) @seealso(al_ferrmsg)
#allegro5.al_ferrmsg
Returns a message string with details about the last error that occurred
on the given file handle. The returned string is empty if there was no
error, or if the file interface does not provide more information.
@seealso(al_fclearerr) @seealso(al_ferror)
#allegro5.al_fclearerr
Clears the error indicator for the given file.

The standard I/O backend also clears the end-of-file indicator, and other
backends should try to do this. However, they may not if it would require
too much effort (e.g. PhysicsFS backend), so your code should not rely on
it if you need your code to be portable to other backends.
@seealso(al_ferror) @seealso(al_feof)
#allegro5.al_fungetc
Ungets a single byte from a file. Pushed-back bytes are not written to the
file, only made available for subsequent reads, in reverse order.

The number of pushbacks depends on the backend. The standard I/O backend
only guarantees a single pushback; this depends on the libc implementation.

For backends that follow the standard behavior, the pushback buffer will
be cleared after any seeking or writing; also calls to @link(al_fseek) and
@link(al_ftell) are relative to the number of pushbacks. If a pushback
causes the position to become negative, the behavior of @code(al_fseek)
and @code(al_ftell) are undefined.
@seealso(al_fgetc) @seealso(al_get_errno)
#allegro5.al_fsize
Returns the size of the file, if it can be determined, or @code(-1) otherwise.

#allegro5.al_fgetc
Reads and returns next byte in the given file. Returns a negative number on end of file or if an error occurred.
@seealso(al_fputc) @seealso(al_fungetc)
#allegro5.al_fputc
Writes a single byte to the given file. The byte written is the value of @code(c) cast to an unsigned char.
@param(c byte value to write.) @param(f file to write to.)
@return(the written byte @(cast back to an @link(AL_INT)@) on success, or negative number on error.)
#allegro5.al_fread16le
Reads a 16-bit word in little-endian format (LSB first).

@return(On success, the 16-bit word. On failure, returns EOF @(-1@). Since
  -1 is also a valid return value, use @link(al_feof) to check if the end
  of the file was reached prematurely, or @link(al_ferror) to check if an
  error occurred.)
@seealso(al_fread16be)
#allegro5.al_fread16be
Reads a 16-bit word in big-endian format (MSB first).
@return(On success, the 16-bit word. On failure, returns EOF @(-1@). Since
  -1 is also a valid return value, use @link(al_feof) to check if the end
  of the file was reached prematurely, or @link(al_ferror) to check if an
  error occurred.)
@seealso(al_fread16le)
#allegro5.al_fwrite16le
Writes a 16-bit word in little-endian format (LSB first).
@return(The number of bytes written: 2 on success, less than 2 on an error.)
@seealso(al_fwrite16be)
#allegro5.al_fwrite16be
Writes a 16-bit word in big-endian format (MSB first).
@return(The number of bytes written: 2 on success, less than 2 on an error.)
@seealso(al_fwrite16le)
#allegro5.al_fread32le
Reads a 32-bit word in little-endian format (LSB first).
@return(On success, the 32-bit word. On failure, returns EOF @(-1@). Since
  -1 is also a valid return value, use @link(al_feof) to check if the end
  of the file was reached prematurely, or @link(al_ferror) to check if an
  error occurred.)
@seealso(al_fread32be)
#allegro5.al_fread32be
Reads a 32-bit word in big-endian format (MSB first).
@return(On success, the 32-bit word. On failure, returns EOF @(-1@). Since
  -1 is also a valid return value, use @link(al_feof) to check if the end
  of the file was reached prematurely, or @link(al_ferror) to check if an
  error occurred.)
@seealso(al_fread32le)
#allegro5.al_fwrite32le
Writes a 32-bit word in little-endian format (LSB first).
@return(The number of bytes written: 2 on success, less than 2 on an error.)
@seealso(al_fwrite32be)
#allegro5.al_fwrite32be
Writes a 32-bit word in big-endian format (MSB first).
@return(The number of bytes written: 2 on success, less than 2 on an error.)
@seealso(al_fwrite32le)
#allegro5.al_fgets
Reads a string of bytes terminated with a newline or end-of-file into the
buffer given. The line terminator(s), if any, are included in the returned
string. A maximum of @code(max-1) bytes are read, with one byte being
reserved for a @code(NUL) terminator.

See @link(al_fopen) about translations of end-of-line characters.
@param(f File to read from.)
@param(buf Buffer to fill.)
@param(max Maximum size of buffer.)
@return(The pointer to @code(buf) on success. Returns @nil if an error
 occurred or if the end of file was reached without reading any bytes.)
@seealso(al_fget_ustr)
#allegro5.al_fget_ustr
Read a string of bytes terminated with a newline or end-of-file. The line
terminator(s), if any, are included in the returned string.

See @link(al_fopen) about translations of end-of-line characters.
@return(On success a pointer to a new @link(ALLEGRO_USTR) structure. This
 must be freed eventually with @link(al_ustr_free). Returns @nil if an
 error occurred or if the end of file was reached without reading any
 bytes.)
@seealso(al_fgetc) @seealso(al_fgets)
#allegro5.al_fputs
Writes a string to file. Apart from the return value, this is equivalent
to @code(@link(al_fwrite) @(f, p, Length @(p@)@);)

@bold(Note)

depending on the stream type and the mode passed to
@link(al_fopen), newline characters in the string may or may not be
automatically translated to native end-of-line sequences, e.g. @code(CR/LF)
instead of @code(LF).
@param(f File handle to write to.)
@param(p String to write.)
@returns(A non-negative integer on success, EOF (-1) on error.)
@seealso(al_fwrite)
#allegro5.al_fopen_slice
Opens a slice (subset) of an already open random access file as if it were
a stand alone file. While the slice is open, the parent file handle must
not be used in any way.

The slice is opened at the current location of the parent file, up through
@code(initial_size) bytes. The @code(initial_size) may be any non-negative
integer that will not exceed the bounds of the parent file.

Seeking with @code(ALLEGRO_SEEK_SET) will be relative to this starting location.
@code(ALLEGRO_SEEK_END) will be relative to the starting location plus the size
of the slice.

The mode can be any combination of:@unorderedlist(
@item(r: read access)  @item(w: write access) @item(e: expandable)
)

For example, a mode of @code('rw') indicates the file can be read and
written. (Note that this is slightly different from the stdio modes.) Keep
in mind that the parent file must support random access and be open in
normal write mode (not append) for the slice to work in a well defined way.

If the slice is marked as expandable, then reads and writes can happen
after the initial end point, and the slice will grow accordingly.
Otherwise, all activity is restricted to the initial size of the slice.

A slice must be closed with @link(al_fclose). The parent file will then be
positioned immediately after the end of the slice.
@seealso(al_fopen)
#allegro5.al_get_new_file_interface
Returns a pointer to the @link(ALLEGRO_FILE_INTERFACE) table in effect
for the calling thread.
@seealso(al_store_state) @seealso(al_restore_state) @seealso(al_set_new_file_interface)
#allegro5.al_set_new_file_interface
Sets the @link(ALLEGRO_FILE_INTERFACE) table for the calling thread.
This will change the handler for later calls to @link(al_fopen).
@seealso(al_set_standard_file_interface) @seealso(al_store_state)
@seealso(al_restore_state)
#allegro5.al_set_standard_file_interface
Sets the @link(ALLEGRO_FILE_INTERFACE) table to the default, for the
calling thread. This will change the handler for later calls to
@link(al_fopen).
@seealso(al_set_new_file_interface)

#allegro5.al_get_file_userdata
Returns a pointer to the custom userdata that is attached to the file
handle. This is intended to be used by functions that extend
@link(ALLEGRO_FILE_INTERFACE).



#allegro5.al_register_bitmap_loader
Registers a handler for @link(al_load_bitmap).
@param(ext File extension.  It should include the leading dot @('.'@) character. It will be
matched case-insensitively.)
@param(loader The given function used to handle the loading of bitmaps files with the given extension.  It may be @nil to unregister an entry.)
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_bitmap_saver) @seealso(al_register_bitmap_loader_f)
#allegro5.al_register_bitmap_saver
Registers a handler for @link(al_save_bitmap).
@param(ext File extension.  It should include the leading dot @('.'@) character. It will be
matched case-insensitively.)
@param(saver The given function used to handle the savint of bitmaps files with the given extension.  It may be @nil to unregister an entry.)
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_bitmap_loader) @seealso(al_register_bitmap_saver_f)
#allegro5.al_register_bitmap_loader_f
Registers a handler for @link(al_load_bitmap_f).
@param(ext File extension.  It should include the leading dot @('.'@) character. It will be
matched case-insensitively.)
@param(fs_loader The given function used to handle the loading of bitmaps files with the given extension.  It may be @nil to unregister an entry.)
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_bitmap_loader)
#allegro5.al_register_bitmap_saver_f
Registers a handler for @link(al_save_bitmap_f).
@param(ext File extension.  It should include the leading dot @('.'@) character. It will be
matched case-insensitively.)
@param(fs_saver The given function used to handle the savint of bitmaps files with the given extension.  It may be @nil to unregister an entry.)
@return(@true on success, @false on error. Returns @false if unregistering
	   an entry that doesn't exist.)
@seealso(al_register_bitmap_saver)
#allegro5.al_register_bitmap_identifier
Registers an identify handler for @link(al_identify_bitmap). The given
function will be used to detect files for the given extension. It will be
called with a single argument of type @link(ALLEGRO_FILEptr) which is a file
handle opened for reading and located at the first byte of the file. The
handler should try to read as few bytes as possible to safely determine if
the given file contents correspond to the type with the extension and return
@true in that case, @false otherwise. The file handle must not be closed but
there is no need to reset it to the beginning.
@param(ext The extension. It should include the leading dot @('.'@) character. It will be
matched case-insensitively.)
@param(identifier The identifier handler.  It may be @nil to unregister an entry.)
@return(@true on success, @false on error. Returns @false if unregistering
	   an entry that doesn't exist.)
@seealso(al_identify_bitmap)
#allegro5.al_load_bitmap
Loads an image file into a new @code(ALLEGRO_BITMAPptr). The file type is
determined by the extension, except if the file has no extension in which
case @code(al_identify_bitmap) is used instead.

This is the same as calling @code(al_load_bitmap_flags) with a flags
parameter of 0.

@bold(Note)

the core Allegro library does not support any image file
formats by default. You must use the @link(al5image) addon, or register your
own format handler.
@return(A pointer to the loaded bitmap or @nil on error.)
@seealso(al_load_bitmap_f) @seealso(al_register_bitmap_loader)
@seealso(al_load_bitmap_flags) @seealso(al_set_new_bitmap_format)
@seealso(al_set_new_bitmap_flags) @seealso(al_init_image_addon)
#allegro5.al_load_bitmap_flags
Loads an image file into a new @code(ALLEGRO_BITMAPptr). The file type is
determined by the extension, except if the file has no extension in which
case @link(al_identify_bitmap) is used instead.

@code(Note:) the core Allegro library does not support any image file
formats by default. You must use the @link(al5image) addon, or register your
own format handler.
@param(filename The file to load.)
@param(flags It may be a combination of the following constants:
@unorderedlist(
   @item(@bold(@code(ALLEGRO_NO_PREMULTIPLIED_ALPHA))
    By default, Allegro pre-multiplies the alpha channel of an image with the
    images color data when it loads it. Typically that would look something like
    this:
@longcode(!
  r := get_float_byte;
  g := get_float_byte;
  b := get_float_byte;
  a := get_float_byte;

  r := r * a;
  g := g * a;
  b := b * a;

  set_image_pixel (x, y, r, g, b, a);
!)
    The reason for this can be seen in the Allegro example @code(ex_premulalpha),
    ie, using pre-multiplied alpha gives more accurate color results in some
    cases. To use alpha blending with images loaded with pre-multiplied alpha,
    you would use the default blending mode, which is set with
    @code(al_set_blender @(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA@)).

    The @code(ALLEGRO_NO_PREMULTIPLIED_ALPHA) flag being set will ensure that
    images are not loaded with alpha pre-multiplied, but are loaded with color
    values direct from the image. That looks like this:
@longcode(!
  r := get_float_byte;
  g := get_float_byte;
  b := get_float_byte;
  a := get_float_byte;

  set_image_pixel (x, y, r, g, b, a);
!)
    To draw such an image using regular alpha blending, you would use
    @code(al_set_blender @(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA@))
    to set the correct blender. This has some caveats. First, as mentioned
    above, drawing such an image can result in less accurate color blending
    (when drawing an image with linear filtering on, the edges will be darker
    than they should be). Second, the behaviour is somewhat confusing, which is
    explained in the example below.
@longcode(!
{ Load and create bitmaps with an alpha channel. }
  al_set_new_bitmap_format (ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA);
{ Load some bitmap with alpha in it. }
  bmp := al_load_bitmap ('some_alpha_bitmap.png');
{ We will draw to this buffer and then draw this buffer to the screen. }
  tmp_buffer := al_create_bitmap (SCREEN_W, SCREEN_H);
{ Set the buffer as the target and clear it. }
  al_set_target_bitmap (tmp_buffer);
  al_clear_to_color (al_map_rgba_f (0, 0, 0, 1));
{ Draw the bitmap to the temporary buffer. }
  al_draw_bitmap (bmp, 0, 0, 0);
{ Finally, draw the buffer to the screen.
  The output will look incorrect (may take close inspection
  depending on the bitmap -- it may also be very obvious). }
  al_set_target_bitmap (al_get_backbuffer (display));
  al_draw_bitmap (tmp_buffer, 0, 0, 0);
!)
    To explain further, if you have a pixel with 0.5 alpha, and you're using
    @code(@(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA@)) for blending,
    the formula is:
@preformatted(
  a := da * dst + sa * src
)
    Expands to:
@longcode(!
  result_a := dst_a * (1-0.5) + 0.5 * 0.5
!)
    So if you draw the image to the temporary buffer, it is blended once
    resulting in 0.75 alpha, then drawn again to the screen, blended in the
    same way, resulting in a pixel has 0.1875 as an alpha value.)
  @item(@bold(@code(ALLEGRO_KEEP_INDEX))

    Load the palette indices of 8-bit .bmp and .pcx files instead of the rgb
    colors.)
  @item(@bold(@code(ALLEGRO_KEEP_BITMAP_FORMAT))

    Force the resulting ALLEGRO_BITMAP to use the same format as the file.

    @italic(This is not yet honoured.))
))
@return(A pointer to the loaded bitmap or @nil on error.)
@seealso(al_load_bitmap)
#allegro5.al_load_bitmap_f
Loads an image from an @link(ALLEGRO_FILEptr) stream into a new
@link(ALLEGRO_BITMAPptr). The file type is determined by the passed
@code(ident) parameter, which is a file name extension including the leading
dot. If (and only if) @code(ident) is an empty string, the file type is determined with
@link(al_identify_bitmap_f) instead.

This is the same as calling @link(al_load_bitmap_flags_f) with @code(0) for
the @code(flags) parameter.

@bold(Note)

the core Allegro library does not support any image file
formats by default. You must use the @link(al5image) addon, or register
your own format handler.
@return(A pointer to the loaded bitmap or @nil on error. The file remains open afterwards.)
@seealso(al_load_bitmap_flags_f) @seealso(al_load_bitmap)
@seealso(al_register_bitmap_loader_f) @seealso(al_init_image_addon)
#allegro5.al_load_bitmap_flags_f
Loads an image from an @link(ALLEGRO_FILEptr) stream into a new
@link(ALLEGRO_BITMAPptr). The file type is determined by the passed
@code(ident) parameter, which is a file name extension including the leading
dot. If (and only if) @code(ident) is an empty string, the file type is determined with
@link(al_identify_bitmap_f) instead.

The @code(flags) parameter is the same as for @link(al_load_bitmap_flags).

@bold(Note)

the core Allegro library does not support any image file
formats by default. You must use the @link(al5image) addon, or register
your own format handler.
@return(A pointer to the loaded bitmap or @nil on error. The file remains open afterwards.)
@seealso(al_load_bitmap_f) @seealso(al_load_bitmap_flags)
#allegro5.al_save_bitmap
Saves an @code(ALLEGRO_BITMAP) to an image file. The file type is determined by
the extension.

@bold(Note)

the core Allegro library does not support any image file
formats by default. You must use the @link(al5image) addon, or register your
own format handler.
@return(@true on success, @false on error.)
@seealso(al_save_bitmap_f) @seealso(al_register_bitmap_saver)
@seealso(al_init_image_addon)
#allegro5.al_save_bitmap_f
Saves an ALLEGRO_BITMAP to an ALLEGRO_FILE stream. The file type is
determined by the passed @code(ident) parameter, which is a file name
extension including the leading dot.

@bold(Note)

the core Allegro library does not support any image file
formats by default. You must use the @link(al5image) addon, or register your
own format handler.
@return(@true on success, @false on error.  The file remains open afterwards.)
@seealso(al_save_bitmap) @seealso(al_register_bitmap_saver_f)
@seealso(al_init_image_addon)
#allegro5.al_identify_bitmap_f
Tries to guess the bitmap file type of the given file by reading the first
few bytes. The extension, if any, of the passed filename is not taken into
account - only the file contents. By default Allegro cannot recognize any
file types, but calling @link(al_init_image_addon) will add detection of
(some of) the types it can read.  You can also use @link(al_register_bitmap_identifier) to add identification of custom file types.
@returns(a pointer to a static string with a file extension for the type,
including the leading dot. For example ".png" or ".jpg". Returns @nil if the
bitmap type cannot be determined.)
@seealso(al_init_image_addon) @seealso(al_identify_bitmap)
@seealso(al_register_bitmap_identifier)
#allegro5.al_identify_bitmap
This works exactly as @link(al_identify_bitmap_f) but you specify the
filename of the file for which to detect the type and not a file handle. The
extension, if any, of the passed filename is not taken into account - only
the file contents.
@seealso(al_init_image_addon) @seealso(al_identify_bitmap_f)
@seealso(al_register_bitmap_identifier)



#allegro5.ALLEGRO_LOCKED_REGION
Users who wish to manually edit or read from a bitmap are required to lock
it first.  The @code(ALLEGRO_LOCKED_REGION) structure represents the
locked region of the bitmap.  This call will work with any bitmap,
including memory bitmaps.
@seealso(al_lock_bitmap) @seealso(al_lock_bitmap_region)
@seealso(al_unlock_bitmap) @seealso(ALLEGRO_PIXEL_FORMAT)
@member data Points to the leftmost pixel of the first row (row 0) of the locked region.
@member format Indicates the pixel format of the data.
@member pitch Gives the size in bytes of a single row (also known as the stride).  The pitch may be greater than @code(width * pixel_size) due to padding; this is not uncommon.  It is also not uncommon for the pitch to be negative (the bitmap may be upside down).  For blocked bitmaps, 'row' refers to the row of blocks, not of pixels.
@member pixel_size It is the number of bytes used to represent a single block of pixels for the pixel format of this locked region. For most formats (and historically, this used to be true for all formats), this is just the size of a single pixel, but for blocked pixel formats this value is different.

#allegro5.al_lock_bitmap
Locks an entire bitmap for reading or writing. If the bitmap is a display
bitmap it will be updated from system memory after the bitmap is unlocked
(unless locked read only).

@bold(Note:)  For some reason, this function seems not to work properly on Windows, neither using Delphi nor Free Pascal.

On some platforms, Allegro automatically backs up the contents of video bitmaps because they may be occasionally lost (see discussion in @link(al_create_bitmap)'s documentation). If you're completely recreating the bitmap contents often (e.g. every frame) then you will get much better performance by creating the target bitmap with @code(ALLEGRO_NO_PRESERVE_TEXTURE) flag.

@bold(Note)

While a bitmap is locked, you can not use any drawing
operations on it (with the sole exception of @link(al_put_pixel) and
@link(al_put_blended_pixel)).
@param(flags @unorderedlist(
  @item(@code(ALLEGRO_LOCK_READONLY) The locked region will not be written
    to. This can be faster if the bitmap is a video texture, as it can be
    discarded after the lock instead of uploaded back to the card.)
  @item(@code(ALLEGRO_LOCK_WRITEONLY) The locked region will not be read
    from. This can be faster if the bitmap is a video texture, as no data
    need to be read from the video card. You are required to fill in all
    pixels before unlocking the bitmap again, so be careful when using this
    flag.)
  @item(@code(ALLEGRO_LOCK_READWRITE) The locked region can be written to
    and read from. Use this flag if a partial number of pixels need to be
    written to, even if reading is not needed.)
))
@param(format Indicates the pixel format that the returned buffer will be
  in. To lock in the same format as the bitmap stores its data internally,
  call with @code(al_get_bitmap_format @(bitmap@)) as the format or use
  @code(ALLEGRO_PIXEL_FORMAT_ANY). Locking in the native format will
  usually be faster. If the bitmap format is compressed, using
  @code(ALLEGRO_PIXEL_FORMAT_ANY) will choose an implementation defined
  non-compressed format.)
@Return(@nil if the bitmap cannot be locked, e.g. the bitmap was locked previously and not unlocked. It also returns @nil if the format is a compressed format.)
@seealso(ALLEGRO_LOCKED_REGION) @seealso(ALLEGRO_PIXEL_FORMAT)
@seealso(al_unlock_bitmap) @seealso(al_lock_bitmap_region)
@seealso(al_lock_bitmap_blocked) @seealso(al_lock_bitmap_region_blocked)
#allegro5.al_lock_bitmap_region
Like @link(al_lock_bitmap), but only locks a specific area of the bitmap. If
the bitmap is a video bitmap, only that area of the texture will be updated
when it is unlocked. Locking only the region you indend to modify will be
faster than locking the whole bitmap.

@bold(Note)

Using the @code(ALLEGRO_LOCK_WRITEONLY) with a blocked pixel
format (i.e. formats for which @link(al_get_pixel_block_width) or
@link(al_get_pixel_block_height) do not return 1) requires you to have the
region be aligned to the block width for optimal performance. If it is not,
then the function will have to lock the region with the
@code(ALLEGRO_LOCK_READWRITE) instead in order to pad this region with
valid data.
@seealso(ALLEGRO_LOCKED_REGION) @seealso(ALLEGRO_PIXEL_FORMAT)
@seealso(al_unlock_bitmap)
#allegro5.al_lock_bitmap_blocked
Like @link(al_lock_bitmap), but allows locking bitmaps with a blocked pixel
format (i.e. a format for which @link(al_get_pixel_block_width) or
@link(al_get_pixel_block_height) do not return 1) in that format. To that
end, this function also does not allow format conversion. For bitmap formats
with a block size of 1, this function is identical to calling
@code(al_lock_bitmap @(bmp, al_get_bitmap_format @(bmp@), flags@)).

@bold(Note)

Currently there are no drawing functions that work when the
bitmap is locked with a compressed format. @link(al_get_pixel) will also not
work.
@seealso(al_lock_bitmap) @seealso(al_lock_bitmap_region_blocked)
#allegro5.al_lock_bitmap_region_blocked
Like @link(al_lock_bitmap_blocked), but allows locking a sub-region, for
performance. Unlike @link(al_lock_bitmap_region) the region specified in
terms of blocks and not pixels.
@seealso(al_lock_bitmap_region) @seealso(al_lock_bitmap_blocked)
#allegro5.al_unlock_bitmap
Unlocks a previously locked bitmap or bitmap region. If the bitmap is a video
bitmap, the texture will be updated to match the system memory copy (unless
it was locked read only).
@seealso(al_lock_bitmap) @seealso(al_lock_bitmap_region)
@seealso(al_lock_bitmap_blocked) @seealso(al_lock_bitmap_region_blocked)
#allegro5.al_is_bitmap_locked
Returns whether or not a bitmap is already locked.
@seealso(al_lock_bitmap) @seealso(al_lock_bitmap_region)
@seealso(al_unlock_bitmap)



#allegro5.al_set_blender
Sets the function to use for blending for the current thread.

Blending means, the source and destination colors are combined in drawing
operations.

Assume the source color (e.g. color of a rectangle to draw, or pixel of a
bitmap to draw) is given as its red/green/blue/alpha components (if the
bitmap has no alpha it always is assumed to be fully opaque, so 255 for
8-bit or 1.0 for floating point): @italic(s = s.r, s.g, s.b, s.a). And this
color is drawn to a destination, which already has a color:
@italic(d = d.r, d.g, d.b, d.a).

The conceptional formula used by Allegro to draw any pixel then depends on
the @code(op) parameter:
@unorderedlist(
@item(@code(ALLEGRO_ADD)
@preformatted(
  r = d.r * df.r + s.r * sf.r
  g = d.g * df.g + s.g * sf.g
  b = d.b * df.b + s.b * sf.b
  a = d.a * df.a + s.a * sf.a
))
@item(@code(ALLEGRO_DEST_MINUS_SRC)
@preformatted(
  r = d.r * df.r - s.r * sf.r
  g = d.g * df.g - s.g * sf.g
  b = d.b * df.b - s.b * sf.b
  a = d.a * df.a - s.a * sf.a
))
@item(@code(ALLEGRO_SRC_MINUS_DEST)
@preformatted(
  r = s.r * sf.r - d.r * df.r
  g = s.g * sf.g - d.g * df.g
  b = s.b * sf.b - d.b * df.b
  a = s.a * sf.a - d.a * df.a
))
)
Valid values for the factors @italic(sf) and @italic(df) passed to this
function are as follows, where @italic(s) is the source color, @italic(d)
the destination color and @italic(cc) the color set with
@link(al_set_blend_color) (white by default)
@unorderedlist(
  @item(@bold(ALLEGRO_ZERO) @code(f = 0, 0, 0, 0))
  @item(@bold(ALLEGRO_ONE) @code(f = 1, 1, 1, 1))
  @item(@bold(ALLEGRO_ALPHA) @code(f = s.a, s.a, s.a, s.a))
  @item(@bold(ALLEGRO_INVERSE_ALPHA) @code(f = 1 - s.a, 1 - s.a, 1 - s.a, 1 - s.a))
  @item(@bold(ALLEGRO_SRC_COLOR) @code(f = s.r, s.g, s.b, s.a))
  @item(@bold(ALLEGRO_DEST_COLOR) @code(f = d.r, d.g, d.b, d.a))
  @item(@bold(ALLEGRO_INVERSE_SRC_COLOR) @code(f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a))
  @item(@bold(ALLEGRO_INVERSE_DEST_COLOR) @code(f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a))
  @item(@bold(ALLEGRO_CONST_COLOR) @code(f = cc.r, cc.g, cc.b, cc.a))
  @item(@bold(ALLEGRO_INVERSE_CONST_COLOR) @code(f = 1 - cc.r, 1 - cc.g, 1 - cc.b, 1 - cc.a))
)
So for example, to restore the default of using premultiplied alpha
blending, you would use:
@longcode(!
al_set_blender (ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
!)
As formula:
@preformatted(
  r = d.r * (1 - s.a) + s.r * 1
  g = d.g * (1 - s.a) + s.g * 1
  b = d.b * (1 - s.a) + s.b * 1
  a = d.a * (1 - s.a) + s.a * 1
)
If you are using non-pre-multiplied alpha, you could use
@longcode(!
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
!)
Additive blending would be achieved with
@longcode(!
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
!)
Copying the source to the destination (including alpha) unmodified
@longcode(!
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
!)
Multiplying source and destination components
@longcode(!
al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO)
!)
Tinting the source (like @link(al_draw_tinted_bitmap))
@longcode(!
al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_ONE);
al_set_blend_color(al_map_rgb(0, 96, 255)); { nice Chrysler blue }
!)
Averaging source and destination pixels
@longcode(!
al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR);
al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5));
!)
As formula:
@preformatted(
  r = d.r * 0 + s.r * d.r
  g = d.g * 0 + s.g * d.g
  b = d.b * 0 + s.b * d.b
  a = d.a * 0 + s.a * d.a
)
@seealso(al_set_separate_blender) @seealso(al_set_blend_color)
@seealso(al_get_blender)
#allegro5.al_set_blend_color
Sets the color to use for blending when using the @code(ALLEGRO_CONST_COLOR)
or @code(ALLEGRO_INVERSE_CONST_COLOR) blend functions. See
@link(al_set_blender) for more information.
@seealso(al_set_blender) @seealso(al_get_blend_color)
#allegro5.al_get_blender
Returns the active blender for the current thread.
@seealso(al_set_blender) @seealso(al_get_separate_blender)
#allegro5.al_get_blend_color
Returns the color currently used for constant color blending (white by
default).
@seealso(al_set_blend_color) @seealso(al_set_blender)
#allegro5.al_set_separate_blender
Like @code(al_set_blender), but allows specifying a separate blending
operation for the alpha channel. This is useful if your target bitmap also
has an alpha channel and the two alpha channels need to be combined in a
different way than the color components.
@seealso(al_set_blender) @seealso(al_get_blender)
@seealso(al_get_separate_blender)
#allegro5.al_get_separate_blender
Returns the active blender for the current thread.
@seealso(al_set_separate_blender) @seealso(al_get_blender)



#allegro5.ALLEGRO_EVENT_TYPE
An integer used to distinguish between different types of events.
@seealso(ALLEGRO_EVENT) @seealso(ALLEGRO_GET_EVENT_TYPE)
@seealso(ALLEGRO_EVENT_TYPE_IS_USER)

#allegro5.ALLEGRO_EVENT_JOYSTICK_AXIS
A joystick axis value changed.
@unorderedlist(
@item(@bold(@code(joystick.id)) Pointer to the joystick which generated the event. This is not the same as the event source @code(joystick.source).)
@item(@bold(@code(joystick.stick)) The stick number, counting from zero. Axes on a joystick are grouped into "sticks".)
@item(@bold(@code(joystick.axis)) The axis number on the stick, counting from zero.)
@item(@bold(@code(joystick.pos)) The axis position, from -1.0 to +1.0.)
)
#allegro5.ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN
A joystick button was pressed.
@unorderedlist(
@item(@bold(@code(joystick.id)) Pointer to the joystick which generated the event. This is not the same as the event source @code(joystick.source).)
@item(@bold(@code(joystick.button)) The button which was pressed, counting from zero.)
)
#allegro5.ALLEGRO_EVENT_JOYSTICK_BUTTON_UP
A joystick button was released.
@unorderedlist(
@item(@bold(@code(joystick.id)) Pointer to the joystick which generated the event. This is not the same as the event source @code(joystick.source).)
@item(@bold(@code(joystick.button)) The button which was released, counting from zero.)
)
#allegro5.ALLEGRO_EVENT_JOYSTICK_CONFIGURATION
A joystick was plugged in or unplugged. See @link(al_reconfigure_joysticks) for details.
#allegro5.ALLEGRO_EVENT_KEY_DOWN
A keyboard key was pressed.
@unorderedlist(
@item(@bold(@code(keyboard.keycode)) The code corresponding to the physical key which was pressed. See the Key codes section for the list of @code(ALLEGRO_KEY_*) constants.)
@item(@bold(@code(keyboard.display)) The display which had keyboard focus when the event occurred.)
)
@bold(Note)

this event is about the physical keys being pressed on the keyboard. Look for @link(ALLEGRO_EVENT_KEY_CHAR) events for character input.
#allegro5.ALLEGRO_EVENT_KEY_CHAR
A character was typed on the keyboard, or a character was auto-repeated.
@unorderedlist(
@item(@bold(@code(keyboard.keycode))
    The code corresponding to the physical key which was last pressed. See the Key codes section for the list of @code(ALLEGRO_KEY_*) constants.)
@item(@bold(@code(keyboard.unichar))
    A Unicode code point @(character@). This may be zero or negative if the event was generated for a non-visible "character", such as an arrow or Function key. In that case you can act upon the @code(keycode) field.

    Some special keys will set the unichar field to their standard ASCII values: Tab=9, Return=13, Escape=27. In addition if you press the Control key together with A to Z the unichar field will have the values 1 to 26. For example Ctrl-A will set unichar to 1 and Ctrl-H will set it to 8.

    As of Allegro 5.0.2 there are some inconsistencies in the treatment of Backspace (8 or 127) and Delete (127 or 0) keys on different platforms. These can be worked around by checking the keycode field.)
@item(@bold(@code(keyboard.modifiers))
    This is a bitfield of the modifier keys which were pressed when the event occurred. See @html(<a href="introduction.html#kbdmodifiers">"Keyboard modifier flags"</a>) for the constants.)
@item(@bold(@code(keyboard.frepeat))
    Indicates if this is a repeated character.)
@item(@bold(@code(keyboard.display))
    The display which had keyboard focus when the event occurred.)
)

@bold(Note)

in many input methods, characters are not entered one-for-one with physical key presses. Multiple key presses can combine to generate a single character, e.g. apostrophe + e may produce 'é'. Fewer key presses can also generate more characters, e.g. macro sequences expanding to common phrases.
#allegro5.ALLEGRO_EVENT_KEY_UP
A keyboard key was released.
@unorderedlist(
@item(@bold(@code(keyboard.keycode)) The code corresponding to the physical key which was released. See the Key codes section for the list of @code(ALLEGRO_KEY_*) constants.)
@item(@bold(@code(keyboard.display)) The display which had keyboard focus when the event occurred.)
)
@bold(Seealso:) @html(<a href="introduction.html#keycodes">Key codes</a>)

#allegro5.ALLEGRO_EVENT_MOUSE_AXES
One or more mouse axis values changed.
@unorderedlist(
@item(@bold(@code(mouse.x))
    x-coordinate.)
@item(@bold(@code(mouse.y))
    y-coordinate.)
@item(@bold(@code(mouse.z))
    z-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative.)
@item(@bold(@code(mouse.w))
    w-coordinate. This usually means the horizontal axis of a mouse wheel.)
@item(@bold(@code(mouse.dx))
    Change in the x-coordinate value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.)
@item(@bold(@code(mouse.dy))
    Change in the y-coordinate value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.)
@item(@bold(@code(mouse.dz))
    Change in the z-coordinate value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.)
@item(@bold(@code(mouse.dw))
    Change in the w-coordinate value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.)
@item(@bold(@code(mouse.pressure))
    Pressure, ranging from 0.0 to 1.0.)
@item(@bold(@code(mouse.display))
    The display which had mouse focus.)
)
@bold(Note)

Calling @link(al_set_mouse_xy) also will result in a change of axis values, but such a change is reported with @link(ALLEGRO_EVENT_MOUSE_WARPED) events instead which are identical except for their type.

@bold(Note)

currently mouse.display may be @nil if an event is generated in response to @link(al_set_mouse_axis).
#allegro5.ALLEGRO_EVENT_MOUSE_BUTTON_DOWN
A mouse button was pressed.
@unorderedlist(
@item(@bold(@code(mouse.x))
    x-coordinate.)
@item(@bold(@code(mouse.y))
    y-coordinate.)
@item(@bold(@code(mouse.z))
    z-coordinate.)
@item(@bold(@code(mouse.w))
    w-coordinate.)
@item(@bold(@code(mouse.button))
    The mouse button which was pressed, numbering from 1.)
@item(@bold(@code(mouse.pressure))
    Pressure, ranging from 0.0 to 1.0.)
@item(@bold(@code(mouse.display))
    The display which had mouse focus.)
)
#allegro5.ALLEGRO_EVENT_MOUSE_BUTTON_UP
A mouse button was released.
@unorderedlist(
@item(@bold(@code(mouse.x))
    x-coordinate.)
@item(@bold(@code(mouse.y))
    y-coordinate.)
@item(@bold(@code(mouse.z))
    z-coordinate.)
@item(@bold(@code(mouse.w))
    w-coordinate.)
@item(@bold(@code(mouse.button))
    The mouse button which was released, numbering from 1.)
@item(@bold(@code(mouse.pressure))
    Pressure, ranging from 0.0 to 1.0.)
@item(@bold(@code(mouse.display))
    The display which had mouse focus.)
)
#allegro5.ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY
The mouse cursor entered a window opened by the program.
@unorderedlist(
@item(@bold(@code(mouse.x))
    x-coordinate.)
@item(@bold(@code(mouse.y))
    y-coordinate.)
@item(@bold(@code(mouse.z))
    z-coordinate.)
@item(@bold(@code(mouse.w))
    w-coordinate.)
@item(@bold(@code(mouse.display))
    The display which had mouse focus.)
)
#allegro5.ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY
The mouse cursor left the boundaries of a window opened by the program.
@unorderedlist(
@item(@bold(@code(mouse.x))
    x-coordinate.)
@item(@bold(@code(mouse.y))
    y-coordinate.)
@item(@bold(@code(mouse.z))
    z-coordinate.)
@item(@bold(@code(mouse.w))
    w-coordinate.)
@item(@bold(@code(mouse.display))
    The display which had mouse focus.)
)
#allegro5.ALLEGRO_EVENT_MOUSE_WARPED
@link(al_set_mouse_xy) was called to move the mouse. This event is identical to @link(ALLEGRO_EVENT_MOUSE_AXES) otherwise.

#allegro5.ALLEGRO_EVENT_TIMER
A timer counter incremented.
@unorderedlist(
@item(@bold(@code(timer.source))
    The timer which generated the event.)
@item(@bold(@code(timer.count))
    The timer count value.)
)

#allegro5.ALLEGRO_EVENT_DISPLAY_EXPOSE
The display (or a portion thereof) has become visible.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which was exposed.)
@item(@bold(@code(display.x), @code(display.y))
    The top-left corner of the rectangle which was exposed.)
@item(@bold(@code(display.width), @code(display.height))
    The width and height of the rectangle which was exposed.)
)
@bold(Note)

The display needs to be created with @code(ALLEGRO_GENERATE_EXPOSE_EVENTS) flag for these events to be generated.
#allegro5.ALLEGRO_EVENT_DISPLAY_RESIZE
The window has been resized.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which was resized.)
@item(@bold(@code(display.x), @code(display.y))
    The position of the top-level corner of the display.)
@item(@bold(@code(display.width))
    The new width of the display.)
@item(@bold(@code(display.height))
    The new height of the display.)
)
You should normally respond to these events by calling @link(al_acknowledge_resize). Note that further resize events may be generated by the time you process the event, so these fields may hold outdated information.
#allegro5.ALLEGRO_EVENT_DISPLAY_CLOSE
The close button of the window has been pressed.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which was closed.)
)
#allegro5.ALLEGRO_EVENT_DISPLAY_LOST
When using Direct3D, displays can enter a "lost" state. In that state, drawing calls are ignored, and upon entering the state, bitmap's pixel data can become undefined. Allegro does its best to preserve the correct contents of bitmaps (see the @code(ALLEGRO_NO_PRESERVE_TEXTURE) flag at @link(al_set_new_bitmap_flags)) and restore them when the device is "found" (see @link(ALLEGRO_EVENT_DISPLAY_FOUND)). However, this is not 100% fool proof (see discussion in @link(al_create_bitmap)'s documentation).

@bold(Note)

This event merely means that the display was lost, that is, DirectX suddenly lost the contents of all video bitmaps. In particular, you can keep calling drawing functions -- they just most likely won't do anything. If Allegro's restoration of the bitmaps works well for you then no further action is required when you receive this event.
@definitionlist(
  @itemlabel(@bold(@code(display.source))) @item(The display which was lost.)
)
#allegro5.ALLEGRO_EVENT_DISPLAY_FOUND
Generated when a lost device is restored to operating state.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which was found.)
)
@seealso(ALLEGRO_EVENT_DISPLAY_LOST)
#allegro5.ALLEGRO_EVENT_DISPLAY_SWITCH_IN
The window is the active one again.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which was switched into.)
)
#allegro5.ALLEGRO_EVENT_DISPLAY_SWITCH_OUT
The window is no longer active, that is the user might have clicked into another window or "tabbed" away. In response to this event you might want to call @link(al_clear_keyboard_state) (possibly passing @code(display.source) as its argument) in order to prevent Allegro's keyboard state from getting out of sync.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which was switched out of.)
)
#allegro5.ALLEGRO_EVENT_DISPLAY_ORIENTATION
Generated when the rotation or orientation of a display changes.
@unorderedlist(
@item(@bold(@code(display.source))
    The display which generated the event.)
@item(@bold(@code(event.display.orientation))
    Contains one of the following values:@unorderedlist(
        @item(@code(ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES))
        @item(@code(ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES))
        @item(@code(ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES))
        @item(@code(ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES))
        @item(@code(ALLEGRO_DISPLAY_ORIENTATION_FACE_UP))
        @item(@code(ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN))
    ))
)
#allegro5.ALLEGRO_EVENT_DISPLAY_HALT_DRAWING
When a display receives this event it should stop doing any drawing and then call @link(al_acknowledge_drawing_halt) immediately.

This is currently only relevant for Android and iOS. It will be sent when the application is switched to background mode, in addition to @link(ALLEGRO_EVENT_DISPLAY_SWITCH_OUT). The latter may also be sent in situations where the application is not active but still should continue drawing, for example when a popup is displayed in front of it.

@bold(Note)

This event means that the next time you call a drawing function, your program will crash. So you must stop drawing and you must immediately reply with @code(al_acknowledge_drawing_halt). Allegro sends this event because it cannot handle this automatically. Your program might be doing the drawing in a different thread from the event handling, in which case the drawing thread needs to be signaled to stop drawing before acknowledging this event.

@bold(Note)

Mobile devices usually never quit an application, so to prevent the battery from draining while your application is halted it can be a good idea to call @link(al_stop_timer) on all your timers, otherwise they will keep generating events. If you are using audio, you can also stop all audio voices (or pass @nil to @link(al_set_default_voice) if you use the default mixer), otherwise Allegro will keep streaming silence to the voice even if the stream or mixer are stopped or detached.
@seealso(ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING)
#allegro5.ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING
When a display receives this event, it may resume drawing again, and it must call @link(al_acknowledge_drawing_resume) immediately.

This is currently only relevant for Android and iOS. The event will be sent when an application returns from background mode and is allowed to draw to the display again, in addition to @link(ALLEGRO_EVENT_DISPLAY_SWITCH_IN). The latter event may also be sent in a situation where the application is already active, for example when a popup in front of it closes.

@bold(Note)

Unlike @link(ALLEGRO_EVENT_DISPLAY_FOUND) it is not necessary to reload any bitmaps when you receive this event.
@seealso(ALLEGRO_EVENT_DISPLAY_HALT_DRAWING)

#allegro5.ALLEGRO_EVENT_TOUCH_BEGIN
The touch input device registered a new touch.
@unorderedlist(
@item(@bold(@code(touch.display))
    The display which was touched.)
@item(@bold(@code(touch.id))
    An identifier for this touch. If supported by the device it will stay the same for events from the same finger until the touch ends.)
@item(@bold(@code(touch.x))
    The x coordinate of the touch in pixels.)
@item(@bold(@code(touch.y))
    The y coordinate of the touch in pixels.)
@item(@bold(@code(touch.dx))
    Movement speed in pixels in x direction.)
@item(@bold(@code(touch.dy))
    Movement speed in pixels in y direction.)
@item(@bold(@code(touch.primary))
    Whether this is the only/first touch or an additional touch.)
)
#allegro5.ALLEGRO_EVENT_TOUCH_END
A touch ended.

Has the same fields as @link(ALLEGRO_EVENT_TOUCH_BEGIN).
#allegro5.ALLEGRO_EVENT_TOUCH_MOVE
The position of a touch changed.

Has the same fields as @link(ALLEGRO_EVENT_TOUCH_BEGIN).
#allegro5.ALLEGRO_EVENT_TOUCH_CANCEL
A touch was cancelled. This is device specific but could for example mean that a finger moved off the border of the device or moved so fast that it could not be tracked any longer.

Has the same fields as @link(ALLEGRO_EVENT_TOUCH_BEGIN).

#allegro5.ALLEGRO_EVENT_DISPLAY_CONNECTED
This event is sent when a physical display is connected to the device Allegro runs on. Currently, on most platforms, Allegro supports only a single physical display. However, on iOS, a secondary physical display is supported.
@unorderedlist(
@item(@bold(@code(display.display))
    The display which was touched.)
)
#allegro5.ALLEGRO_EVENT_DISPLAY_DISCONNECTED
This event is sent when a physical display is disconnected from the device Allegro runs on. Currently, on most platforms, Allegro supports only a single physical display. However, on iOS, a secondary physical display is supported.
@unorderedlist(
@item(@bold(@code(display.display))
    The display which was touched.)
)

#allegro5.ALLEGRO_EVENT_TYPE_IS_USER
Returns @true if the event type is not a builtin event type, i.e. one of
those described in @link(ALLEGRO_EVENT_TYPE).
@seealso(ALLEGRO_GET_EVENT_TYPE)
#allegro5.ALLEGRO_GET_EVENT_TYPE
Makes an event type identifier, which is a 32-bit integer. Usually, but not
necessarily, this will be made from four 8-bit character codes, for example:
@longcode(!
  MY_EVENT_TYPE := ALLEGRO_GET_EVENT_TYPE ('MINE');
!)
IDs less than 1024 are reserved for Allegro or its addons. Don't use
anything lower than @code(ALLEGRO_GET_EVENT_TYPE @(#0#0#4#0@)).

You should try to make your IDs unique so they don't clash with any 3rd
party code you may be using. Be creative. Numbering from 1024 is not
creative.

If you need multiple identifiers, you could define them like this:
@longcode(!
  BASE_EVENT := ALLEGRO_GET_EVENT_TYPE ('MINE');
  BARK_EVENT := BASE_EVENT + 1;
  MEOW_EVENT := BASE_EVENT + 2;
  SQUAWK_EVENT := BASE_EVENT + 3;
!)
@seealso(ALLEGRO_EVENT) @seealso(ALLEGRO_USER_EVENT)
@seealso(ALLEGRO_EVENT_TYPE_IS_USER)

#allegro5.ALLEGRO_DISPLAYptr
Pointer to a display.

An opaque type representing an open display or window.
#allegro5.ALLEGRO_JOYSTICKptr
A pointer to an abstract data representing a physical joystick.
@seealso(al_get_joystick)

#allegro5.ALLEGRO_EVENT_SOURCE
An event source is any object which can generate events.  For example, an
@link(ALLEGRO_DISPLAYptr) can generate events, and you can get the
@code(ALLEGRO_EVENT_SOURCE) pointer from an @code(ALLEGRO_DISPLAYptr) with
@link(al_get_display_event_source).

You may create your own "user" event sources that emit custom events.
@seealso(ALLEGRO_EVENT) @seealso(al_init_user_event_source)
@seealso(al_emit_user_event)

#allegro5.ALLEGRO_ANY_EVENT
Contains the common information about events.
@seealso(ALLEGRO_EVENT)
#allegro5.ALLEGRO_DISPLAY_EVENT
Contains display events information. @seealso(ALLEGRO_EVENT)
@member x The left side of the rectangle which was exposed or the position of the top-level corner of the display.
@member y The top side of the rectangle which was exposed or the position of the top-level corner of the display.
@member width The width of the rectangle which was exposed or the new size of the display.
@member height The height of the rectangle which was exposed or the new size of the display.
#allegro5.ALLEGRO_DISPLAY_EVENT.orientation
Contains one of the following values:@unorderedlist(
  @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES)))
  @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES)))
  @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES)))
  @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES)))
  @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_FACE_UP)))
  @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN)))
)

#allegro5.ALLEGRO_JOYSTICK_EVENT
Contains the joystick events information. @seealso(ALLEGRO_EVENT)
@member id The joystick which generated the event. This is not the same as the event source.
@member stick The stick number, counting from zero. Axes on a joystick are grouped into "sticks".

#allegro5.ALLEGRO_KEYBOARD_EVENT
Contains the keyboard events information. @seealso(ALLEGRO_EVENT)
@member keycode The code corresponding to the physical key which was pressed or released. See the @link(Keyboard) section for the list of @code(ALLEGRO_KEY_* ) constants.
@member modifiers This is a bitfield of the modifier keys which were pressed when the event occurred. See @link(Keyboard modifier flags) for the constants.
#allegro5.ALLEGRO_KEYBOARD_EVENT.unichar
A Unicode code point (character). This may be zero or negative if the
event was generated for a non-visible "character", such as an arrow or
Function key. In that case you can act upon the keycode field.

Some special keys will set the unichar field to their standard ASCII
values: Tab=9, Return=13, Escape=27. In addition if you press the
Control key together with A to Z the unichar field will have the values
1 to 26. For example Ctrl-A will set unichar to 1 and Ctrl-H will set it
to 8.

As of Allegro 5.0.2 there are some inconsistencies in the treatment of
Backspace (8 or 127) and Delete (127 or 0) keys on different platforms.
These can be worked around by checking the keycode field.

#allegro5.ALLEGRO_MOUSE_EVENT
Contains the mouse events information. @seealso(ALLEGRO_EVENT)
@member x x-coordinate.
@member y y-coordinate.
@member z z-coordinate. This usually means the vertical axis of a mouse wheel, where up is positive and down is negative.
@member w w-coordinate. This usually means the horizontal axis of a mouse wheel.
@member dx Change in the coordinates value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.
@member dy Change in the coordinates value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.
@member dz Change in the coordinates value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.
@member dw Change in the coordinates value since the previous @code(ALLEGRO_EVENT_MOUSE_AXES) event.

#allegro5.ALLEGRO_TOUCH_EVENT
Contains the touch input events information. @seealso(ALLEGRO_EVENT)
@member id An identifier for this touch. If supported by the device it will stay the same for events from the same finger until the touch ends.

#allegro5.ALLEGRO_USER_EVENT
An event structure that can be emitted by user event sources. These are the public fields:
@longcode(!
  source: ALLEGRO_EVENT_SOURCE;
  data1: AL_DATA_INTPTR_T;
  data2: AL_DATA_INTPTR_T;
  data3: AL_DATA_INTPTR_T;
  data4: AL_DATA_INTPTR_T;
!)
Like all other event types this structure is a part of the @link(ALLEGRO_EVENT) union. To access the fields in an @code(ALLEGRO_EVENT) variable @code(ev), you would use:
@preformatted(
  ev.user.source
  ev.user.data1
  ev.user.data2
  ev.user.data3
  ev.user.data4
)
To create a new user event you would do this:
@longcode(!
VAR
  MyEventSource: ALLEGRO_EVENT_SOURCE;
  MyEvent: ALLEGRO_EVENT;
  SomeVar: REAL;
BEGIN
  al_init_user_event_source (@MyEventSource);
  MyEvent.user.ftype := ALLEGRO_GET_EVENT_TYPE ('MINE');
  MyEvent.user.data1.int_value := 1;
  MyEvent.user.data2.ptr_value := @SomeVar;
  al_emit_user_event (MyEventSource, MyEvent, NIL)
END;
!)
Event type identifiers for user events are assigned by the user. Please see the documentation for @link(ALLEGRO_GET_EVENT_TYPE) for the rules you should follow when assigning identifiers.
@seealso(al_emit_user_event) @seealso(ALLEGRO_GET_EVENT_TYPE) @seealso(al_init_user_event_source)
#allegro5.ALLEGRO_EVENT
An @code(ALLEGRO_EVENT) is an union of all builtin event structures, i.e. it is an object large enough to hold the data of any event type. All events have the following fields in common:
@unorderedlist(
  @item(@code(@bold(ftype @(@link(ALLEGRO_EVENT_TYPE)@))) Indicates the type of event.)
  @item(@code(@bold(any.source @(ALLEGRO_EVENT_SOURCEptr@))) The event source
         which generated the event.)
  @item(@code(@bold(any.timestamp @(DOUBLE@))) When the event was generated.)
)
By examining the type field you can then access type-specific fields. The
@code(any.source) field tells you which event source generated that
particular event. The @code(any.timestamp) field tells you when the event
was generated. The time is referenced to the same starting point as
@link(al_get_time).

Each event is of one of the following types, with the usable fields given.
@unorderedlist(
  @item(@link(ALLEGRO_EVENT_JOYSTICK_AXIS))
  @item(@link(ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN))
  @item(@link(ALLEGRO_EVENT_JOYSTICK_BUTTON_UP))
  @item(@link(ALLEGRO_EVENT_JOYSTICK_CONFIGURATION))
  @item(@link(ALLEGRO_EVENT_KEY_DOWN))
  @item(@link(ALLEGRO_EVENT_KEY_UP))
  @item(@link(ALLEGRO_EVENT_KEY_CHAR))
  @item(@link(ALLEGRO_EVENT_MOUSE_AXES))
  @item(@link(ALLEGRO_EVENT_MOUSE_BUTTON_DOWN))
  @item(@link(ALLEGRO_EVENT_MOUSE_BUTTON_UP))
  @item(@link(ALLEGRO_EVENT_MOUSE_WARPED))
  @item(@link(ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY))
  @item(@link(ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY))
  @item(@link(ALLEGRO_EVENT_TOUCH_BEGIN))
  @item(@link(ALLEGRO_EVENT_TOUCH_END))
  @item(@link(ALLEGRO_EVENT_TOUCH_MOVE))
  @item(@link(ALLEGRO_EVENT_TOUCH_CANCEL))
  @item(@link(ALLEGRO_EVENT_TIMER))
  @item(@link(ALLEGRO_EVENT_DISPLAY_EXPOSE))
  @item(@link(ALLEGRO_EVENT_DISPLAY_RESIZE))
  @item(@link(ALLEGRO_EVENT_DISPLAY_CLOSE))
  @item(@link(ALLEGRO_EVENT_DISPLAY_LOST))
  @item(@link(ALLEGRO_EVENT_DISPLAY_FOUND))
  @item(@link(ALLEGRO_EVENT_DISPLAY_SWITCH_OUT))
  @item(@link(ALLEGRO_EVENT_DISPLAY_SWITCH_IN))
  @item(@link(ALLEGRO_EVENT_DISPLAY_ORIENTATION))
  @item(@link(ALLEGRO_EVENT_DISPLAY_HALT_DRAWING))
  @item(@link(ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING))
  @item(@link(ALLEGRO_EVENT_DISPLAY_DISCONNECTED))
)
@member any This is to allow the user to access the other fields which are common to all event types, without using some specific type structure.

#allegro5.al_init_user_event_source
Initialices an event source for emitting user events. The space for the event
source must already have been allocated.

One possible way of creating custom event sources is to derive other
structures with @code(ALLEGRO_EVENT_SOURCE) at the head, e.g.
@longcode(!
TYPE
  THINGptr = ^THING;
  THING = RECORD
    event_source: ALLEGRO_EVENT_SOURCE;
    field1, field2: INTEGER;
    { etc. }
  END;

FUNCTION CreateThing: THINGptr;
BEGIN
  RESULT := getmem (sizeof (THING));
  IF RESULT <> NIL THEN
  BEGIN
    al_init_user_event_source (@@(RESULT^.event_source));
    RESULT^.field1 := 0;
    RESULT^.field2 := 0
  END
END;
!)

The advantage here is that the @code(THING) pointer will be the same as the
@code(ALLEGRO_EVENT_SOURCE) pointer. Events emitted by the event source will
have the event source pointer as the source field, from which you can get a
pointer to a @code(THING) by a simple cast (after ensuring checking the event
is of the correct type).

However, it is only one technique and you are not obliged to use it.

The user event source will never be destroyed automatically. You must destroy
it manually with @code(al_destroy_user_event_source).
@param(source Pointer to the variable that will store the source information.)
@seealso(ALLEGRO_EVENT_SOURCE) @seealso(al_destroy_user_event_source)
@seealso(al_emit_user_event) @seealso(ALLEGRO_USER_EVENT)
#allegro5.al_destroy_user_event_source
Destroys an event source initialised with @link(al_init_user_event_source).

This does not free the memory, as that was user allocated to begin with.
@param(source Pointer to the variable that stored the source information.)
@seealso(ALLEGRO_EVENT_SOURCE)
#allegro5.al_emit_user_event
Emits an event from a user event source. The event source must have been initialised with @link(al_init_user_event_source).
@Returns(@false if the event source isn't registered with any queues, hence the event wouldn't have been delivered into any queues.)

Events are copied in and out of event queues, so after this function returns the memory pointed to by event may be freed or reused. Some fields of the event being passed in may be modified by the function.

Reference counting will be performed if @code(dtor) is not @nil. Whenever a copy of the event is made, the reference count increases. You need to call @link(al_unref_user_event) to decrease the reference count once you are done with a user event that you have received from @link(al_get_next_event), @link(al_peek_next_event), @link(al_wait_for_event), etc.

Once the reference count drops to zero @code(dtor) will be called with a copy of the event as an argument. It should free the resources associated with the event, but not the event itself (since it is just a copy).

If @code(dtor) is @nil then reference counting will not be performed. It is safe, but unnecessary, to call @code(al_unref_user_event) on non-reference counted user events.

You can use @code(al_emit_user_event) to emit both user and non-user events from your user event source. Note that emitting input events will not update the corresponding input device states. For example, you may emit an event of type @link(ALLEGRO_EVENT_KEY_DOWN), but it will not update the @link(ALLEGRO_KEYBOARD_STATE) returned by @link(al_get_keyboard_state).
@seealso(ALLEGRO_USER_EVENT) @seealso(al_unref_user_event) @seealso(ALLEGRO_EVENT_DTOR_PROC)
#allegro5.al_unref_user_event
Decreases the reference count of a user-defined event. This must be called on any user event that you get from @link(al_get_next_event), @link(al_peek_next_event), @link(al_wait_for_event), etc. which is reference counted. This function does nothing if the event is not reference counted.
@seealso(al_emit_user_event) @seealso(ALLEGRO_USER_EVENT)
#allegro5.al_set_event_source_data
Assigns the abstract user data to the event source. Allegro does not use the data internally for anything; it is simply meant as a convenient way to associate your own data or objects with events.
@seealso(al_get_event_source_data)
#allegro5.al_get_event_source_data
Returns the abstract user data associated with the event source. If no data was previously set, returns @nil.
@seealso(al_set_event_source_data)

#allegro5.ALLEGRO_EVENT_QUEUEptr
An event queue holds events that have been generated by event sources that are registered with the queue. Events are stored in the order they are generated. Access is in a strictly FIFO (first-in-first-out) order.
@seealso(al_create_event_queue) @seealso(al_destroy_event_queue)

#allegro5.al_create_event_queue
Creates a new, empty event queue.
@return(A pointer to the newly created object if successful, @nil on error.)
@seealso(al_register_event_source) @seealso(al_destroy_event_queue)@seealso(ALLEGRO_EVENT_QUEUEptr)
#allegro5.al_destroy_event_queue
Destroys the event queue specified. All event sources currently registered
with the queue will be automatically unregistered before the queue is
destroyed.
@seealso(al_create_event_queue) @seealso(ALLEGRO_EVENT_QUEUEptr)
#allegro5.al_register_event_source
Register the event source with the event queue specified. An event source may be registered with any number of event queues simultaneously, or none. Trying to register an event source with the same event queue more than once does nothing.
@seealso(al_unregister_event_source) @seealso(ALLEGRO_EVENT_SOURCE)
#allegro5.al_unregister_event_source
Unregister an event source with an event queue. If the event source is not actually registered with the event queue, nothing happens.

If the queue had any events in it which originated from the event source, they will no longer be in the queue after this call.
@seealso(al_register_event_source)
#allegro5.al_pause_event_queue
Pauses or resumes accepting new events into the event queue (to resume, pass @false for pause). Events already in the queue are unaffected.

While a queue is paused, any events which would be entered into the queue are simply ignored. This is an alternative to unregistering then re-registering all event sources from the event queue, if you just need to prevent events piling up in the queue for a while.
@seealso(al_is_event_queue_paused)
#allegro5.al_is_event_queue_empty
Returns @true if the event queue specified is currently empty. @seealso(al_get_next_event) @seealso(al_peek_next_event)
#allegro5.al_get_next_event
Takes the next event out of the event queue specified, and copy the contents into @code(ret_event), returning @true.  The original event will be removed from the queue.  If the event queue is empty, returns @false and the contents of @code(ret_event) are unspecified.
@seealso(ALLEGRO_EVENT) @seealso(al_peek_next_event) @seealso(al_wait_for_event)
#allegro5.al_peek_next_event
Copies the contents of the next event in the event queue specified into @code(ret_event) and returns @true. The original event packet will remain at the head of the queue. If the event queue is actually empty, this function returns @false and the contents of @code(ret_event) are unspecified.
@seealso(ALLEGRO_EVENT) @seealso(al_get_next_event) @seealso(al_drop_next_event)
#allegro5.al_drop_next_event
Drops (removes) the next event from the queue. If the queue is empty, nothing happens.
@param(queue Pointer to the queue.)
@Returns((@true) if an event was dropped.)
@seealso(al_flush_event_queue) @seealso(al_is_event_queue_empty)
#allegro5.al_wait_for_event
Waits until the event queue specified is non-empty. If @code(ret_event) is not @nil, the first event in the queue will be copied into @code(ret_event) and removed from the queue. If @code(ret_event) is @nil the first event is left at the head of the queue.
@seealso(ALLEGRO_EVENT) @seealso(al_wait_for_event_timed) @seealso(al_wait_for_event_until) @seealso(al_get_next_event)
#allegro5.al_wait_for_event_timed
Waits until the event queue specified is non-empty.
@param(queue Pointer to the queue.)
@param(ret_event If it is not @nil, the first event in the queue will be copied into @code(ret_event) and removed from the queue. If it is @nil the first event is left at the head of the queue.)
@param(secs Determines approximately how many seconds to wait. If the call times out, @false is returned. Otherwise, if an event ocurred, @true is returned.  For compatibility with all platforms, @code(secs) must be 2,147,483.647 seconds or less.)
@seealso(ALLEGRO_EVENT) @seealso(al_wait_for_event) @seealso(al_wait_for_event_until)
#allegro5.al_wait_for_event_until
Waits until the event queue specified is non-empty.
@param(queue Pointer to the queue.)
@param(ret_event If it is not @nil, the first event in the queue will be copied into @code(ret_event) and removed from the queue. If it is @nil the first event is left at the head of the queue.)
@param(timeout Determines how long to wait. If the call times out, @false is returned. Otherwise, if an event ocurred, @true is returned.  For compatibility with all platforms, @code(timeout) must be 2,147,483.647 seconds or less.)
@seealso(ALLEGRO_EVENT) @seealso(al_init_timeout) @seealso(al_wait_for_event) @seealso(al_wait_for_event_timed)



#allegro5.ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE
Max size of window titles. @seealso(al_set_new_window_title) @seealso(al_set_window_title)

#allegro5.al_set_new_display_refresh_rate
Sets the refresh rate to use when creating new displays on the calling thread. If the refresh rate is not available, @link(al_create_display) will fail. A list of modes with refresh rates can be found with @link(al_get_num_display_modes) and @link(al_get_display_mode).

The default setting is zero (don't care).
@seealso(al_get_new_display_refresh_rate)
#allegro5.al_set_new_display_flags
Sets various flags to be used when creating new displays on the calling
thread. flags is a bitfield containing any reasonable combination of the following:
@unorderedlist(
  @item(@bold(@code(ALLEGRO_WINDOWED)) Prefer a windowed mode.

    Under multi-head X (not XRandR/TwinView), the use of more than one adapter is impossible due to bugs in X and GLX. @link(al_create_display) will fail if more than one adapter is attempted to be used.)
  @item(@bold(@code(ALLEGRO_FULLSCREEN_WINDOW)) Make the window span the entire screen. Unlike @code(ALLEGRO_FULLSCREEN) this will never attempt to modify the screen resolution. Instead the pixel dimensions of the created display will be the same as the desktop.

    The passed width and height are only used if the window is switched out of fullscreen mode later but will be ignored initially.

    Under Windows and X11 a fullscreen display created with this flag will behave differently from one created with the @code(ALLEGRO_FULLSCREEN) flag - even if the @code(ALLEGRO_FULLSCREEN) display is passed the desktop dimensions. The exact difference is platform dependent, but some things which may be different is how alt-tab works, how fast you can toggle between fullscreen/windowed mode or how additional monitors behave while your display is in fullscreen mode.

    Additionally under X, the use of more than one adapter in multi-head mode or with true Xinerama enabled is impossible due to bugs in X/GLX, creation will fail if more than one adapter is attempted to be used.)
  @item(@bold(@code(ALLEGRO_FULLSCREEN)) Prefer a fullscreen mode.

    Under X the use of more than one FULLSCREEN display when using multi-head X, or true Xinerama is not possible due to bugs in X and GLX, display creation will fail if more than one adapter is attempted to be used.

    @bold(Note:) Prefer using @code(ALLEGRO_FULLSCREEN_WINDOW) as it typically provides a better user experience as the monitor doesn't change resolution and switching away from your game via Alt-Tab works smoothly. @code(ALLEGRO_FULLSCREEN) is typically less well supported compared to @code(ALLEGRO_FULLSCREEN_WINDOW).)
  @item(@bold(@code(ALLEGRO_RESIZABLE)) The display is resizable @(only applicable if combined with @code(ALLEGRO_WINDOWED)@).)
  @item(@bold(@code(ALLEGRO_MAXIMIZED)) The display window will be maximized @(only applicable if combined with @code(ALLEGRO_RESIZABLE)@).)
  @item(@bold(@code(ALLEGRO_OPENGL)) Require the driver to provide an initialized OpenGL context after returning successfully.)
  @item(@bold(@code(ALLEGRO_OPENGL_3_0)) Require the driver to provide an initialized OpenGL context compatible with OpenGL version 3.0.)
  @item(@bold(@code(ALLEGRO_OPENGL_FORWARD_COMPATIBLE)) If this flag is set, the OpenGL context created with @code(ALLEGRO_OPENGL_3_0) will be forward compatible only, meaning that all of the OpenGL API declared deprecated in OpenGL 3.0 will not be supported. Currently, a display created with this flag will not be compatible with Allegro drawing routines; the display option @code(ALLEGRO_COMPATIBLE_DISPLAY) will be set to false.)
  @item(@bold(@code(ALLEGRO_OPENGL_ES_PROFILE)) Used together with @code(ALLEGRO_OPENGL), requests that the OpenGL context uses the OpenGL ES profile. A specific version can be requested with @link(al_set_new_display_option). @bold(Note:) Currently this is only supported by the X11/GLX driver.)
  @item(@bold(@code(ALLEGRO_DIRECT3D)) Require the driver to do rendering with Direct3D and provide a Direct3D device.)
  @item(@bold(@code(ALLEGRO_PROGRAMMABLE_PIPELINE)) Require a programmable graphics pipeline. This flag is required to use @link(ALLEGRO_SHADERptr) objects.)
  @item(@bold(@code(ALLEGRO_FRAMELESS)) Try to create a window without a frame @(i.e. no border or titlebar@). This usually does nothing for fullscreen modes, and even in windowed modes it depends on the underlying platform whether it is supported or not.)
  @item(@bold(@code(ALLEGRO_GENERATE_EXPOSE_EVENTS)) Let the display generate expose events.)
)
0 can be used for default values.
@seealso(al_set_new_display_option) @seealso(al_get_display_option) @seealso(al_set_display_option)
#allegro5.al_get_new_display_refresh_rate
Gets the requested refresh rate to be used when creating new displays on the calling thread.
@seealso(al_set_new_display_refresh_rate)
#allegro5.al_get_new_display_flags
Gets the display flags to be used when creating new displays on the calling thread.
@seealso(al_set_new_display_flags) @seealso(al_set_display_flag)

#allegro5.al_set_new_window_title
Sets the title that will be used when a new display is created. Allegro uses a static buffer of @code(ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE) to store this, so the length of the titme you set must be less than this.
@seealso(al_set_window_title) @seealso(al_get_new_window_title) @seealso(al_create_display) @seealso(ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE)
#allegro5.al_get_new_window_title
Returns the title that will be used when a new display is created. This returns the value that @link(al_set_window_title) was called with. The current implementation returns a pointer to a static buffer of which you should make a copy if you want to modify it.
@seealso(al_set_window_title) @seealso(al_set_new_window_title) @seealso(al_create_display)

#allegro5.al_get_display_width
Gets the width of the display. This is like @code(SCREEN_W) in Allegro 4.x.
@seealso(al_get_display_height)
#allegro5.al_get_display_height
Gets the height of the display. This is like @code(SCREEN_H) in Allegro 4.x.
@seealso(al_get_display_width)
#allegro5.al_get_display_format
Gets pixel format of the display.
@seealso(ALLEGRO_PIXEL_FORMAT)
#allegro5.al_get_display_refresh_rate
Gets the refresh rate of the display.
@seealso(al_set_new_display_refresh_rate)
#allegro5.al_get_display_flags
Gets the flags of the display.

In addition to the flags set for the display at creation time with @link(al_set_new_display_flags) it can also have the @code(ALLEGRO_MINIMIZED) flag set, indicating that the window is currently minimized.  This flag is very platform-dependent as even a minimized application may still render a preview version so normally you should not care whether it is minimized or not.
@seealso(al_set_new_display_flags) @seealso(al_set_display_flag)
#allegro5.al_get_display_orientation
Return the display orientation, which can be one of the following:
@unorderedlist(
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN))
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES))
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES))
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES))
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES))
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_FACE_UP))
  @item(@code(ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN))
)
#allegro5.al_set_display_flag
Enables or disables one of the display flags. The flags are the same as for @link(al_set_new_display_flags).  The only flags that can be changed after creation are:
@unorderedlist(
  @item(@code(ALLEGRO_FULLSCREEN_WINDOW)) @item(@code(ALLEGRO_FRAMELESS)) @item(@code(ALLEGRO_MAXIMIZED))
)
You can use @code(al_get_display_flags) to query whether the given display property actually changed.
@return(@true if the driver supports toggling the specified flag else @false.)
@seealso(al_set_new_display_flags) @seealso(al_get_display_flags)

#allegro5.al_create_display
Creates a display, or window, with the specified dimensions. The parameters of the display are determined by the last calls to @code(al_set_new_display_* ). Default parameters are used if none are set explicitly. Creating a new display will automatically make it the active one, with the backbuffer selected for drawing.

Each display that uses OpenGL as a backend has a distinct OpenGL rendering context associated with it. See @link(al_set_target_bitmap) for the discussion about rendering contexts.
@returns(@nil on error.)
@seealso(al_set_new_display_flags) @seealso(al_set_new_display_option) @seealso(al_set_new_display_refresh_rate) @seealso(al_set_new_display_adapter) @seealso(al_set_new_window_title) @seealso(al_destroy_display)
#allegro5.al_destroy_display
Destroys a display.

If the target bitmap of the calling thread is tied to the display, then it implies a call to @code(al_set_target_bitmap @(@nil@);) before the display is destroyed.

That special case notwithstanding, you should make sure no threads are currently targeting a bitmap which is tied to the display before you destroy it.
@seealso(al_set_target_bitmap)
#allegro5.al_get_current_display
Returns the display that is "current" for the calling thread, or @nil if there is none.
@seealso(al_set_target_bitmap)
#allegro5.al_set_target_bitmap
This function selects the bitmap to which all subsequent drawing operations in the calling thread will draw to. To return to drawing to a display, set the backbuffer of the display as the target bitmap, using @link(al_get_backbuffer).  As a convenience, you may also use @link(al_set_target_backbuffer).

Each video bitmap is tied to a display. When a video bitmap is set to as the target bitmap, the display that the bitmap belongs to is automatically made "current" for the calling thread (if it is not current already). Then drawing other bitmaps which are tied to the same display can be hardware accelerated.

A single display cannot be current for multiple threads simultaneously. If you need to release a display, so it is not current for the calling thread, call @code(al_set_target_bitmap @(@nil@);)

Setting a memory bitmap as the target bitmap will not change which display is current for the calling thread.

On some platforms, Allegro automatically backs up the contents of video bitmaps because they may be occasionally lost (see discussion in @link(al_create_bitmap)'s documentation). If you're completely recreating the bitmap contents often (e.g. every frame) then you will get much better performance by creating the target bitmap with @code(ALLEGRO_NO_PRESERVE_TEXTURE) flag.

@bold(OpenGL note:)

Framebuffer objects (FBOs) allow OpenGL to directly draw to a bitmap, which is very fast. When using an OpenGL display, if all of the following conditions are met an FBO will be created for use with the bitmap:@unorderedlist(
    @item(The @code(GL_EXT_framebuffer_object) OpenGL extension is available.)
    @item(The bitmap is not a memory bitmap.)
    @item(The bitmap is not currently locked.)
)
In Allegro 5.0.0, you had to be careful as an FBO would be kept around until the bitmap is destroyed or you explicitly called @link(al_remove_opengl_fbo) on the bitmap, wasting resources. In newer versions, FBOs will be freed automatically when the bitmap is no longer the target bitmap, unless you have called @link(al_get_opengl_fbo) to retrieve the FBO id.

In the following example, no FBO will be created:
@longcode(!
lock := al_lock_bitmap (bitmap);
al_set_target_bitmap (bitmap);
al_put_pixel (x, y, color);
al_unlock_bitmap (bitmap);
!)
The above allows using @link(al_put_pixel) on a locked bitmap without creating an FBO.

In this example an FBO is created however:
@longcode(!
al_set_target_bitmap (bitmap);
al_draw_line (x1, y1, x2, y2, color, 0);
!)
An OpenGL command will be used to directly draw the line into the bitmap's associated texture.
@seealso(al_get_target_bitmap) @seealso(al_set_target_backbuffer)
#allegro5.al_set_target_backbuffer
Same as @code(al_set_target_bitmap@(al_get_backbuffer@(display@)@);).
@seealso(al_set_target_bitmap) @seealso(al_get_backbuffer)
#allegro5.al_get_backbuffer
Returns a special bitmap representing the back-buffer of the display.

Care should be taken when using the backbuffer bitmap (and its sub-bitmaps) as the source bitmap (e.g as the bitmap argument to @link(al_draw_bitmap)).  Only untransformed operations are hardware accelerated. These consist of @link(al_draw_bitmap) and @link(al_draw_bitmap_region) when the current transformation is the identity. If the tranformation is not the identity, or some other drawing operation is used, the call will be routed through the memory bitmap routines, which are slow. If you need those operations to be accelerated, then first copy a region of the backbuffer into a temporary bitmap (via the @link(al_draw_bitmap) and @link(al_draw_bitmap_region)), and then use that temporary bitmap as the source bitmap.
#allegro5.al_get_target_bitmap
Returns the target bitmap of the calling thread. @seealso(al_set_target_bitmap)

#allegro5.al_acknowledge_resize
When the user receives a resize event (@link(ALLEGRO_EVENT_DISPLAY_RESIZE) from a resizable display, if they wish the display to be resized they must call this function to let the graphics driver know that it can now resize the display.

Adjusts the clipping rectangle to the full size of the backbuffer. This also resets the backbuffers projection transform to default orthographic transform (see @link(al_use_projection_transform)).

Note that a resize event may be outdated by the time you acknowledge it;  there could be further resize events generated in the meantime.
@return(@true on success.)
@seealso(al_resize_display) @seealso(ALLEGRO_EVENT)
#allegro5.al_resize_display
Resizes the display.  This works on both fullscreen and windowed displays, regardless of the @code(ALLEGRO_RESIZABLE) flag.

Adjusts the clipping rectangle to the full size of the backbuffer.
@returns(@true on success, or @false on error.)
@seealso(al_acknowledge_resize)
#allegro5.al_flip_display
Copies or updates the front and back buffers so that what has been drawn previously on the currently selected display becomes visible on screen. Pointers to the special back buffer bitmap remain valid and retain their semantics as the back buffer, although the contents may have changed.

Several display options change how this function behaves:
@unorderedlist(
 @item(With @code(ALLEGRO_SINGLE_BUFFER), no flipping is done. You still have
     to call this function to display graphics, depending on how the used
     graphics system works.)
 @item(The @code(ALLEGRO_SWAP_METHOD) option may have additional information
     about what kind of operation is used internally to flip the front and back
     buffers.)
 @item(If @code(ALLEGRO_VSYNC) is 1, this function will force waiting for
     vsync. If @code(ALLEGRO_VSYNC) is 2, this function will not wait for
     vsync. With many drivers the vsync behavior is controlled by the user and
     not the application, and @code(ALLEGRO_VSYNC) will not be set; in this
     case @code(al_flip_display) will wait for vsync depending on the settings
     set in the system's graphics preferences.)
)
@seealso(al_set_new_display_flags) @seealso(al_set_new_display_option) @seealso(al_wait_for_vsync)
#allegro5.al_update_display_region
Does the same as al_flip_display, but tries to update only the specified region. With many drivers this is not possible, but for some it can improve performance. If this is not supported, this function falls back to the behavior of @link(al_flip_display). You can query the support for this function using @code(al_get_display_option @(display, ALLEGRO_UPDATE_DISPLAY_REGION@)).
@seealso(al_flip_display) @seealso(al_get_display_option)
#allegro5.al_is_compatible_bitmap
D3D and OpenGL allow sharing a texture in a way so it can be used for multiple windows. Each @link(ALLEGRO_BITMAPptr) created with @link(al_create_bitmap) however is usually tied to a single @code(ALLEGRO_DISPLAYptr). This function can be used to know if the bitmap is compatible with the given display, even if it is a different display to the one it was created with. It returns @true if the bitmap is compatible (things like a cached texture version can be used) and @false otherwise (blitting in the current display will be slow).

The only time this function is useful is if you are using multiple windows and need accelerated blitting of the same bitmaps to both.
@Returns(@true if the bitmap is compatible with the current display, @false otherwise. If there is no current display, @false is returned.)

#allegro5.al_wait_for_vsync
Waits for the beginning of a vertical retrace. Some driver/card/monitor combinations may not be capable of this.

Note how @link(al_flip_display) usually already waits for the vertical retrace, so unless you are doing something special, there is no reason to call this function.
@returns(@false if not possible, @true if successful.)
@seealso(al_flip_display)

#allegro5.al_get_display_event_source
Retrieves the associated event source. See the documentation on events for a list of the events displays will generate.
@seealso(ALLEGRO_EVENT_DISPLAY_EXPOSE)

#allegro5.al_set_display_icon
Changes the icon associated with the display (window).
@seealso(al_set_display_icons) @seealso(al_set_window_title)
#allegro5.al_set_display_icons
Changes the icons associated with the display (window). Multiple icons can be provided for use in different contexts, e.g. window frame, taskbar, alt-tab popup. The number of icons must be at least one.

@bold(Note)

If the underlying OS requires an icon of a size not provided then one of the bitmaps will be scaled up or down to the required size. The choice of bitmap is implementation dependent.
@seealso(al_set_display_icon) @seealso(al_set_window_title)

#allegro5.al_get_new_display_adapter
Gets the video adapter index where new displays will be created by the calling thread, if previously set with @link(al_set_new_display_adapter). Otherwise returns @code(ALLEGRO_DEFAULT_DISPLAY_ADAPTER).
@seealso(al_set_new_display_adapter)
#allegro5.al_set_new_display_adapter
Sets the adapter to use for new displays created by the calling thread. The adapter has a monitor attached to it. Information about the monitor can be gotten using @link(al_get_num_video_adapters) and @link(al_get_monitor_info).

To return to the default behaviour, pass @code(ALLEGRO_DEFAULT_DISPLAY_ADAPTER).
@seealso(al_get_num_video_adapters) @seealso(al_get_monitor_info)
#allegro5.al_set_new_window_position
Sets where the top left pixel of the client area of newly created windows (non-fullscreen) will be on screen, for displays created by the calling thread. Negative values are allowed on some multihead systems.

To reset to the default behaviour, pass @code(@(maxLongint, maxLongint@)).
@seealso(al_get_new_window_position) @seealso(al_set_window_position)
#allegro5.al_get_new_window_position
Gets the position where new non-fullscreen displays created by the calling thread will be placed.
@seealso(al_set_new_window_position)
#allegro5.al_set_window_position
Sets the position on screen of a non-fullscreen display.
@seealso(al_get_window_position) @seealso(al_set_new_window_position)
#allegro5.al_get_window_position
Gets the position of a non-fullscreen display.
@seealso(al_set_window_position)
#allegro5.al_set_window_constraints
Constrains a non-fullscreen resizable display. The constraints are a hint only, and are not necessarily respected by the window environment. A value of 0 for any of the parameters indicates no constraint for that parameter.

The constraints will be applied to a display only after the @link(al_apply_window_constraints) function call.
@seealso(al_apply_window_constraints) (al_get_window_constraints)
#allegro5.al_get_window_constraints
Gets the constraints for a non-fullscreen resizable display.
@seealso(al_set_window_constraints)
#allegro5.al_apply_window_constraints
Enables or disables previously set constraints by @link(al_set_window_constraints) function.

If enabled, the specified display will be automatically resized to new sizes to conform constraints in next cases:
@unorderedlist(
  @item(The specified display is resizable, not maximized and is not in fullscreen mode.)
  @item(If the appropriate current display size (width or height) is less than the value of constraint. Applied to minimum constraints.)
  @item(If the appropriate current display size (width or height) is greater than the value of constraint. Applied to maximum constraints.)
)
Constrains are not applied when a display is toggle from windowed to maximized or fullscreen modes. When a display is toggle from maximized/fullscreen to windowed mode, then the display may be resized as described above. The later case is also possible when a user drags the maximized display via mouse.

If disabled, the specified display will stop using constraints.
@seealso(al_get_window_constraints) @seealso(al_set_window_constraints)

#allegro5.al_set_window_title
Sets the title on a display.
@seealso(al_set_display_icon) @seealso(al_set_display_icons)

#allegro5.al_set_new_display_option
Sets an extra display option, to be used when creating new displays on the
   calling thread.  Display options differ from display flags, and specify some
   details of the context to be created within the window itself.  These mainly
   have no effect on Allegro itself, but you may want to specify them, for
   example if you want to use multisampling.

The @code(importance) parameter can be either:@unorderedlist(
  @item(@bold(@code(ALLEGRO_REQUIRE)) - The display will not be created if
     the setting can not be met.)
  @item(@bold(@code(ALLEGRO_SUGGEST)) - If the setting is not available, the
     display will be created anyway with a setting as close as possible to the
     requested one.  You can query the actual value used in that case by
     calling @link(al_get_display_option) after the display has been created.)
  @item(@bold(@code(ALLEGRO_DONTCARE)) - If you added a display option with
     one of the above two settings before, it will be removed again.  Else this
     does nothing.)
)
The supported options are:
@definitionlist(
  @itemlabel(@bold(@code(ALLEGRO_COLOR_SIZE))) @item(This can be used to ask for a
     specific bit depth. For example to force a 16-bit framebuffer set this to
     16.)
  @itemlabel(@bold(@code(ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE,
     ALLEGRO_ALPHA_SIZE))) @item(Individual color component size in bits.)
  @itemlabel(@bold(@code(ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT,
     ALLEGRO_BLUE_SHIFT, ALLEGRO_ALPHA_SHIFT))) @item(Together with the previous
     settings these can be used to specify the exact pixel layout the display
     should use. Normally there is no reason to use these.)
  @itemlabel(@bold(@code(ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE,
     ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE))) @item(This can be used to
     define the required accumulation buffer size.)
  @itemlabel(@bold(@code(ALLEGRO_STEREO))) @item(Whether the display is a stereo display.)
  @itemlabel(@bold(@code(ALLEGRO_AUX_BUFFERS))) @item(Number of auxiliary buffers the
     display should have.)
  @itemlabel(@bold(@code(ALLEGRO_DEPTH_SIZE))) @item(How many depth buffer @(z-buffer@)
     bits to use.)
  @itemlabel(@bold(@code(ALLEGRO_STENCIL_SIZE))) @item(How many bits to use for the
     stencil buffer.)
  @itemlabel(@bold(@code(ALLEGRO_SAMPLE_BUFFERS))) @item(Whether to use multisampling
     @(@code(1)@) or not @(@code(0)@).)
  @itemlabel(@bold(@code(ALLEGRO_SAMPLES))) @item(If the above is @code(1), the number
     of samples to use per pixel. Else @code(0).)
  @itemlabel(@bold(@code(ALLEGRO_RENDER_METHOD))) @item(@code(0) if hardware
     acceleration is not used with this display.)
  @itemlabel(@bold(@code(ALLEGRO_FLOAT_COLOR))) @item(Whether to use floating point
     color components.)
  @itemlabel(@bold(@code(ALLEGRO_FLOAT_DEPTH))) @item(Whether to use a floating point
     depth buffer.)
  @itemlabel(@bold(@code(ALLEGRO_SINGLE_BUFFER))) @item(Whether the display uses a
     single buffer @(@code(1)@) or another update method @(@code(0)@).)
  @itemlabel(@bold(@code(ALLEGRO_SWAP_METHOD))) @item(If the above is @code(0), this is
     set to @code(1) to indicate the display is using a copying method to make
     the next buffer in the flip chain available, or to @code(2) to indicate a
     flipping or other method.)
  @itemlabel(@bold(@code(ALLEGRO_COMPATIBLE_DISPLAY))) @item(Indicates if Allegro's
     graphics functions can use this display. If you request a display not
     useable by Allegro, you can still use for example OpenGL to draw graphics.)
  @itemlabel(@bold(@code(ALLEGRO_UPDATE_DISPLAY_REGION))) @item(Set to @code(1) if the
     display is capable of updating just a region, and @code(0) if calling
     @link(al_update_display_region) is equivalent to @link(al_flip_display).)
  @itemlabel(@bold(@code(ALLEGRO_VSYNC))) @item(Set to @code(1) to tell the driver to
     wait for vsync in @link(al_flip_display), or to @code(2) to force vsync
     off.  The default of @code(0) means that Allegro does not try to modify
     the vsync behavior so it may be on or off.  Note that even in the case of
     1 or 2 it is possible to override the vsync behavior in the graphics
     driver so you should not rely on it.)
  @itemlabel(@bold(@code(ALLEGRO_MAX_BITMAP_SIZE))) @item(When queried this returns the
     maximum size @(width as well as height@) a bitmap can have for this
     display.  Calls to @link(al_create_bitmap) or @link(al_load_bitmap) for
     bitmaps larger than this size will fail.  It does not apply to memory
     bitmaps which always can have arbitrary size @(but are slow for drawing@).)
  @itemlabel(@bold(@code(ALLEGRO_SUPPORT_NPOT_BITMAP))) @item(Set to 1 if textures used
     for bitmaps on this display can have a size which is not a power of two.
     This is mostly useful if you use Allegro to load textures as otherwise
     only power-of-two textures will be used internally as bitmap storage.)
  @itemlabel(@bold(@code(ALLEGRO_CAN_DRAW_INTO_BITMAP))) @item(Set to @code(1) if you
     can use @link(al_set_target_bitmap) on bitmaps of this display to draw
     into them. If this is not the case software emulation will be used when
     drawing into display bitmaps @(which can be very slow@).)
  @itemlabel(@bold(@code(ALLEGRO_SUPPORT_SEPARATE_ALPHA))) @item(This is set to
    @code(1) if the @link(al_set_separate_blender) function is supported.
     Otherwise the alpha parameters will be ignored.)
  @itemlabel(@bold(@code(ALLEGRO_AUTO_CONVERT_BITMAPS))) @item(This is on by
     default. It causes any existing memory bitmaps with the
     @code(ALLEGRO_CONVERT_BITMAP) flag to be converted to a display bitmap of
     the newly created display with the option set.)
  @itemlabel(@bold(@code(ALLEGRO_SUPPORTED_ORIENTATIONS))) @item(This is a
     bit-combination of the orientations supported by the application. The
     orientations are the same as for @link(al_get_display_orientation) with
     the additional possibilities:@unorderedlist(
     @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT)) - means only the
      two portrait orientations are supported.)
     @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE)) - means only the
      two landscape orientations)
     @item(@bold(@code(ALLEGRO_DISPLAY_ORIENTATION_ALL)) - allows all four
      orientations.))
     When the orientation changes between a portrait and a landscape
     orientation the display needs to be resized.  This is done by sending an
     @code(ALLEGRO_EVENT_DISPLAY_RESIZE) message which should be handled by
     calling @link(al_acknowledge_resize).)
  @itemlabel(@bold(@code(ALLEGRO_OPENGL_MAJOR_VERSION))) @item(Request a specific OpenGL major version.)
  @itemlabel(@bold(@code(ALLEGRO_OPENGL_MINOR_VERSION))) @item(Request a specific OpenGL minor version.)
  @itemlabel(@bold(@code(ALLEGRO_DEFAULT_SHADER_PLATFORM))) @item(Specify the shader platform to use for the default shader. See @link(ALLEGRO_SHADER_PLATFORM). The default is @link(ALLEGRO_SHADER_AUTO).)
)
@seealso(al_get_new_display_option)@seealso(al_set_new_display_flags) @seealso(al_reset_new_display_options) @seealso(al_get_display_option)
#allegro5.al_get_new_display_option
Retrieves an extra display setting which was previously set with @link(al_set_new_display_option).
#allegro5.al_reset_new_display_options
This undoes any previous call to al_set_new_display_option on the calling thread.
@seealso(al_set_new_display_option)
#allegro5.al_set_display_option
Changes an option that was previously set for a display. After displays are created, they take on the options set with @link(al_set_new_display_option). Calling @link(al_set_new_display_option) subsequently only changes options for newly created displays, and doesn't touch the options of already created displays. @code(al_set_display_option) allows changing some of these values. Not all display options can be changed or changing them will have no effect. Changing options other than those listed below is undefined.
@definitionlist(
  @itemlabel(@bold(@code(ALLEGRO_SUPPORTED_ORIENTATIONS))) @item(This can be changed to allow new or restrict previously enabled orientations of the screen/device. See al_set_new_display_option for more information on this option.)
)
@seealso(al_get_display_option) @seealso(al_set_new_display_option)
#allegro5.al_get_display_option
Returns an extra display setting of the display. @seealso(al_set_new_display_option)
#allegro5.al_hold_bitmap_drawing
Enables or disables deferred bitmap drawing. This allows for efficient drawing of many bitmaps that share a parent bitmap, such as sub-bitmaps from a tilesheet or simply identical bitmaps. Drawing bitmaps that do not share a parent is less efficient, so it is advisable to stagger bitmap drawing calls such that the parent bitmap is the same for large number of those calls. While deferred bitmap drawing is enabled, the only functions that can be used are the bitmap drawing functions and font drawing functions. Changing the state such as the blending modes will result in undefined behaviour. One exception to this rule are the non-projection transformations. It is possible to set a new transformation while the drawing is held.

No drawing is guaranteed to take place until you disable the hold. Thus, the idiom of this function's usage is to enable the deferred bitmap drawing, draw as many bitmaps as possible, taking care to stagger bitmaps that share parent bitmaps, and then disable deferred drawing. As mentioned above, this function also works with bitmap and truetype fonts, so if multiple lines of text need to be drawn, this function can speed things up.
@seealso(al_is_bitmap_drawing_held)
#allegro5.al_is_bitmap_drawing_held
Returns whether the deferred bitmap drawing mode is turned on or off. @seealso(al_hold_bitmap_drawing)

#allegro5.al_acknowledge_drawing_halt
Call this in response to the @link(ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) event. This is currently necessary for Android and iOS as you are not allowed to draw to your display while it is not being shown. If you do not call this function to let the operating system know that you have stopped drawing or if you call it to late the application likely will be considered misbehaving and get terminated.
@seealso(ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) @seealso(al_acknowledge_drawing_resume)
#allegro5.al_acknowledge_drawing_resume
Call this in response to the @seealso(ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) event.
@seealso(ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) @seealso(al_acknowledge_drawing_halt)



#allegro5.al_get_clipboard_text
This function returns a pointer to a string, allocated with @link(al_malloc) with the text contents of the clipboard if available. If no text is available on the clipboard then this function returns @nil. You must call @link(al_free) on the returned pointer when you don't need it anymore.

Beware that text on the clipboard on Windows may be in Windows format, that is, it may have carriage return newline combinations for the line endings instead of regular newlines for the line endings on Linux or OSX.
@seealso(al_set_clipboard_text) @seealso(al_clipboard_has_text)
#allegro5.al_set_clipboard_text
This function pastes the text given as an argument to the clipboard.
@seealso(al_get_clipboard_text) @seealso(al_clipboard_has_text)
#allegro5.al_clipboard_has_text
This function returns true if and only if the clipboard has text available.
@seealso(al_set_clipboard_text) @seealso(al_get_clipboard_text)



#allegro5.al_create_config
Creates an empty configuration structure. @seealso(al_load_config_file) @seealso(al_destroy_config)
#allegro5.al_add_config_section
Adds a section to a configuration structure with the given name. If the section already exists then nothing happens.
@seealso(al_remove_config_section) @seealso(al_create_config)
#allegro5.al_set_config_value
Sets a value in a section of a configuration. If the section doesn't yet exist, it will be created. If a value already existed for the given key,
it will be overwritten. The section can be @code('') for the global section.

For consistency with the on-disk format of config files, any leading and trailing whitespace will be stripped from the value. If you have significant whitespace you wish to preserve, you should add your own quote characters and remove them when reading the values back in.
@seealso(al_get_config_value)
#allegro5.al_add_config_comment
Adds a comment in a section of a configuration. If the section doesn't yet exist, it will be created. The section can be @code('') for the global section.

The comment may or may not begin with a hash character. Any newlines in the comment string will be replaced by space characters.
@seealso(al_add_config_section)
#allegro5.al_get_config_value
Gets a pointer to an internal character buffer that will only remain valid as long as the @code(ALLEGRO_CONFIGptr) structure is not destroyed. Copy the value if you need a copy.  The section can be @code('') for the global section.
@return(@nil if section or key do not exist.)
@seealso(al_set_config_value)
#allegro5.al_load_config_file
Reads a configuration file from disk. The configuration structure should be destroyed with @link(al_destroy_config).
@return(Pointer to configuration or @nil on error.)
@seealso(al_load_config_file_f) @seealso(al_save_config_file) @seealso(al_destroy_config)
#allegro5.al_load_config_file_f
Reads a configuration file from an already open file.
@return(@nil on error. The configuration structure should be destroyed with @link(al_destroy_config). The file remains open afterwards.)
@seealso(al_load_config_file)
#allegro5.al_save_config_file
Writes out a configuration file to disk.
@return(@true on success, @false on error.)
@seealso(al_save_config_file_f) @seealso(al_load_config_file)
#allegro5.al_save_config_file_f
Writes out a configuration file to an already open file.
@return(@true on success, @false on error. The file remains open afterwards.)
@seealso(al_save_config_file)
#allegro5.al_merge_config_into
Merges one configuration structure into another. Values in configuration @code(add) override those in @code(master). @code(master) is modified. Comments from @code(add) are not retained.
@seealso(al_merge_config)
#allegro5.al_merge_config
Merges two configuration structures, and return the result as a new configuration. Values in configuration @code(cfg2) override those in @code(cfg1). Neither of the input configuration structures are modified. Comments from @code(cfg2) are not retained.
@seealso(al_merge_config_into)
#allegro5.al_destroy_config
Frees the resources used by a configuration structure. Does nothing if passed @nil.
@seealso(al_create_config) @seealso(al_load_config_file)
#allegro5.al_remove_config_section
Removes a section of a configuration.
@return(@true if the section was removed, or @false if the section did not exist.)
@seealso(al_add_config_section)
#allegro5.al_remove_config_key
Removes a key and its associated value in a section of a configuration.
@return(@true if the entry was removed, or @false if the entry did not exist.)



#allegro5.al_get_cpu_count
Returns the number of CPU cores that the system Allegro is running on has
and which could be detected, or a negative number if detection failed.  Even
if a positive number is returned, it might be that it is not correct.  For
example, Allegro running on a virtual machine will return the amount of
CPU's of the VM, and not that of the underlying system.

Furthermore even if the number is correct, this only gives you information
about the total CPU cores of the system Allegro runs on.  The amount of
cores available to your program may be less due to circumstances such as
programs that are currently running.

Therefore, it's best to use this for advisory purposes only.  It is
certainly a bad idea to make your program exclusive to systems for which
this function returns a certain "desirable" number.

This function may be called prior to @link(al_install_system) or @link(al_init).
#allegro5.al_get_ram_size
Returns the size in MB of the random access memory that the system Allegro
is running on has and which could be detected, or a negative number if
detection failed.  Even if a positive number is returned, it might be that
it is not correct.  For example, Allegro running on a virtual machine will
return the amount of RAM of the VM, and not that of the underlying system.

Furthermore even if the number is correct, this only gives you information
about the total physical memory of the system Allegro runs on.  The memory
available to your program may be less due to circumstances such as virtual
memory, and other programs that are currently running.

Therefore, it's best to use this for advisory purposes only.  It is
certainly a bad idea to make your program exclusive to systems for which
this function returns a certain "desirable" number.

This function may be called prior to @link(al_install_system) or @link(al_init).



#allegro5.al_clear_to_color
Clears the complete target bitmap, but confined by the clipping rectangle.
@seealso(al_set_clipping_rectangle) @seealso(al_clear_depth_buffer)
#allegro5.al_clear_depth_buffer
Clears the depth buffer (confined by the clipping rectangle) to the given value. A depth buffer is only available if it was requested with @link(al_set_new_display_option) and the requirement could be met by the @link(al_create_display) call creating the current display. Operations involving the depth buffer are also affected by @link(al_set_render_state).

For example, if @code(ALLEGRO_DEPTH_FUNCTION) is set to @code(ALLEGRO_RENDER_LESS) then depth buffer value of 1 represents infinite distance, and thus is a good value to use when clearing the depth buffer.
@seealso(al_clear_to_color) @seealso(al_set_clipping_rectangle) @seealso(al_set_render_state) @seealso(al_set_new_display_option)
#allegro5.al_draw_pixel
Draws a single pixel at @code({x, y}). This function, unlike @link(al_put_pixel), does blending and, unlike @link(al_put_blended_pixel), respects the transformations (that is, the pixel's position is transformed, but its size is unaffected - it remains a pixel). This function can be slow if called often; if you need to draw a lot of pixels consider using @link(al_draw_prim) with @code(ALLEGRO_PRIM_POINT_LIST) from the primitives addon.

@bold(Note)

This function may not draw exactly where you expect it to. See the @bold(Pixel-precise output) section on the @link(al5primitives primitives addon) documentation for details on how to control exactly where the pixel is drawn.
@param(x destination x)
@param(y destination y)
@param(color color of the pixel)
@seealso(ALLEGRO_COLOR) @seealso(al_put_pixel)



#allegro5.AL_EDOM
An error value returned by @link(al_get_errno) in some cases.
@seealso(AL_ERANGE)
#allegro5.AL_ERANGE
An error value returned by @link(al_get_errno) in some cases.
@seealso(AL_EDOM)

#allegro5.al_get_errno
Some Allegro functions will set an error number as well as returning an error code.  Call this function to retrieve the last error number set for the calling thread.
@seealso(al_set_errno) @seealso(AL_EDOM) @seealso(AL_ERANGE)



#allegro5.AL_FIXED
Allegro provides some routines for working with fixed point numbers, and defines the type @code(AL_FIXED) to be a signed 32-bit integer.  The high word is used for the integer part and the low word for the fraction, giving a range of -32768 to 32767 and an accuracy of about four or five decimal places.  Fixed point numbers can be assigned, compared, added, subtracted, negated and shifted (for multiplying or dividing by powers of two) using the normal integer operators, but you should take care to use the appropriate conversion routines when mixing fixed point with integer or floating point values. Writing @code(fixed_point_1 + fixed_point_2) is OK, but @code(fixed_point + integer) is not.

The only advantage of fixed point math routines is that you don't require a floating point coprocessor to use them.  This was great in the time period of i386 and i486 machines, but stopped being so useful with the coming of the Pentium class of processors.  From Pentium onwards, CPUs have increased their strength in floating point operations, equaling or even surpassing integer math performance.

Depending on the type of operations your program may need, using floating point types may be faster than fixed types if you are targeting a specific machine class. Many embedded processors have no FPUs so fixed point maths can be useful there.
@seealso(al_itofix) @seealso(al_fixtoi) @seealso(al_fixtrunc) @seealso(al_ftofix) @seealso(al_fixtof)
@seealso(al_fixadd) @seealso(al_fixsub) @seealso(al_fixmul) @seealso(al_fixdiv)
@seealso(al_fixsqrt)
@seealso(al_fixcos) @seealso(al_fixsin) @seealso(al_fixtan)

#allegro5.AL_FIXTORAD_R
Example:
@longcode(!
var
  RadAngle, BinaryAngle: AL_FIXED;
begin
...

{ Set the binary angle to 90 degrees. }
  BinaryAngle := 64;
{ Now convert to radians (about 1.57). }
  RadAngle = al_fixmul (BinaryAngle, AL_FIXTORAD_R);
...
end.
!)
@seealso(AL_FIXED) @seealso(al_fixmul) @seealso(AL_RADTOFIX_R)
#allegro5.AL_RADTOFIX_R
Example:
@longcode(!
var
  RadAngle, BinaryAngle: AL_FIXED;
begin
  BinaryAngle := al_fixmul (RadAngle, AL_RADTOFIX_R)
end.
!)
@seealso(AL_FIXED) @seealso(al_fixmul) @seealso(AL_FIXTORAD_R)

#allegro5.al_fixsqrt
If `x' is negative, @link(al_get_errno) is set to @link(AL_EDOM) and the function returns zero.
#allegro5.al_fixhypot
This should be better than calculating the formula yourself manually, since the error is much smaller.
#allegro5.al_fixatan
The input value must be a fixed point radian.  The inverse tangent is the value whose tangent is x.

Example:
@longcode(!
var
  InverseTangent: AL_FIXED;
begin
{ Sets InverseTangent to binary angle 13. }
  InverseTangent := al_fixatan (al_ftofix (0.326))
en.
!)
@return(The inverse tangent of a fixed point value, measured as a fixed point binary format angle.)
@seealso(al_fixtan) @seealso(al_fixatan2)
#allegro5.al_fixatan2
Computes the arc tangent of @code(y / x), but the signs of both arguments are used to determine the quadrant of the result, and @code(x) is permitted to be zero.  This function is useful to convert Cartesian coordinates to polar coordinates.

Example:
@longcode(!
var
  ResultValue: AL_FIXED;
begin
{ Sets ResultValue to binary angle 64. }
  ResultValue := al_fixatan2 (al_itofix (1), 0);
{ Sets ResultValue to binary angle -109. }
  ResultValue ::= al_fixatan2 (al_itofix (-1), al_itofix (-2));
{ Fails. }
  ResultValue := al_fixatan2 (0, 0);
  if al_get_errno <> 0 then Halt (-1)
end.
!)
@return(The arc tangent of y / x in fixed point binary format angle, from -128 to 128. If both x and y are zero, returns zero and sets Allegro's errno to @link(AL_EDOM).)
@seealso(al_fixtan) @seealso(al_fixatan)

#allegro5.al_ftofix
Unlike @link(al_itofix), this function clamps values which could overflow the type conversion, setting @link(al_get_errno) to non-zero in the process if this happens.
@seealso(al_itofix) @seealso(al_fixtof)
#allegro5.al_fixtof
@seealso(al_ftofix)

#allegro5.al_fixadd
Although fixed point numbers can be added with the normal '+' integer operator, that doesn't provide any protection against overflow.  If overflow is a problem, you should use this function instead.  It is slower than using integer operators, but if an overflow occurs it will set @link(al_get_errno) and clamp the result, rather than just letting it wrap.

Example:
@longcode(!
var
  Value: AL_FIXED;
begin
{ This will put 5035 into Value. }
  Value := al_fixadd (al_itofix (5000), al_itofix (35));
{ Sets errno and puts -32768 into Value. }
  Value := al_fixadd (al_itofix (-31000), al_itofix (-3000));
{ This will fail. }
  if al_get_errno <> 0 then Halt (-1)
end.
!)
@returns(The clamped result of adding x to y, setting Allegro's errno to @link(AL_ERANGE) if there was an overflow.)
@seealso(al_fixsub) @seealso(al_fixmul) @seealso(al_fixdiv)
#allegro5.al_fixsub
Although fixed point numbers can be substracted with the normal '-' integer operator, that doesn't provide any protection against overflow.  If overflow is a problem, you should use this function instead.  It is slower than using integer operators, but if an overflow occurs it will set @link(al_get_errno) and clamp the result, rather than just letting it wrap.

Example:
@longcode(!
var
  Value: AL_FIXED;
begin
{ This will put 4965 into Value. }
  Value := al_fixsub (al_itofix (5000), al_itofix (35));
{ Sets errno and puts -32768 into Value. }
  Value = al_fixsub (al_itofix (-31000), al_itofix (3000));
{ This will fail. }
  if al_get_errno <> 0 then Halt (-1)
end.
!)
@returns(The clamped result of substracting y from x, setting Allegro's errno to @link(AL_ERANGE) if there was an overflow.)
@seealso(al_fixadd) @seealso(al_fixmul) @seealso(al_fixdiv)
#allegro5.al_fixmul
A fixed point value can be multiplied or divided by an integer with the normal * and / operators.  To multiply two fixed point values, though, you must use this function.

Example:
@longcode(!
var
  Value: AL_FIXED;
begin
{ This will put 30000 into Value. }
  Value := al_fixmul (al_itofix (10), al_itofix (3000))
end.
!)
@return(The clamped result of multiplying x by y.)
@seealso(al_fixadd) @seealso(al_fixsub) @seealso(al_fixdiv)
#allegro5.al_fixdiv
A fixed point value can be divided by an integer with the normal / operator.  To divide two fixed point values, though, you must use this function.  If a division by zero occurs, Allegro's errno will be set and the maximum possible value will be returned, but errno is not cleared if the operation is successful.  This means that if you are going to test for division by zero you should call @code(@link(al_set_errno) @(0@)) before calling @code(al_fixdiv).

Example:

@longcode(!
var
  Value: AL_FIXED;
begin
{ This will put 0.06060 Value. }
  Value := al_fixdiv (al_itofix (2), al_itofix (33));
{ This will put 0 into Value. }
  Value := al_fixdiv (0, al_itofix (-30));
{ Sets errno and puts -32768 into Value. }
  Value := al_fixdiv (al_itofix (-100), al_itofix (0));
  if al_get_errno <> 0 then Halt (-1)
end.
!)
@return(The result of dividing x by y. If y is zero, returns the maximum possible fixed point value and sets Allegro's errno to @link(AL_ERANGE).)
@seealso(al_fixadd) @seealso(al_fixsub) @seealso(al_fixmul)

#allegro5.al_fixfloor
That is, it rounds towards negative infinity.

Example:
@longcode(!
var
  Number: AL_FIXED;
begin
{ This will put 33 into Number. }
  Number := al_fixfloor (al_itofix (100) / 3);
{ And this will round down to 16. }
  Number := al_fixfloor (al_itofix (100) / 6)
end.
!)
@seealso(al_fixtoi) @seealso(al_fixceil)
#allegro5.al_fixceil
That is, it rounds towards positive infinity.

Example:
@longcode(!
var
  Number: AL_FIXED;
begin
{ This will put 34 into Number. }
  Number := al_fixceil (al_itofix (100) / 3);
{ And this will round down to 17. }
  Number := al_fixceil (al_itofix (100) / 6)
end.
!)
@seealso(al_fixtoi) @seealso(al_fixfloor)
#allegro5.al_itofix
This is the same thing as @code(x shl 16).  Remember that overflows (trying to convert an integer greater than 32767) and underflows (trying to convert an integer lesser than -32768) are not detected even in debug builds!  The values simply "wrap around".

Example:
@longcode(!
var
  Number: AL_FIXED;
begin
{ This conversion is OK. }
  Number := al_itofix (100);
  if al_fixtoi (Number) <> 100 then Halt (-1);
{ This is not OK. }
  Number := al_itofix (64000);
  if al_fixtoi (Number) <> 64000 then Halt (-1)
end.
!)
@returns(The value of the integer converted to fixed point ignoring overflows.)
@seealso(al_fixtoi) @seealso(al_ftofix) @seealso(al_fixtof)
#allegro5.al_fixtoi)
In general, this is the same as @code(x shr 16) but this won't work with negative numbers.  In that case it is equivalent to @code(not @(@(not x@) shr 16@)).

Example:
@longcode(!
var
  Value: AL_FIXED;
begin
{ This will put 33 into Value. }
  Value := al_fixtoi (al_itofix (100) div 3);
{ But this will round up to 17. }
  Value := al_fixtoi (al_itofix (100) div 6)
end.
!)
@seealso(al_itofix) @seealso(al_fixtrunc)
#allegro5.al_fixtrunc
@seealso(al_fixtoi) @seealso(al_itofix)

#allegro5.al_fixcos
The input value must be a @html(<a href="introduction.html#fix_trig">fixed point binary angle</a>).

Example:
@longcode(!
var
  Angle: AL_FIXED;
  Value: Real;
begin
{ Set the binary angle to 45 degrees. }
  Angle := al_itofix (32);
{ The cosine of 45 degrees is about 0.7071. }
  Value := al_fixtof (al_fixcos (Angle));
  if not ((Value > 0.7) and (Value < 0.71)) then Halt (-1)
end.
!)
@return(The cosine of a fixed point binary format angle.)
@seealso(al_fixsin) @seealso(al_fixacos)
#allegro5.al_fixsin
The input value must be a @html(<a href="introduction.html#fix_trig">fixed point binary angle</a>).

Example:
@longcode(!
var
  Angle: AL_FIXED;
  Value: Real;
begin
{ Set the binary angle to 90 degrees. }
  Angle := al_itofix (64);
{ The sine of 90 degrees is about one. }
  Value := al_fixtof (al_fixsin (Angle));
  if Value <> 1 then Halt (-1)
end.
!)
@return(The cosine of a fixed point binary format angle.)
@seealso(al_fixcos) @seealso(al_fixasin)
#allegro5.al_fixtan
The input value must be a @html(<a href="introduction.html#fix_trig">fixed point binary angle</a>).

Example:
@longcode(!
var
  Angle: AL_FIXED, ResA, ResB;
  Dif: Real;
begin
  Angle := al_itofix (37);
{ Prove that tan (angle) = sin (angle) / cos (angle). }
  ResA := al_fixdiv (al_fixsin (Angle), al_fixcos (Angle));
  ResB := al_fixtan (Angle);
  Dif := al_fixtof (al_fixsub (ResA, ResB));
  WriteLn (Format ('Precision error: %f', [Dif]))
end.
!)
@return(The tangent of a fixed point binary format angle.)
@seealso(al_fixatan) @seealso(al_fixcos) @seealso(al_fixsin)
#allegro5.al_fixacos
The inverse cosine is defined only in the domain from -1 to 1.  Outside of this input range, the function will set Allegro's errno to @link(AL_EDOM) and return zero.

Example:
@longcode(!
var
  Value: AL_FIXED;
begin
{ Sets Value to binary angle 128. }
  Value = al_fixacos (al_itofix (-1))
end.
!)
@return(The inverse cosine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of range.  All return values of this function will be in the range 0 to 128.)
@seealso(al_fixcos) @seealso(al_get_errno)
#allegro5.al_fixasin
The inverse sine is defined only in the domain from -1 to 1.  Outside of this input range, the function will set Allegro's errno to @link(AL_EDOM) and return zero.

Example:
@longcode(!
var
  Angle: Real;
  Value: AL_FIXED;
begin
{ Sets Value to right binary angle (64). }
  Value = al_fixasin (al_itofix (1))
{ Sets Angle to 0.2405. }
  Angle := al_fixtof (al_fixmul (al_fixasin (al_ftofix (0.238)), AL_FIXTORAD_R));
{ This will trigger the if. }
  Value := al_fixasin (al_ftofix (-1.09));
  if al_get_errno <> 0 then Halt (-1)
end.
!)
@return(The inverse sine of a fixed point value, measured as fixed point binary format angle, or zero if the input was out of range.  All return values of this function will be in the range 0 to 128.)
@seealso(al_fixsin) @seealso(al_get_errno)



#allegro5.ALLEGRO_DISPLAY_MODE
Used for fullscreen mode queries.  Contains information about a supported fullscreen modes.
@member width Screen width.
@member height Screen height.
@member format The pixel format of the mode.  For an explanation of what does it mean, see @link(ALLEGRO_PIXEL_FORMAT).
@member refresh_rate The refresh rate of the mode. It may be zero if unknown.
@seealso(al_get_display_mode)

#allegro5.al_get_num_display_modes
Gets the number of available fullscreen display modes for the current set of display parameters. This will use the values set with @link(al_set_new_display_refresh_rate), and @link(al_set_new_display_flags) to find the number of modes that match. Setting the new display parameters to zero will give a list of all modes for the default driver.
@seealso(al_get_display_mode)
#allegro5.al_get_display_mode
Retrieves a fullscreen mode.  Display parameters should not be changed  between a call of @link(al_get_num_display_modes) and @code(al_get_display_mode).
@param(index Must be between 0 and the number returned from @code(al_get_num_display_modes - 1).)
@param(mode Must be an allocated @code(ALLEGRO_DISPLAY_MODE) structure.)
@return(@nil on failure, or a pointer to the @code(mode) parameter that was passed in on success.)
@seealso(ALLEGRO_DISPLAY_MODE) @seealso(al_get_num_display_modes)



#allegro5.ALLEGRO_JOYSTICK_STATE
This is a structure that is used to hold a @italic("snapshot") of a joystick's axes and buttons at a particular instant. All fields public and read-only. @seealso(al_get_joystick_state)

#allegro5.ALLEGRO_JOYFLAGS
@deprecated This is a holdover from the old API and may be removed. @seealso(al_get_joystick_stick_flags)
#allegro5.ALLEGRO_JOYFLAG_DIGITAL
The stick provides digital input.
#allegro5.ALLEGRO_JOYFLAG_ANALOGUE
The stick provides analogue input.

#allegro5.al_install_joystick
Installs a joystick driver, returning @true if successful.  If a joystick driver was already installed, returns @true immediately.
@seealso(al_uninstall_joystick)
#allegro5.al_uninstall_joystick
Uninstalls the active joystick driver. All outstanding @link(ALLEGRO_JOYSTICKptr) pointers are invalidated.  If no joystick driver was active, this function does nothing.

This function is automatically called when Allegro is shut down.
@seealso(al_install_joystick)
#allegro5.al_reconfigure_joysticks
Allegro is able to cope with users connecting and disconnected joystick devices on-the-fly. On existing platforms, the joystick event source will generate an event of type @code(ALLEGRO_EVENT_JOYSTICK_CONFIGURATION) when a device is plugged in or unplugged. In response, you should call @code(al_reconfigure_joysticks).

Afterwards, the number returned by @link(al_get_num_joysticks) may be different, and the handles returned by @link(al_get_joystick) may be different or be ordered differently.

All @link(ALLEGRO_JOYSTICKptr) handles remain valid, but handles for disconnected devices become inactive: their states will no longer update, and @link(al_get_joystick) will not return the handle. Handles for devices which remain connected will continue to represent the same devices. Previously inactive handles may become active again, being reused to represent newly connected devices.

It is possible that on some systems, Allegro won't be able to generate @code(ALLEGRO_EVENT_JOYSTICK_CONFIGURATION) events. If your game has an input configuration screen or similar, you may wish to call @code(al_reconfigure_joysticks) when entering that screen.
@return(@true if the joystick configuration changed, otherwise @false.)
@seealso(al_get_joystick_event_source) @seealso(ALLEGRO_EVENT)

#allegro5.al_get_num_joysticks
Returns the number of joysticks currently on the system (or potentially on the system). This number can change after @link(al_reconfigure_joysticks) is called, in order to support hotplugging.

Returns @code(0) if there is no joystick driver installed.
@seealso(al_get_joystick) @seealso(al_get_joystick_active)
#allegro5.al_get_joystick
Gets a handle for a joystick on the system. The number may be from @code(0) to @code(al_get_num_joysticks - 1). If successful a pointer to a joystick object is returned, which represents a physical device. Otherwise @nil is returned.

The handle and the index are only incidentally linked. After @code(al_reconfigure_joysticks) is called, @code(al_get_joystick) may return handles in a different order, and handles which represent disconnected devices will not be returned.
@seealso(al_get_num_joysticks) @seealso(al_reconfigure_joysticks) @seealso(al_get_joystick_active)
#allegro5.al_get_joystick_active
Returns if the joystick handle is "active", i.e. in the current configuration, the handle represents some physical device plugged into the system. @link(al_get_joystick) returns active handles. After reconfiguration, active handles may become inactive, and vice versa.
@seealso(al_reconfigure_joysticks)
#allegro5.al_get_joystick_name
Returns the name of the given joystick.
@seealso(al_get_joystick_stick_name) @seealso(al_get_joystick_axis_name)
@seealso(al_get_joystick_button_name)

#allegro5.al_get_joystick_num_sticks
Returns the number of "sticks" on the given joystick. A stick has one or more axes.
@seealso(al_get_joystick_num_axes) @seealso(al_get_joystick_num_buttons)
#allegro5.al_get_joystick_stick_flags
Returns the flags of the given "stick". If the stick doesn't exist, @nil is returned. Indices begin from @code(0).
@seealso(ALLEGRO_JOYFLAGS)
#allegro5.al_get_joystick_stick_name
Returns the name of the given "stick". If the stick doesn't exist, @nil is returned.
@seealso(al_get_joystick_axis_name) @seealso(al_get_joystick_num_sticks)

#allegro5.al_get_joystick_num_axes
Returns the number of axes on the given "stick". If the stick doesn't exist, @code(0) is returned.
@seealso(al_get_joystick_num_sticks)
#allegro5.al_get_joystick_axis_name
Returns the name of the given axis. If the axis doesn't exist, @nil is returned. Indices begin from @code(0).
@seealso(al_get_joystick_stick_name) @seealso(al_get_joystick_num_axes)

#allegro5.al_get_joystick_num_buttons
Returns the number of buttons on the joystick.
@seealso(al_get_joystick_num_sticks)
#allegro5.al_get_joystick_button_name
Returns the name of the given button. If the button doesn't exist, @nil is returned. Indices begin from @code(0).
@seealso(al_get_joystick_stick_name) @seealso(al_get_joystick_axis_name) @seealso(al_get_joystick_num_buttons)

#allegro5.al_get_joystick_state
Gets the current joystick state.
@seealso(ALLEGRO_JOYSTICK_STATE) @seealso(al_get_joystick_num_buttons) @seealso(al_get_joystick_num_axes)

#allegro5.al_get_joystick_event_source
Retrieves the global joystick event source. All joystick events are generated by this event source.
@seealso(al_register_event_source) @seealso(ALLEGRO_EVENT)


#allegro5.ALLEGRO_KEYBOARD_STATE
This is a structure that is used to hold a "snapshot" of keyboard at a particular instant.

You cannot read the state of keys directly. Use the function @link(al_key_down).
@seealso(al_get_keyboard_state)
@member display Points to the display that had keyboard focus at the time the state was saved. If no display was focused, this points to @nil.
#allegro5.al_install_keyboard
Installs a keyboard driver.
@returns(@true if successful.  If a driver was already installed, nothing happens and @true is returned.)
@seealso(al_uninstall_keyboard) @seealso(al_is_keyboard_installed)
#allegro5.al_uninstall_keyboard
Uninstalls the active keyboard driver, if any. This will automatically unregister the keyboard event source with any event queues.

This function is automatically called when Allegro is shut down.
@seealso(al_install_keyboard)

#allegro5.al_set_keyboard_leds
Overrides the state of the keyboard LED indicators. Set @code(leds) to a combination of the keyboard modifier flags to enable the corresponding LED indicators (@code(ALLEGRO_KEYMOD_NUMLOCK), @code(ALLEGRO_KEYMOD_CAPSLOCK) and @code(ALLEGRO_KEYMOD_SCROLLLOCK) are supported) or to @code(-1) to return to default behavior.
@return(@false if the current keyboard driver cannot set LED.)

#allegro5.al_get_keyboard_state
Saves the state of the keyboard specified at the time the function is called into @code(ret_state).
@seealso(al_key_down) @seealso(ALLEGRO_KEYBOARD_STATE)
#allegro5.al_clear_keyboard_state
Clears the state of the keyboard, emitting @link(ALLEGRO_EVENT_KEY_UP) for each currently pressed key. The given display is regarded as the one which had the keyboard focus when the event occurred. In case display is @nil no event is emitted. For most keyboard drivers Allegro maintains its own state of the keyboard, which might get out of sync with the real one. This function is intended to remedy such situation by resetting Allegro's keyboard state to a known default (no key pressed). This is particularly useful in response to @link(ALLEGRO_EVENT_DISPLAY_SWITCH_OUT) events.

@bold(Unstable API:) This is a new feature and the exact semantics are still being decided upon.
@seealso(al_get_keyboard_state) @seealso(ALLEGRO_KEYBOARD_STATE)
#allegro5.al_key_down
Returns @true if the key specified was held down in the state specified.
@seealso(ALLEGRO_KEYBOARD_STATE)

#allegro5.al_get_keyboard_event_source
Retrieves the keyboard event source. All keyboard events are generated by this event source.
@return(@nil if the keyboard subsystem was not installed.)
@seealso(al_register_event_source) @seealso(ALLEGRO_EVENT)



#allegro5.ALLEGRO_MOUSE_STATE
Stores mouse state.  Fields are read-only.
@seealso(al_get_mouse_state) @seealso(al_get_mouse_state_axis) @seealso(al_mouse_button_down)
@member x Mouse X position.
@member y Mouse Y position.
@member z Mouse weel position (2D @italic(ball)).
@member w Mouse weel position (2D @italic(ball)).
@member buttons Mouse buttons bitfield. The zeroth bit is set if the primary mouse button is held down, the first bit is set if the secondary mouse button is held down, and so on.
@member pressure Pressure, ranging from 0.0 to 1.0.
@member display Pointer to the display.

#allegro5.al_install_mouse
Installs mouse driver.
@return(@true if successful.  If a driver was already installed, nothing happens and @true is returned.)
@seealso(al_uninstall_mouse) @seealso(al_is_mouse_installed)
#allegro5.al_uninstall_mouse
Uninstalls the active mouse driver, if any. This will automatically unregister the mouse event source with any event queues.

This function is automatically called when Allegro is shut down.
@seealso(al_install_mouse)
#allegro5.al_get_mouse_num_buttons
Returns the number of buttons on the mouse. The first button is 1.
@seealso(al_get_mouse_num_axes)
#allegro5.al_get_mouse_num_axes
Returns the number of axes on the mouse. The first axis is 0.
@seealso(al_get_mouse_num_buttons)
#allegro5.al_set_mouse_xy
Tryes to position the mouse at the given coordinates on the given display. The mouse movement resulting from a successful move will generate an @link(ALLEGRO_EVENT_MOUSE_WARPED) event.
@return(@true on success, @false on failure.)
@seealso(al_set_mouse_z) @seealso(al_set_mouse_w)
#allegro5.al_set_mouse_z
Sets the mouse wheel position to the given value.
@return(@true on success, @false on failure.)
@seealso(al_set_mouse_xy) @seealso(al_set_mouse_w)
#allegro5.al_set_mouse_w
Sets the second mouse wheel position to the given value.
@return(@true on success, @false on failure.)
@seealso(al_set_mouse_xy) @seealso(al_set_mouse_z)
#allegro5.al_set_mouse_axis
Sets the given mouse axis to the given value.

The axis number must not be 0 or 1, which are the X and Y axes. Use @code(al_set_mouse_xy) for that.
@returns(@true on success, @false on failure.)
@seealso(al_set_mouse_xy) @seealso(al_set_mouse_z) @seealso(al_set_mouse_w)
#allegro5.al_get_mouse_state
Saves the state of the mouse specified at the time the function is called into @code(ret_state).

Example:
@longcode(!
VAR
  State: ALLEGRO_MOUSE_STATE;
BEGIN
  al_get_mouse_state (State);
  IF (State.buttons AND 1) <> 0 THEN
  { Primary (e.g. left) mouse button is held. }
    WriteLn (Format ('Mouse position: (%d, %d)', [State.x, State.y]));
  IF (State.buttons AND 2) <> 0 THEN
  { Secondary (e.g. right) mouse button is held. }
    ;
  IF (State.buttons AND 4) <> 0 THEN
  { Tertiary (e.g. middle) mouse button is held. }
    ;
END.
!)
@seealso(ALLEGRO_MOUSE_STATE) @seealso(al_get_mouse_state_axis) @seealso(al_mouse_button_down)
#allegro5.al_mouse_button_down
Returns @true if the mouse button specified was held down in the state specified. Unlike most things, the first mouse button is numbered 1.
@seealso(ALLEGRO_MOUSE_STATE) @seealso(al_get_mouse_state) @seealso(al_get_mouse_state_axis)
#allegro5.al_get_mouse_state_axis
Extracts the mouse axis value from the saved state. The axes are numbered from 0, in this order: x-axis, y-axis, z-axis, w-axis.
@seealso(ALLEGRO_MOUSE_STATE) @seealso(al_get_mouse_state) @seealso(al_mouse_button_down)
#allegro5.al_get_mouse_cursor_position
On platforms where this information is available, this function returns the global location of the mouse cursor, relative to the desktop. You should not normally use this function, as the information is not useful except for special scenarios as moving a window.
@return(@true on success, @false on failure.)
#allegro5.al_grab_mouse
Confines the mouse cursor to the given display. The mouse cursor can only be confined to one display at a time.

Do not assume that the cursor will remain confined until you call @link(al_ungrab_mouse). It may lose the confined status at any time for other reasons.

@bold(Note)

not yet implemented on Mac OS X.
@return(@true if successful, otherwise returns @false.)
@seealso(al_ungrab_mouse)
#allegro5.al_ungrab_mouse
Stop confining the mouse cursor to any display belonging to the program.

@bold(Note)

not yet implemented on Mac OS X.
@seealso(al_grab_mouse)
#allegro5.al_set_mouse_wheel_precision
Sets the precision of the mouse wheel (the z and w coordinates). This precision manifests itself as a multiplier on the @code(dz) and @code(dw) fields in mouse events. It also affects the @code(z) and @code(w) fields of events and @link(ALLEGRO_MOUSE_STATE), but not in a simple way if you alter the precision often, so it is suggested to reset those axes to @code(0) when you change precision. Setting this to a high value allows you to detect small changes in those two axes for some high precision mice. A flexible way of using this precision is to set it to a high value (120 is likely sufficient for most, if not all, mice) and use a floating point @code(dz) and @code(dw) like so:
@longcode(!
VAR
  Event: ALLEGRO_EVENT;
  dz := DOUBLE;
BEGIN
  al_set_mouse_wheel_precision (120);
  al_wait_for_event (EventQueue, Event);
  IF Event.ftype = ALLEGRO_EVENT_MOUSE_AXES THEN
  BEGIN
    dz := Event.mouse.dz / al_get_mouse_wheel_precision ();
  { Use dz in some way... }
  END;
END.
!)
Precision is set to 1 by default. It is impossible to set it to a lower precision than that.
@seealso(al_get_mouse_wheel_precision)
#allegro5.al_get_mouse_wheel_precision
Gets the precision of the mouse wheel (the z and w coordinates).
@seealso(al_set_mouse_wheel_precision)

#allegro5.al_get_mouse_event_source
Retrieve the mouse event source. All mouse events are generated by this event source.
@return(@nil if the mouse subsystem was not installed.)
@seealso(al_register_event_source) @seealso(ALLEGRO_EVENT_MOUSE_AXES)



#allegro5.ALLEGRO_MEMORY_INTERFACE
Used to define the memory management functions.
@seealso(al_set_memory_interface)

#allegro5.al_set_memory_interface
Overrides the memory management functions with implementations of @link(al_malloc_with_context), @link(al_free_with_context), @link(al_realloc_with_context) and @link(al_calloc_with_context). The context arguments may be used for debugging. The new functions should be thread safe.
@seealso(ALLEGRO_MEMORY_INTERFACE) @seealso(al_restore_memory_interface)
#allegro5.al_restore_memory_interface
Restores the default behavior of the memory management functions.
@seealso(al_set_memory_interface)

#allegro5.al_malloc
Like @code(GetMem), reserves @code(n) bytes memory on heap and returns a pointer to this memory.  The implementation may be overriden.

Memory allocated with this function @bold(must) be released by @link(al_free).
@seealso(al_free) @seealso(al_realloc) @seealso(al_calloc)
@seealso(al_malloc_with_context) @seealso(al_set_memory_interface)
#allegro5.al_free
Like @code(FreeMem), releases the memory occupied by pointer @code(p).  The implementation may be overriden.

Additionally, on Windows, a memory block allocated by one DLL must be freed from the same DLL. In the few places where an Allegro function returns a pointer that @bold(must) be freed, you must use @code(al_free) for portability to Windows.
@seealso(al_malloc) @seealso(al_free_with_context)
#allegro5.al_realloc
Like @code(ReAllocMem), resizes the memory pointed to by @code(p) so it has size @code(n). The value of @code(p) may change during this operation.  The contents of the memory pointed to by @code(p) (if any) will be copied to the new location, but may be truncated if the newly allocated memory block is smaller in size. If a larger block is allocated, only the used memory is initialized, extra memory will not be zeroed out.  The implementation may be overriden.
@seealso(al_malloc) @seealso(al_realloc_with_context)
#allegro5.al_calloc
Like @code(GetMem), reserves memory enough to store @code(c) elements of @code(n) bytes each on heap and returns a pointer to this memory.  The implementation may be overriden.
@seealso(al_free) @seealso(al_realloc) @seealso(al_malloc)
@seealso(al_calloc_with_context) @seealso(al_set_memory_interface)

#allegro5.al_malloc_with_context
This reserves memory for the Allegro library (this matters on Windows), unless overridden with @link(al_set_memory_interface).

Generally you should use the @link(al_malloc) function.
#allegro5.al_free_with_context
This releases the memory reserved by the Allegro library (this matters on Windows), unless overridden with @link(al_set_memory_interface).

Generally you should use the @link(al_free) function.
#allegro5.al_realloc_with_context
This reserves memory for the Allegro library (this matters on Windows), unless overridden with @link(al_set_memory_interface).

Generally you should use the @link(al_realloc) function.
#allegro5.al_calloc_with_context
This reserves memory for the Allegro library (this matters on Windows), unless overridden with @link(al_set_memory_interface).

Generally you should use the @link(al_calloc) function.



#allegro5.ALLEGRO_MONITOR_INFO
Describes a monitor's size and position relative to other monitors. @code(x1, y1) will be @code(0, 0) on the primary display. Other monitors can have negative values if they are to the left or above the primary display. @code(x2, y2) are the coordinates one beyond the bottom right pixel, so that @code(x2 - x1) gives the width and @code(y2 - y1) gives the height of the display.
@seealso(al_get_monitor_info)

#allegro5.al_get_num_video_adapters
Gets the number of video "adapters" attached to the computer. Each video card attached to the computer counts as one or more adapters. An adapter is thus really a video port that can have a monitor connected to it.

On Windows, use @link(al_set_new_display_flags) to switch between Direct3D and OpenGL backends, which will often have different adapters available.
@seealso(al_get_monitor_info)
#allegro5.al_get_monitor_info
Gets information about a monitor's position on the desktop. adapter is a number from 0 to @code(al_get_num_video_adapters - 1).

On Windows, use @link(al_set_new_display_flags) to switch between Direct3D and OpenGL backends, which will often have different adapters available.
@return(@true on success, @false on failure.)
@seealso(ALLEGRO_MONITOR_INFO) @seealso(al_get_num_video_adapters)



#allegro5.ALLEGRO_SYSTEM_MOUSE_CURSOR
Used to identify the mouse cursor. @seealso(al_set_system_mouse_cursor)

#allegro5.al_create_mouse_cursor
Creates a mouse cursor from the bitmap provided.
@param(x_focus Describes the bit of the cursor that will represent the actual mouse position.)
@param(y_focus Describes the bit of the cursor that will represent the actual mouse position.)
@return(A pointer to the cursor on success, or @nil on failure.)
@seealso(al_set_mouse_cursor) @seealso(al_destroy_mouse_cursor)
#allegro5.al_destroy_mouse_cursor
Frees the memory used by the given cursor.

It has no effect if @code(cursor) is @nil.
@seealso(al_create_mouse_cursor)
#allegro5.al_set_mouse_cursor
Sets the given mouse cursor to be the current mouse cursor for the given display.

If the cursor is currently 'shown' (as opposed to 'hidden') the change is immediately visible.
@return(@true on success, @false on failure.)
@seealso(al_set_system_mouse_cursor) @seealso(al_show_mouse_cursor) @seealso(al_hide_mouse_cursor)
#allegro5.al_set_system_mouse_cursor
Sets the given system mouse cursor to be the current mouse cursor for the given @code(display). If the cursor is currently 'shown' (as opposed to 'hidden') the change is immediately visible.

If the cursor doesn't exist on the current platform another cursor will be silently be substituted.
@returns(@true on success, @false on failure.)
@seealso(ALLEGRO_SYSTEM_MOUSE_CURSOR) @seealso(al_set_mouse_cursor) @seealso(al_show_mouse_cursor) @seealso(al_hide_mouse_cursor)
#allegro5.al_show_mouse_cursor
Makes a mouse cursor visible in the given display.
@return(@true if a mouse cursor is shown as a result of the call @(or one already was visible@), @false otherwise.)
@seealso(al_hide_mouse_cursor)
#allegro5.al_hide_mouse_cursor
Hides the mouse cursor in the given display. This has no effect on what the current mouse cursor looks like; it just makes it disappear.
@return(@true on success @(or if the cursor already was hidden@), @false otherwise.)
@seealso(al_show_mouse_cursor)



#allegro5.ALLEGRO_RENDER_STATE
Possible render states which can be set with @link(al_set_render_state).
#allegro5.ALLEGRO_ALPHA_TEST
If this is set to 1, the values of @code(ALLEGRO_ALPHA_FUNCTION) and @code(ALLEGRO_ALPHA_TEST_VALUE) define a comparison function which is performed for each pixel. Only if it evaluates to true the pixel is written. Otherwise no subsequent processing @(like depth test or blending@) is performed.
#allegro5.ALLEGRO_WRITE_MASK
This determines how the framebuffer and depthbuffer are updated whenever a pixel is written @(in case alpha and/or depth testing is enabled: after all such enabled tests succeed@). Depth values are only written if  @code(ALLEGRO_DEPTH_TEST) is 1, in addition to the write mask flag being set.
#allegro5.ALLEGRO_DEPTH_TEST
If this is set to 1, compare the depth value of any newly written pixels with the depth value already in the buffer, according to @code(ALLEGRO_DEPTH_FUNCTION). Allegro primitives with no explicit z coordinate will write a value of 0 into the depth buffer.
#allegro5.ALLEGRO_DEPTH_FUNCTION
One of the next values: @code(ALLEGRO_RENDER_NEVER) @code(ALLEGRO_RENDER_ALWAYS) @code(ALLEGRO_RENDER_LESS) @code(ALLEGRO_RENDER_EQUAL) @code(ALLEGRO_RENDER_LESS_EQUAL) @code(ALLEGRO_RENDER_GREATER) @code(ALLEGRO_RENDER_NOT_EQUAL) @code(ALLEGRO_RENDER_GREATER_EQUAL), only used when @code(ALLEGRO_DEPTH_TEST) is 1.
#allegro5.ALLEGRO_ALPHA_FUNCTION
One of the next values: @code(ALLEGRO_RENDER_NEVER) @code(ALLEGRO_RENDER_ALWAYS) @code(ALLEGRO_RENDER_LESS) @code(ALLEGRO_RENDER_EQUAL) @code(ALLEGRO_RENDER_LESS_EQUAL) @code(ALLEGRO_RENDER_GREATER) @code(ALLEGRO_RENDER_NOT_EQUAL) @code(ALLEGRO_RENDER_GREATER_EQUAL), only used when @code(ALLEGRO_ALPHA_TEST) is 1.
#allegro5.ALLEGRO_ALPHA_TEST_VALUE
Only used when @code(ALLEGRO_ALPHA_TEST) is 1.

#allegro5.al_set_render_state
Sets one of several render attributes.

This function does nothing if the target bitmap is a memory bitmap.
@param(state Possible render states which can be one of @link(ALLEGRO_RENDER_STATE).)
@param(value Value to apply to the given @code(state).)



#allegro5.ALLEGRO_TRANSFORM
Defines the generic transformation type, a 4x4 matrix. 2D transforms use only a small subsection of this matrix, namely the top left 2x2 matrix, and the right most 2x1 matrix, for a total of 6 values.
@member m A 4x4 float matrix.

#allegro5.al_use_transform
Sets the transformation to be used for the the drawing operations on the target bitmap (each bitmap maintains its own transformation). Every drawing operation after this call will be transformed using this transformation. Call this function with an identity transformation to return to the default behaviour.

This function does nothing if there is no target bitmap.

The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables.
@longcode(!
PROCEDURE SetupMyTransformation;
VAR
  Transform: ALLEGRO_TRANSFORM;
BEGIN
  al_translate_transform (Transform, 5, 10);
  al_use_transform (Transform)
END;
!)
@param(trans Transformation to use.)
@seealso(al_get_current_transform) @seealso(al_transform_coordinates)
#allegro5.al_use_projection_transform
Sets the projection transformation to be used for the the drawing operations on the target bitmap (each bitmap maintains its own projection transformation). Every drawing operation after this call will be transformed using this transformation. To return default behavior, call this function with an orthographic transform like so:
@longcode(!
VAR
  Trans: ALLEGRO_TRANSFORM;
BEGIN
  al_identity_transform (Trans);
  al_orthographic_transform (
    Trans,
    0, 0, -1.0,
    al_get_bitmap_width (Bitmap), al_get_bitmap_height (Bitmap), 1.0
  );
  al_set_target_bitmap (Bitmap);
  al_use_projection_transform (trans)
END;
!)
The orthographic transformation above is the default projection transform.

This function does nothing if there is no target bitmap. This function also does nothing if the bitmap is a memory bitmap (i.e. memory bitmaps always use an orthographic transform like the snippet above). Note that the projection transform will be reset to default if a video bitmap is converted to a memory bitmap. Additionally, if the bitmap in question is the backbuffer, it's projection transformation will be reset to default if it is resized. Lastly, when you draw a memory bitmap to a video bitmap with a custom projection transform, this transformation will be ignored (i.e. it'll be as if the projection transform of the target bitmap was temporarily reset to default).

The parameter is passed by reference as an optimization to avoid the overhead of stack copying. The reference will not be stored in the Allegro library so it is safe to pass references to local variables.
@seealso(al_get_current_projection_transform)
#allegro5.al_copy_transform
Makes a copy of a transformation.
@param(src Source transformation.)
@param(dest Destination transformation.)
#allegro5.al_identity_transform
Sets the transformation to be the identity transformation. This is the default transformation. Use @link(al_use_transform) on an identity transformation to return to the default.
@longcode(!
VAR
  T: ALLEGRO_TRANSFORM;
BEGIN
  al_identity_transform (T);
  al_use_transform (T)
END;
!)
@param(trans Transformation to alter.)
@seealso(al_translate_transform) @seealso(al_rotate_transform) @seealso(al_scale_transform) @seealso(al_transpose_transform)
#allegro5.al_build_transform
Builds a transformation given some parameters. This call is equivalent to calling the transformations in this order: make identity, rotate, scale, translate. This method is faster, however, than actually calling those functions.

@bold(Note)

this function was previously documented to be equivalent to a different (and more useful) order of operations: identity, scale, rotate, translate.
@param(trans Transformation to alter.)
@param(x Horizontal translation.)
@param(y Vertical translation.)
@param(sx Horizontal scale.)
@param(sy Vertical scale.)
@param(theta Rotation angle in radians:)
@seealso(al_identity_transform) @seealso(al_translate_transform) @seealso(al_rotate_transform) @seealso(al_scale_transform) @seealso(al_compose_transform)
#allegro5.al_build_camera_transform
Builds a transformation which can be used to transform 3D coordinates in world space to camera space. This involves translation and a rotation. The function expects three coordinate triplets: The camera's position, the position the camera is looking at and an up vector. The up vector does not need to be of unit length and also does not need to be perpendicular to the view direction - it can usually just be the world up direction (most commonly 0/1/0).

For example:
@longcode(!
al_build_camera_transform (
    T,
    1, 1, 1,
    5, 5, 5,
    0, 1, 0
);
!)
This create a transformation for a camera standing at 1/1/1 and looking towards 5/5/5.

@bold(Note:) If the position and look parameters are identical, or if the up direction is parallel to the view direction, an identity matrix is created.

Another example which will simply re-create the identity matrix:
@longcode(!
al_build_camera_transform (
    T,
    0, 0,  0,
    0, 0, -1,
    0, 1,  0
);
!)
An example where the up vector will cause the camera to lean (roll) by 45 degrees:
@longcode(!
al_build_camera_transform (
    T,
    1, 1, 1,
    5, 5, 5,
    1, 1, 0
);
!)
@seealso(al_identity_transform) @seealso(al_translate_transform_3d) @seealso(al_rotate_transform_3d) @seealso(al_scale_transform_3d) @seealso(al_compose_transform) @seealso(al_use_transform)
#allegro5.al_translate_transform
Applies a translation to a transformation.
@param(trans Transformation to alter.)
@param(x Horizontal translation.)
@param(y Vertical translation.)
@seealso(al_identity_transform) @seealso(al_rotate_transform) @seealso(al_scale_transform) @seealso(al_build_transform)
#allegro5.al_translate_transform_3d
Combines the given transformation with a transformation which translates coordinates by the given vector.
@seealso(al_identity_transform) @seealso(al_use_projection_transform)
#allegro5.al_rotate_transform
Applies a rotation to a transformation.
@param(trans Transformation to alter.)
@param(theta Rotation angle in radians.)
@seealso(al_identity_transform) @seealso(al_translate_transform) @seealso(al_scale_transform) @seealso(al_build_transform)
#allegro5.al_rotate_transform_3d
Combines the given transformation with a transformation which rotates coordinates around the given vector by the given angle in radians.

Note: The vector is assumed to be of unit length (otherwise it will also incur a scale).
@seealso(al_identity_transform) @seealso(al_rotate_transform)
#allegro5.al_scale_transform
Applies a scale to a transformation.
@param(trans Transformation to alter.)
@param(sx Horizontal scale.)
@param(sy Vertical scale.)
@seealso(al_identity_transform) @seealso(al_translate_transform) @seealso(al_rotate_transform) @seealso(al_build_transform)
#allegro5.al_scale_transform_3d
Combines the given transformation with a transformation which scales coordinates by the given vector.
@seealso(al_identity_transform) @seealso(al_use_projection_transform)
#allegro5.al_transform_coordinates
Transforms a pair of coordinates.
@param(trans Transformation to use.)
@param(x Horizontal coordinate.)
@param(y Vertical coordinate.)
@seealso(al_identity_transform) @seealso(al_use_transform) @seealso(al_transform_coordinates_3d)
#allegro5.al_transform_coordinates_3d
Transforms x, y, z coordinates.

Note: If you are using a projection transform you most likely will want to use al_transform_coordinates_3d_projective instead.
@param(trans Transformation to use.)
@param(x Horizontal coordinate.)
@param(y Vertical coordinate.)
@param(z Depth coordinate.)
@seealso(al_identity_transform) @seealso(al_use_transform) @seealso(al_transform_coordinates)
#allegro5.al_transform_coordinates_4d
Transforms x, y, z, w coordinates.
@param(trans Transformation to use.)
@param(x Horizontal coordinate.)
@param(y Vertical coordinate.)
@param(z Depth coordinate.)
@param(w W coordinate.)
@seealso(al_identity_transform) @seealso(al_use_transform) @seealso(al_transform_coordinates) @seealso(al_transform_coordinates_3d)
#allegro5.al_transform_coordinates_3d_projective
Transforms @code(x), @code(y), @code(z) as homogeneous coordinates. This is the same as using @link(al_transform_coordinates_4d) with the @code(w) coordinate set to 1, then dividing @code(x), @code(y), @code(z) by the resulting @code(w). This will provide the same coordinates Allegro will draw to when a projective transform is in effect as set with al_use_projection_transform.
@param(trans Transformation to use.)
@param(x Horizontal coordinate.)
@param(y Vertical coordinate.)
@param(z Depth coordinate.)
@seealso(al_identity_transform) @seealso(al_use_transform) @seealso(al_transform_coordinates) @seealso(al_transform_coordinates_3d) @seealso(al_use_projection_transform)
#allegro5.al_compose_transform
Composes (combine) two transformations by a matrix multiplication.
@longcode(!
trans := trans other
!)
Note that the order of matrix multiplications is important. The effect of applying the combined transform will be as if first applying @code(trans) and then applying @code(other) and not the other way around.
@param(trans ransformation to alter.)
@param(other ransformation used to transform trans.)
@seealso(al_identity_transform) @seealso(al_translate_transform) @seealso(al_rotate_transform) @seealso(al_scale_transform)
#allegro5.al_get_current_transform
Returns the transformation of the current target bitmap, as set by @link(al_use_transform). If there is no target bitmap, this function returns @nil.
@return(A pointer to the current transformation.)
@seealso(al_get_current_projection_transform)
#allegro5.al_get_current_inverse_transform
Returns the inverse of the current transformation of the target bitmap. If there is no target bitmap, this function returns @nil.

This is similar to calling @code(@link(al_invert_transform) @(@link(al_get_current_transform)^@)) but the result of this function is cached.

@bold(Note)

Allegro's transformation inversion functions work correctly only with 2D transformations.
#allegro5.al_get_current_projection_transform(void)
Returns a pointer to the current projection transformation.  If there is no target bitmap, this function returns @nil.
@seealso(al_use_projection_transform)
#allegro5.al_invert_transform
Inverts the passed transformation. If the transformation is nearly singular (close to not having an inverse) then the returned transformation may be invalid. Use @link(al_check_inverse) to ascertain if the transformation has an inverse before inverting it if you are in doubt.

@bold(Note)

Allegro's transformation inversion functions work correctly only with 2D transformations.
@param(trans Transformation to invert.)
@seealso(al_identity_transform) @seealso(al_check_inverse) @seealso(al_transpose_transform)
#allegro5.al_transpose_transform
Transposes the matrix of the given transform. This can be used for inversing a rotation transform. For example:
@longcode(#
al_build_camera_transform (camera, 0, 0, 0, x, y, z, xu, yu, zu)
al_copy_transform (inverse, camera)
al_transpose_transform (camera)
{ Now "inverse" will be a transformation rotating in the opposite
  direction from "camera". Note that this only works if the camera
  position is 0/0/0 as in the example. }
#)
@seealso(al_identity_transform)
#allegro5.al_check_inverse
Checks if the transformation has an inverse using the supplied tolerance. Tolerance should be a small value between 0 and 1, with 1e-7 being sufficient for most applications.

In this function tolerance specifies how close the determinant can be to 0 (if the determinant is 0, the transformation has no inverse). Thus the smaller the tolerance you specify, the "worse" transformations will pass this test. Using a tolerance of 1e-7 will catch errors greater than 1/1000's of a pixel, but let smaller errors pass. That means that if you transformed a point by a transformation and then transformed it again by the inverse transformation that passed this check, the resultant point should less than 1/1000's of a pixel away from the original point.

Note that this check is superfluous most of the time if you never touched the transformation matrix values yourself. The only thing that would cause the transformation to not have an inverse is if you applied a 0 (or very small) scale to the transformation or you have a really large translation. As long as the scale is comfortably above 0, the transformation will be invertible.

@bold(Note)

Allegro's transformation inversion functions work correctly only with 2D transformations.
@param(trans Transformation to check.)
@param(tol Tolerance.)
@return(@true if the transformation is invertible, @false otherwise.)
@seealso(al_invert_transform)
#allegro5.al_orthographic_transform
Combines the given transformation with an orthographic transformation which maps the screen rectangle to the given left/top and right/bottom coordinates.

near/far is the z range, coordinates outside of that range will get clipped. Normally -1/1 is fine because all 2D graphics will have a z coordinate of 0. However if you for example do @code(al_draw_rectangle (0, 0, 100, 100)) and rotate around the x axis ("towards the screen") make sure your z range allows values from -100 to 100 or the rotated rectangle will get clipped.

Also, if you are using a depth buffer the z range decides the depth resolution. For example if you have a 16 bit depth buffer there are only 65536 discrete depth values. So if your near/far is set to -1000000/1000000 most of the z positions would not result in separate depth values which could lead to artifacts.
@seealso(al_use_projection_transform) @seealso(al_perspective_transform)
#allegro5.al_perspective_transform
Like @link(al_orthographic_transform) but honors perspective. If everything is at a z-position of -near it will look the same as with an orthographic transformation.

To use a specific horizontal field of view you can use the relation:
@preformatted(!
tan(hfov / 2) = (right - left) / 2 / near
!)
@seealso(al_use_projection_transform) @seealso(al_orthographic_transform)
#allegro5.al_horizontal_shear_transform(ALLEGRO_TRANSFORM* trans, float theta)
Applies a horizontal shear to the transform
@param(trans Transformation to alter.)
@param(theta Rotation angle in radians.)
@seealso(al_vertical_shear_transform)
#allegro5.al_vertical_shear_transform
Applies a vertical shear to the transform
@param(trans Transformation to alter.)
@param(theta Rotation angle in radians.)
@seealso(al_horizontal_shear_transform)



#allegro5.ALLEGRO_SHADERptr
Pointer to an @code(ALLEGRO_SHADER).

An @code(ALLEGRO_SHADER) is a program that runs on the GPU.  It combines both a vertex and a pixel shader. (In OpenGL terms, an @code(ALLEGRO_SHADER) is actually a program which has one or more shaders attached. This can be confusing.)

The source code for the underlying vertex or pixel shader can be provided either as GLSL or HLSL, depending on the value of @link(ALLEGRO_SHADER_PLATFORM) used when creating it.
@seealso(al_create_shader)
#allegro5.ALLEGRO_SHADER_TYPE
Used with @link(al_attach_shader_source) and @link(al_attach_shader_source_file) to specify how to interpret the attached source.
#allegro5.ALLEGRO_VERTEX_SHADER
A vertex shader is executed for each vertex it is used with. The program will output exactly one vertex at a time.

When Allegro's graphics are being used then in addition to all vertices of primitives from the primitives addon, each drawn bitmap also consists of four vertices.
#allegro5.ALLEGRO_PIXEL_SHADER
A pixel shader is executed for each pixel it is used with.  The program will output exactly one pixel at a time - either in the backbuffer or in the current target bitmap.

With Allegro's builtin graphics this means the shader is for example called for each destination pixel of the output of an @link(al_draw_bitmap) call.

A more accurate term for pixel shader would be fragment shader since one final pixel in the target bitmap is not necessarily composed of only a single output but of multiple fragments (for example when multi-sampling is being used).
#allegro5.ALLEGRO_SHADER_PLATFORM
The underlying platform which the @link(ALLEGRO_SHADERptr) is built on top of, which dictates the language used to program the shader.

#allegro5.al_create_shader
Creates a shader object.

The platform argument is one of the @link(ALLEGRO_SHADER_PLATFORM) values,
and specifies the type of shader object to create, and which language is
used to program the shader.

The shader platform must be compatible with the type of display that you
will use the shader with.  For example, you cannot create and use a HLSL
shader on an OpenGL display, nor a GLSL shader on a Direct3D display.

The @code(ALLEGRO_SHADER_AUTO) value automatically chooses the appropriate
platform for the display currently targeted by the calling thread; there
must be such a display.  It will create a GLSL shader for an OpenGL
display, and a HLSL shader for a Direct3D display.
@return(A pointer to the shader object on success. Otherwise, returns @nil.)
@seealso(al_attach_shader_source) @seealso(al_attach_shader_source_file)
@seealso(al_build_shader) @seealso(al_use_shader)
@seealso(al_destroy_shader) @seealso(al_get_shader_platform)
#allegro5.al_attach_shader_source
Attaches the shader's source code to the shader object and compiles it. Passing @nil deletes the underlying (OpenGL or DirectX) shader.  See also @link(al_attach_shader_source_file) if you prefer to obtain your shader source from an external file.

If you do not use @code(ALLEGRO_PROGRAMMABLE_PIPELINE) Allegro's graphics functions will not use any shader specific functions themselves. In case of a system with no fixed function pipeline (like OpenGL ES 2 or OpenGL 3 or 4) this means Allegro's drawing functions cannot be used.

TODO: Is @code(ALLEGRO_PROGRAMMABLE_PIPELINE) set automatically in this case?

When @code(ALLEGRO_PROGRAMMABLE_PIPELINE) is used the following shader uniforms are provided by Allegro and can be accessed in your shaders:
@definitionlist(
 @itemlabel(@bold(al_projview_matrix)) @item(matrix for Allegro's orthographic
      projection multiplied by the al_use_transform matrix. The type is
      @code(mat4) in GLSL, and @code(float4x4) in HLSL.)
 @itemlabel(@bold(al_use_tex)) @item(whether or not to use the bound texture. The type
      is @code(bool) in both GLSL and HLSL.)
 @itemlabel(@bold(al_tex)) @item(the texture if one is bound. The type is
      @code(sampler2D) in GLSL and @code(texture) in HLSL.)
 @itemlabel(@bold(al_use_tex_matrix)) @item(whether or not to use a texture matrix
      @(used by the primitives addon@). The type is @code(bool) in both GLSL
      and HLSL.)
 @itemlabel(@bold(al_tex_matrix)) @item(the texture matrix @(used by the primitives
      addon@). Your shader should multiply the texture coordinates by this
      matrix. The type is @code(mat4) in GLSL, and @code(float4x4) in HLSL.)
)

For GLSL shaders the vertex attributes are passed using the following variables:
@definitionlist(
 @itemlabel(@bold(al_pos)) @item(vertex position attribute. Type is @code(vec4).)
 @itemlabel(@bold(al_texcoord)) @item(vertex texture coordinate attribute. Type is @code(vec2).)
 @itemlabel(@bold(al_color)) @item(vertex color attribute. Type is @code(vec4).)
)

For HLSL shaders the vertex attributes are passed using the following semantics:
@definitionlist(
 @itemlabel(@bold(POSITION0)) @item(vertex position attribute. Type is @code(float4).)
 @itemlabel(@bold(TEXCOORD0)) @item(vertex texture coordinate attribute. Type is @code(float2).)
 @itemlabel(@bold(TEXCOORD1)) @item(vertex color attribute. Type is @code(float4).)
)

Also, each shader variable has a corresponding macro name that can be used
when defining the shaders using string literals. Don't use these macros with
the other shader functions as that will lead to undefined behavior.
@unorderedlist(
 @item(@code(ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX) for "al_projview_matrix")
 @item(@code(ALLEGRO_SHADER_VAR_POS) for "al_pos")
 @item(@code(ALLEGRO_SHADER_VAR_COLOR) for "al_color")
 @item(@code(ALLEGRO_SHADER_VAR_TEXCOORD) for "al_texcoord")
 @item(@code(ALLEGRO_SHADER_VAR_USE_TEX) for "al_use_tex")
 @item(@code(ALLEGRO_SHADER_VAR_TEX) for "al_tex")
 @item(@code(ALLEGRO_SHADER_VAR_USE_TEX_MATRIX) for "al_use_tex_matrix")
 @item(@code(ALLEGRO_SHADER_VAR_TEX_MATRIX for) "al_tex_matrix")
)
Examine the output of @link(al_get_default_shader_source) for an example of
how to use the above uniforms and attributes.
@return(@true on success and @false on error, in which case the error log is updated. The error log can be retrieved with @link(al_get_shader_log).)
@seealso(al_attach_shader_source_file) @seealso(al_build_shader) @seealso(al_get_default_shader_source) @seealso(al_get_shader_log)
#allegro5.al_attach_shader_source_file
Like @link(al_attach_shader_source) but reads the source code for the shader from the named file.
@return(@true on success and @false on error, in which case the error log is updated. The error log can be retrieved with @link(al_get_shader_log).)
@seealso(al_attach_shader_source) @seealso(al_build_shader) @seealso(al_get_shader_log)
#allegro5.al_build_shader
This is required before the shader can be used with @link(al_use_shader). It should be called after successfully attaching the pixel and/or vertex shaders with @link(al_attach_shader_source) or @link(al_attach_shader_source_file).

@bold(Note)

If you are using the @code(ALLEGRO_PROGRAMMABLE_PIPELINE) flag, then you must specify both a pixel and a vertex shader sources for anything to be rendered.
@return(@true on success and @false on error, in which case the error log is updated. The error log can be retrieved with @link(al_get_shader_log).)
@seealso(al_use_shader) @seealso(al_get_shader_log)
#allegro5.al_get_shader_log
Returns a read-only string containing the information log for a shader program. The log is updated by certain functions, such as @link(al_attach_shader_source) or @link(al_build_shader) when there is an error.

This function never returns @nil.
@seealso(al_attach_shader_source) @seealso(al_attach_shader_source_file) @seealso(al_build_shader)
#allegro5.al_get_shader_platform
Returns the platform the shader was created with (either @code(ALLEGRO_SHADER_HLSL) or @code(ALLEGRO_SHADER_GLSL)).
@seealso(al_create_shader)
#allegro5.al_use_shader
Uses the shader for subsequent drawing operations on the current target bitmap. Pass @nil to stop using any shader on the current target bitmap.
@return(@true on success. Otherwise returns @false, e.g. because the shader is incompatible with the target bitmap.)
@seealso(al_destroy_shader) @seealso(al_set_shader_sampler) @seealso(al_set_shader_matrix) @seealso(al_set_shader_int) @seealso(al_set_shader_float) @seealso(al_set_shader_bool) @seealso(al_set_shader_int_vector) @seealso(al_set_shader_float_vector)
#allegro5.al_destroy_shader
Destroy a shader. Any bitmaps which currently use the shader will implicitly stop using the shader. In multi-threaded programs, be careful that no such bitmaps are being accessed by other threads at the time.

As a convenience, if the target bitmap of the calling thread is using the shader then the shader is implicitly unused before being destroyed.

This function does nothing if the shader argument is @nil.
@seealso(al_create_shader)

#allegro5.al_set_shader_sampler
Sets a texture sampler uniform and texture unit of the current target bitmap's shader. The given bitmap must be a video bitmap.

Different samplers should use different units. The bitmap passed to Allegro's drawing functions uses the 0th unit, so if you're planning on using the @code(al_tex) variable in your pixel shader as well as another sampler, set the other sampler to use a unit different from 0. With the primitives addon, it is possible to free up the 0th unit by passing @nil as the texture argument to the relevant drawing functions. In this case, you may set a sampler to use the 0th unit and thus not use @code(al_tex) (the @code(al_use_tex) variable will be set to @code(false)).
@return(@true on success. Otherwise returns @false, e.g. if the uniform by that name does not exist in the shader.)
@seealso(al_use_shader)
#allegro5.al_set_shader_matrix
Sets a matrix uniform of the current target bitmap's shader.
@return(@true on success. Otherwise returns @false, e.g. if the uniform by that name does not exist in the shader.)
@seealso(al_use_shader)
#allegro5.al_set_shader_int
Sets an integer uniform of the current target bitmap's shader.
@return(@true on success. Otherwise returns @false, e.g. if the uniform by that name does not exist in the shader.)
@seealso(al_use_shader)
#allegro5.al_set_shader_float
Sets a float uniform of the current target bitmap's shader.
@return(@true on success. Otherwise returns @false, e.g. if the uniform by that name does not exist in the shader.)
@seealso(al_use_shader)
#allegro5.al_set_shader_int_vector
Sets an integer vector array uniform of the current target bitmap's shader.
The @code(num_components) parameter can take one of the values 1, 2, 3 or 4.
If it is 1 then an array of @code(num_elems) integer elements is added.
Otherwise each added array element is assumed to be a vector with 2, 3 or 4 components in it.

For example, if you have a GLSL uniform declared as uniform @code(ivec3
flowers[4]) or an HLSL uniform declared as uniform @code(int3 flowers[4]),
then you'd use this function from your code like so:
@longcode(!
VAR
  Flowers: ARRAY [0..3] OF ARRAY [0..2] OF AL_INT =
  (
   (1, 2, 3),
   (4, 5, 6),
   (7, 8, 9),
   (2, 5, 7)
  );
BEGIN
  ...
  al_set_shader_int_vector ('flowers', 3, @@(Flowers[0][0]), 4);
  ...
END;
!)
@return(@true on success. Otherwise returns @false, e.g. if the uniform by that name does not exist in the shader.)
@seealso(al_set_shader_float_vector) @seealso(al_use_shader)
#allegro5.al_set_shader_float_vector
Same as @link(al_set_shader_int_vector) except all values are float instead of integer.
@seealso(al_set_shader_int_vector) @seealso(al_use_shader)
#allegro5.al_set_shader_bool
Sets a boolean uniform of the current target bitmap's shader.
@return(@true on success. Otherwise returns @false, e.g. if the uniform by that name does not exist in the shader.)
@seealso(al_use_shader)

#allegro5.al_get_default_shader_source
Returns a string containing the source code to Allegro's default vertex or pixel shader appropriate for the passed platform. The @code(ALLEGRO_SHADER_AUTO) value means GLSL is used if OpenGL is being used otherwise HLSL.  @code(ALLEGRO_SHADER_AUTO) requires that there is a current display set on the calling thread. This function can return @nil if Allegro was built without support for shaders of the selected platform.
@seealso(al_attach_shader_source)



#allegro5.ALLEGRO_SYSTEM_ID
The system Allegro is running on.
@definitionlist(
  @itemlabel(ALLEGRO_SYSTEM_ID_UNKNOWN) @item(Unknown system.)
  @itemlabel(ALLEGRO_SYSTEM_ID_XGLX) @item(Xglx)
  @itemlabel(ALLEGRO_SYSTEM_ID_WINDOWS) @item(Windows)
  @itemlabel(ALLEGRO_SYSTEM_ID_MACOSX) @item(macOS)
  @itemlabel(ALLEGRO_SYSTEM_ID_ANDROID) @item(Android)
  @itemlabel(ALLEGRO_SYSTEM_ID_IPHONE) @item(iOS)
  @itemlabel(ALLEGRO_SYSTEM_ID_GP2XWIZ) @item(GP2XWIZ)
  @itemlabel(ALLEGRO_SYSTEM_ID_RASPBERRYPI) @item(Raspberry Pi)
  @itemlabel(ALLEGRO_SYSTEM_ID_SDL) @item(SDL)
)
@seealso(al_get_system_id)
#allegro5.al_init
Like @link(al_install_system), but automatically passes in the version and @nil as @code(atexit_ptr):

@bold(Note)

It is typically wrong to call al_init anywhere except the final game binary. In particular, do not call it inside a shared library unless you know what you're doing. In those cases, it is better to call @link(al_install_system) either with a @nil @code(atexit_ptr), or with a pointer to @code(atexit) provided by the user of this shared library.
@seealso(al_uninstall_system) @seealso(al_get_system_id)

#allegro5.al_install_system
Initializes the Allegro system.  No other Allegro functions can be called before this (with one or two exceptions).
@param(version Should always be set to @link(ALLEGRO_VERSION_INT).)
@param(atexit_ptr If non-@nil, and if hasn't been done already, @code(al_uninstall_system) will be registered as an atexit function. @code(atexit) is a function provided by standard C runtime library.  It allows similar functionality than @code(FINALIZATION) section in Pascal.)
@returns(@true if Allegro was successfully initialized by this function call @(or already was initialized previously@), @false if Allegro cannot be used.)
@seealso(al_init) @seealso(al_uninstall_system) @seealso(al_get_system_id)
#allegro5.al_uninstall_system
Closes down the Allegro system.

In most cases you don't need to call this, because it's called by @code(allegro5.pas) @code(FINALIZATION) section.
@seealso(al_init) @seealso(al_install_system)
#allegro5.al_get_system_config(void)
Returns the system configuration structure. The returned configuration should not be destroyed with @link(al_destroy_config). This is mainly used for configuring Allegro and its addons. You may populate this configuration before Allegro is installed to control things like the logging levels and other features.

Allegro will try to populate this configuration by loading a configuration file from a few different locations, in this order:
@unorderedlist(
  @item(Unix only: /etc/allegro5rc)
  @item(Unix only: $HOME/allegro5rc)
  @item(Unix only: $HOME/.allegro5rc)
  @item(allegro5.cfg next to the executable)
)
If multiple copies are found, then they are merged using @link(al_merge_config_into).

The contents of this file are documented inside a prototypical allegro5.cfg that you can find in the @code(resources) directory of the distributions of Allegro.pas.

Note that Allegro will not look into that file unless you make a copy of it and place it next to your executable!
#allegro5.al_get_system_id
Returns the platform that Allegro is running on.
@seealso(ALLEGRO_SYSTEM_ID)

#allegro5.al_inhibit_screensaver
This function allows the user to stop the system screensaver from starting up if @true is passed, or resets the system back to the default state (the state at program start) if @false is passed.
@returns(@true if the state was set successfully, otherwise @false.)



#allegro5.ALLEGRO_TIMERptr
Pointer to timer.  This is an abstract data type representing a timer object.
@seealso(al_create_timer)

#allegro5.al_create_timer
Allocates and initializes a timer. The new timer is initially stopped.

Usage note:  typical granularity is on the order of microseconds, but with some drivers might only be milliseconds.
@param(speed_secs Seconds per "tick". Must be positive.)
@returns(If successful, a pointer to a new timer object, otherwise @nil.)
@seealso(al_start_timer) @seealso(al_destroy_timer)
#allegro5.al_destroy_timer
Uninstalls the timer specified. If the timer is started, it will automatically be stopped before uninstallation. It will also automatically unregister the timer with any event queues.

Does nothing if passed the @nil pointer.
@seealso(al_create_timer)
#allegro5.al_start_timer
Starts the timer specified.  From then, the timer's counter will increment at a constant rate, and it will begin generating events.  Starting a timer that is already started does nothing.  Starting a timer that was stopped will reset the timer's counter, effectively restarting the timer from the beginning.
@seealso(al_stop_timer) @seealso(al_get_timer_started) @seealso(al_resume_timer)
#allegro5.al_stop_timer
Stops the timer specified. The timer's counter will stop incrementing and it will stop generating events. Stopping a timer that is already stopped does nothing.
@seealso(al_start_timer) @seealso(al_get_timer_started) @seealso(al_resume_timer)
#allegro5.al_resume_timer
Resumes the timer specified. From then, the timer's counter will increment at a constant rate, and it will begin generating events. Resuming a timer that is already started does nothing. Resuming a stopped timer will not reset the timer's counter (unlike @link(al_start_timer)).
@seealso(al_start_timer) @seealso(al_stop_timer) @seealso(al_get_timer_started)
#allegro5.al_get_timer_speed
Returns the timer's speed, in seconds. (The same value passed to @link(al_create_timer) or @link(al_set_timer_speed).)
@seealso(al_set_timer_speed)
#allegro5.al_set_timer_speed
Sets the timer's speed, i.e. the rate at which its counter will be incremented when it is started. This can be done when the timer is started or stopped. If the timer is currently running, it is made to look as though the speed change occurred precisely at the last tick.
@param(speed_secs Exactly the same meaning as with @link(al_create_timer).)
@seealso(al_get_timer_speed)
#allegro5.al_get_timer_count
Returns the timer's counter value. The timer can be started or stopped.
@seealso(al_set_timer_count)
#allegro5.al_set_timer_count
Sets the timer's counter value. The timer can be started or stopped. The @code(count) value may be positive or negative, but will always be incremented by +1 at each tick.
@seealso(al_get_timer_count) @seealso(al_add_timer_count)
#allegro5.al_add_timer_count
Add @code(diff) to the timer's counter value. This is similar to writing:
@longcode(!
al_set_timer_count (Timer, al_get_timer_count (Timer) + diff);
!)
except that the addition is performed atomically, so no ticks will be lost.
@seealso(al_set_timer_count)
#allegro5.al_get_timer_event_source
Retrieves the associated event source. Timers will generate events of type @link(ALLEGRO_EVENT_TIMER).



#allegro5.ALLEGRO_STATE
Opaque type which is passed to @link(al_store_state)/@link(al_restore_state).

The various state kept internally by Allegro can be displayed like this:
@preformatted(
  global
      active system driver
          current config
  per thread
      new bitmap params
      new display params
      active file interface
      errno
      current blending mode
      current display
          deferred drawing
      current target bitmap
          current transformation
          current projection transformation
          current clipping rectangle
          bitmap locking
          current shader
)
In general, the only real global state is the active system driver. All other global state is per-thread, so if your application has multiple separate threads they never will interfere with each other. (Except if there are objects accessed by multiple threads of course. Usually you want to minimize that though and for the remaining cases use synchronization primitives described in the threads section or events described in the events section to control inter-thread communication.)

#allegro5.al_store_state
Stores part of the state of the current thread in the given @link(ALLEGRO_STATE) object. The flags parameter can take any bit-combination of these flags:
@unorderedlist(
 @item(@code(ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS) - new_display_format, new_display_refresh_rate, new_display_flags)
 @item(@code(ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) - new_bitmap_format, new_bitmap_flags)
 @item(@code(ALLEGRO_STATE_DISPLAY) - current_display)
 @item(@code(ALLEGRO_STATE_TARGET_BITMAP) - target_bitmap)
 @item(@code(ALLEGRO_STATE_BLENDER) - blender)
 @item(@code(ALLEGRO_STATE_TRANSFORM) - current_transformation)
 @item(@code(ALLEGRO_STATE_PROJECTION_TRANSFORM) - current_projection_transformation)
 @item(@code(ALLEGRO_STATE_NEW_FILE_INTERFACE) - new_file_interface)
 @item(@code(ALLEGRO_STATE_BITMAP) - same as @code(ALLEGRO_STATE_NEW_BITMAP_PARAMETERS) and @code(ALLEGRO_STATE_TARGET_BITMAP))
 @item(@code(ALLEGRO_STATE_ALL) - all of the above)
)
@seealso(al_restore_state)
#allegro5.al_restore_state
Restores part of the state of the current thread from the given @link(ALLEGRO_STATE) object.
@seealso(al_store_state)



#al5acodec.al_init_acodec_addon
This procedure registers all the known audio file type handlers for @link(al_load_sample), @link(al_save_sample), @link(al_load_audio_stream), etc.

Depending on what libraries are available, the full set of recognised extensions is: .wav, .flac, .ogg, .it, .mod, .s3m, .xm.

@italic(Limitations:)
@unorderedlist(
  @item(Saving is only supported for wav files.)
  @item(The wav file loader currently only supports 8/16 bit little endian PCM files. 16 bits are used when saving wav files. Use flac files if more precision is required.)
  @item(Module files @(.it, .mod, .s3m, .xm@) are often composed with streaming in mind, and sometimes cannot be easily rendered into a finite length sample. Therefore they cannot be loaded with @link(al_load_sample) and must be streamed with @link(al_load_audio_stream).)
  @item(.voc file streaming is unimplemented.)
)
@return(@true on success.)
#al5acodec.al_get_allegro_acodec_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).



#al5audio.ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT
Sent when a stream fragment is ready to be filled in. @seealso(al_get_audio_stream_fragment)
#al5audio.ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT
Sent after a user-specified number of samples have been recorded. Convert this to @link(ALLEGRO_AUDIO_RECORDER_EVENT) via @link(al_get_audio_recorder_event).

You must always check the values for the buffer and samples as they are not guaranteed to be exactly what was originally specified.

@bold(Unstable API:) The API may need a slight redesign.

#al5audio.ALLEGRO_AUDIO_RECORDERptr
An opaque datatype that represents a recording device.

@bold(Unstable API:) The API may need a slight redesign.

#al5audio.ALLEGRO_AUDIO_RECORDER_EVENT
Structure that holds the audio recorder event data.

@bold(Unstable API:) The API may need a slight redesign.
@seealso(al_get_audio_recorder_event) @seealso(ALLEGRO_EVENT)

#al5audio.ALLEGRO_AUDIO_DEPTH
Sample depth and type as well as signedness. Mixers only use 32-bit signed float (-1..+1), or 16-bit signed integers. Signedness is determined by an "unsigned" bit-flag applied to the depth value.

@bold(@code(ALLEGRO_AUDIO_DEPTH_UINT8)): @code(INT8 + UNSIGNED)

#al5audio.ALLEGRO_PLAYMODE
@value(ALLEGRO_PLAYMODE_ONCE the sample/stream is played from start to finish an then it stops.)
@value(ALLEGRO_PLAYMODE_LOOP the sample/stream is played from start to finish (or between the two loop points). When it reaches the end, it restarts from the beginning.)
@value(ALLEGRO_PLAYMODE_LOOP_ONCE just like ALLEGRO_PLAYMODE_ONCE, but respects the loop end point.)
@value(ALLEGRO_PLAYMODE_BIDIR the sample is played from start to finish (or between the two loop points). When it reaches the end, it reverses the playback direction and plays until it reaches the beginning when it reverses the direction back to normal. This is mode is rarely supported for streams.)


#al5audio.ALLEGRO_AUDIO_PAN_NONE
A special value for the pan property of sample instances and audio streams. Use this value to disable panning on sample instances and audio streams, and play them without attentuation implied by panning support.

@code(ALLEGRO_AUDIO_PAN_NONE) is different from a pan value of 0.0 (centered) because, when panning is enabled, we try to maintain a constant sound power level as a sample is panned from left to right. A sound coming out of one speaker should sound as loud as it does when split over two speakers. As a consequence, a sample with pan value 0.0 will be 3 dB softer than the original level.

(Please correct us if this is wrong.)

#al5audio.ALLEGRO_SAMPLEptr
Pointer to an Allegro sample object.

An Allegro sample object stores the data necessary for playing pre-defined digital audio. It holds a user-specified PCM data buffer and information about its format (data length, depth, frequency, channel configuration). You can have the same ALLEGRO_SAMPLE playing multiple times simultaneously.
@seealso(ALLEGRO_SAMPLE_INSTANCEptr)
#al5audio.ALLEGRO_SAMPLE_ID
An @code(ALLEGRO_SAMPLE_ID) represents a sample being played via @link(al_play_sample). It can be used to later stop the sample with @link(al_stop_sample). The underlying @link(ALLEGRO_SAMPLE_INSTANCEptr) can be extracted using @link(al_lock_sample_id).
#al5audio.ALLEGRO_SAMPLE_INSTANCEptr
Pointer to an Allegro sample instance.

An Allegro sample instance represents a playable instance of a predefined sound effect. It holds information about how the effect should be played: These playback parameters consist of the looping mode, loop start/end points, playing position, speed, gain, pan and the playmode. Whether a sample instance is currently playing or paused is also one of its properties.

An instance uses the data from an Allegro sample object. Multiple instances may be created from the same @code(ALLEGRO_SAMPLE). An @code(ALLEGRO_SAMPLE) must not be destroyed while there are instances which reference it.

To actually produce audio output, an @code(ALLEGRO_SAMPLE_INSTANCEptr) must be attached to an @link(ALLEGRO_MIXERptr) which eventually reaches an @link(ALLEGRO_VOICEptr) object.
@seealso(ALLEGRO_SAMPLEptr)
#al5audio.ALLEGRO_AUDIO_STREAMptr
Pointer to an @code(ALLEGRO_AUDIO_STREAM) object that is used to stream generated audio to the sound device, in real-time. This is done by reading from a buffer, which is split into a number of fragments. Whenever a fragment has finished playing, the user can refill it with new data.

As with @link(ALLEGRO_SAMPLE_INSTANCEptr) objects, streams store information necessary for playback, so you may not play the same stream multiple times simultaneously. Streams also need to be attached to an @link(ALLEGRO_MIXERptr), which, eventually, reaches an @link(ALLEGRO_VOICEptr) object.

While playing, you must periodically fill fragments with new audio data. To know when a new fragment is ready to be filled, you can either directly check with @link(al_get_available_audio_stream_fragments), or listen to events from the stream.

You can register an audio stream event source to an event queue; see @link(al_get_audio_stream_event_source). An @code(ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) event is generated whenever a new fragment is ready. When you receive an event, use @link(al_get_audio_stream_fragment) to obtain a pointer to the fragment to be filled. The size and format are determined by the parameters passed to @link(al_create_audio_stream).

If you're late with supplying new data, the stream will be silent until new data is provided. You must call @link(al_drain_audio_stream) when you're finished with supplying data to the stream.

If the stream is created by @link(al_load_audio_stream) then it will also generate an @link(ALLEGRO_EVENT_AUDIO_STREAM_FINISHED) event if it reaches the end of the file and is not set to loop.
#al5audio.ALLEGRO_MIXERptr
A mixer mixes together attached streams into a single buffer. In the process, it converts channel configurations, sample frequencies and audio depths of the attached sample instances and audio streams accordingly. You can control the quality of this conversion using @link(ALLEGRO_MIXER_QUALITY).

When going from mono to stereo (and above), the mixer reduces the volume of both channels by sqrt(2). When going from stereo (and above) to mono, the mixer reduces the volume of the left and right channels by sqrt(2) before adding them to the center channel (if present).
#al5audio.ALLEGRO_VOICEptr
A pointer to an Allegro voice.

A voice represents an audio device on the system, which may be a real device, or an abstract device provided by the operating system. To play back audio, you would attach a mixer, sample instance or audio stream to a voice.
@seealso(ALLEGRO_MIXERptr) @seealso(ALLEGRO_SAMPLEptr) @seealso(ALLEGRO_AUDIO_STREAMptr)
#al5audio.ALLEGRO_AUDIO_DEVICEptr
An opaque datatype that represents an audio device.
@seealso(al_get_audio_output_device)

#al5audio.ALLEGRO_MIXER_CALLBACK
@seealso(al_set_mixer_postprocess_callback)
#al5audio.ALLEGRO_SAMPLE_LOADER
Callback function to load samples. @seealso(al_register_sample_loader)
#al5audio.ALLEGRO_SAMPLE_SAVER
Callback function to save samples. @seealso(al_register_sample_saver)
#al5audio.ALLEGRO_AUDIO_STREAM_LOADER
Callback function to load audio streams. @seealso(al_register_audio_stream_loader)
#al5audio.ALLEGRO_SAMPLE_LOADER_F
Callback function to load samples. @seealso(al_register_sample_loader_f)
#al5audio.ALLEGRO_SAMPLE_SAVER_F
Callback function to save samples. @seealso(al_register_sample_saver_f)
#al5audio.ALLEGRO_AUDIO_STREAM_LOADER_F
Callback function to load audio streams. @seealso(al_register_audio_stream_loader_f)

#al5audio.al_create_sample
Creates a sample data structure from the supplied buffer. If @code(free_buf) is @true then the buffer will be freed with @link(al_free) when the sample data structure is destroyed. For portability (especially Windows), the buffer should have been allocated with @link(al_malloc). Otherwise you should free the sample data yourself.

A sample that is referred to by the @code(samples) parameter refers to a sequence channel intensities. E.g. if you're making a stereo sample with the @code(samples) set to 4, then the layout of the data in buf will be:
@preformatted(
  LRLRLRLR
)
Where L and R are the intensities for the left and right channels respectively. A single sample, then, refers to the LR pair in this example.

To allocate a buffer of the correct size, you can use something like this:
@longcode(!
VAR
  SampleSize, Bytes: INTEGER;
  Buffer: POINTER;
BEGIN
  SampleSize := al_get_channel_count (ChanConf) * al_get_audio_depth_size (Depth);
  Bytes := Samples * SampleSize;
  Buffer := al_malloc (Bytes)
END.
!)
@seealso(al_destroy_sample) @seealso(ALLEGRO_AUDIO_DEPTH) @seealso(ALLEGRO_CHANNEL_CONF)
#al5audio.al_destroy_sample
Frees the sample data structure. If it was created with the @code(free_buf) parameter set to @true, then the buffer will be freed with @link(al_free).

This function will stop any sample instances which may be playing the buffer referenced by the @code(ALLEGRO_SAMPLEptr).
@seealso(al_destroy_sample_instance) @seealso(al_stop_sample) @seealso(al_stop_samples)

#al5audio.al_create_sample_instance
Creates a sample instance, using the supplied sample data. The instance must be attached to a mixer (or voice) in order to actually produce output.

The argument may be @nil. You can then set the sample data later with @link(al_set_sample).
@seealso(al_destroy_sample_instance)
#al5audio.al_destroy_sample_instance
Detaches the sample instance from anything it may be attached to and frees it (the sample data, i.e. its @code(ALLEGRO_SAMPLE), is @italic(not) freed!).
@seealso(al_create_sample_instance)

#al5audio.al_get_sample_frequency
Returns the frequency (in Hz) of the sample.
@seealso(al_get_sample_channels) @seealso(al_get_sample_depth) @seealso(al_get_sample_length) @seealso(al_get_sample_data)
#al5audio.al_get_sample_length
Returns the length of the sample in sample values.
@seealso(al_get_sample_channels) @seealso(al_get_sample_depth) @seealso(al_get_sample_frequency) @seealso(al_get_sample_data)
#al5audio.al_get_sample_depth
Returns the audio depth of the sample.
@seealso(ALLEGRO_AUDIO_DEPTH) @seealso(al_get_sample_channels) @seealso(al_get_sample_frequency) @seealso(al_get_sample_length) @seealso(al_get_sample_data)
#al5audio.al_get_sample_channels
Returns the channel configuration of the sample.
@seealso(ALLEGRO_CHANNEL_CONF) @seealso(al_get_sample_depth) @seealso(al_get_sample_frequency) @seealso(al_get_sample_length) @seealso(al_get_sample_data)
#al5audio.al_get_sample_data
Returns a pointer to the raw sample data.
@seealso(al_get_sample_channels) @seealso(al_get_sample_depth) @seealso(al_get_sample_frequency) @seealso(al_get_sample_length)

#al5audio.al_get_sample_instance_frequency
Returns the frequency (in Hz) of the sample instance's sample data.
#al5audio.al_get_sample_instance_length
Returns the length of the sample instance in sample values. This property may differ from the length of the instance's sample data.
@seealso(al_set_sample_instance_length) @seealso(al_get_sample_instance_time)
#al5audio.al_get_sample_instance_position
Gets the playback position of a sample instance. @seealso(al_set_sample_instance_position)

#al5audio.al_get_sample_instance_speed
Returns the relative playback speed of the sample instance. @seealso(al_set_sample_instance_speed)
#al5audio.al_get_sample_instance_gain
Returns the playback gain of the sample instance. @seealso(al_set_sample_instance_gain)
#al5audio.al_get_sample_instance_pan
Gets the pan value of the sample instance. @seealso(al_set_sample_instance_pan)
#al5audio.al_get_sample_instance_time
Returns the length of the sample instance in seconds, assuming a playback speed of 1.0.
@seealso(al_get_sample_instance_length)

#al5audio.al_get_sample_instance_depth
Returns the audio depth of the sample instance's sample data. @seealso(ALLEGRO_AUDIO_DEPTH)
#al5audio.al_get_sample_instance_channels
Returns the channel configuration of the sample instance's sample data. @seealso(ALLEGRO_CHANNEL_CONF)
#al5audio.al_get_sample_instance_playmode
Returns the playback mode of the sample instance.
@seealso(ALLEGRO_PLAYMODE) @seealso(al_set_sample_instance_playmode)

#al5audio.al_get_sample_instance_playing
Returns @true if the sample instance is in the playing state. This may be true even if the instance is not attached to anything.
@seealso(al_set_sample_instance_playing)
#al5audio.al_get_sample_instance_attached
Returns whether the sample instance is attached to something.
@seealso(al_attach_sample_instance_to_mixer) @seealso(al_attach_sample_instance_to_voice) @seealso(al_detach_sample_instance)

#al5audio.al_set_sample_instance_position
Sets the playback position of a sample instance. @return(@true on success, @false on failure.)
@seealso(al_get_sample_instance_position)
#al5audio.al_set_sample_instance_length
Sets the length of the sample instance in sample values. This can be used to play only parts of the underlying sample. Be careful not to exceed the actual length of the sample data, though.
@return(@true on success, @false on failure. Will fail if the sample instance is currently playing.)
@seealso(al_get_sample_instance_length)

#al5audio.al_set_sample_instance_speed
Sets the relative playback speed of the sample instance. 1.0 means normal speed.
@Return(@true on success, @false on failure. Will fail if the sample instance is attached directly to a voice.)
@seealso(al_get_sample_instance_speed)
#al5audio.al_set_sample_instance_gain
Sets the playback gain of the sample instance.
@Return(@true on success, @false on failure. Will fail if the sample instance is attached directly to a voice.)
@seealso(al_get_sample_instance_gain)
#al5audio.al_set_sample_instance_pan
Sets the pan value on a sample instance. A value of -1.0 means to play the sample only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value @link(ALLEGRO_AUDIO_PAN_NONE) disables panning and plays the sample at its original level. This will be louder than a pan value of 0.0.

@bold(Note)

panning samples with more than two channels doesn't work yet.
@return(@true on success, @false on failure. Will fail if the sample instance is attached directly to a voice.)
@seealso(al_get_sample_instance_pan) @seealso(ALLEGRO_AUDIO_PAN_NONE)

#al5audio.al_set_sample_instance_playmode
Sets the playback mode of the sample instance.
@return(@true on success, @false on failure.)
@seealso(ALLEGRO_PLAYMODE) @seealso(al_get_sample_instance_playmode)

#al5audio.al_set_sample_instance_playing
Changes whether the sample instance is playing.

The instance does not need to be attached to anything.
@return(@true on success, @false on failure.) @seealso(al_get_sample_instance_playing)
#al5audio.al_detach_sample_instance
Detachs the sample instance from whatever it's attached to, if anything.
@return(@true on success.)
@seealso(al_attach_sample_instance_to_mixer) @seealso(al_attach_sample_instance_to_voice) @seealso(al_get_sample_instance_attached)

#al5audio.al_set_sample
Changes the sample data that a sample instance plays. This can be quite an involved process.

First, the sample is stopped if it is not already.

Next, if data is @nil, the sample is detached from its parent (if any).

If data is not @nil, the sample may be detached and reattached to its parent (if any). This is not necessary if the old sample data and new sample data have the same frequency, depth and channel configuration. Reattaching may not always succeed.

On success, the sample remains stopped. The playback position and loop end points are reset to their default values. The loop mode remains unchanged.
@return(@true on success, @false on failure. On failure, the sample will be stopped and detached from its parent.)
@seealso(al_get_sample)
#al5audio.al_get_sample
Returns the sample data that the sample instance plays.

Note this returns a pointer to an internal structure, not the @link(ALLEGRO_SAMPLEptr) that you may have passed to @link(al_set_sample). However, the sample buffer of the returned @code(ALLEGRO_SAMPLEptr) will be the same as the one that was used to create the sample (passed to @link(al_create_sample)). You can use @link(al_get_sample_data) on the return value to retrieve and compare it.
@seealso(al_set_sample)
#al5audio.al_play_sample_instance
Plays the sample instance. @return(@true on success, @false on failure.)
@seealso(al_stop_sample_instance)
#al5audio.al_stop_sample_instance
Stops an sample instance playing. @seealso(al_play_sample_instance)

#al5audio.al_create_audio_stream
Creates an @link(ALLEGRO_AUDIO_STREAMptr). The stream will be set to play by default. It will feed audio data from a buffer, which is split into a number of fragments.

A sample that is referred to by the @code(samples) parameter refers to a sequence channel intensities. E.g. if you're making a stereo stream with the @code(samples) set to 4, then the layout of the data in the fragment will be:
@preformatted(
  LRLRLRLR
)
Where L and R are the intensities for the left and right channels respectively. A single sample, then, refers to the LR pair in this example.

The choice of @code(buffer_count), @code(samples) and @code(freq) directly influences the audio delay. The delay in seconds can be expressed as:
@longcode(!
Delay := buffer_count * samples / freq
!)
This is only the delay due to Allegro's streaming, there may be additional delay caused by sound drivers and/or hardware.

@bold(Note)

If you know the fragment size in bytes, you can get the size in samples like this:
@longcode(!
  SampleSize := al_get_channel_count (ChannelConf) * al_get_audio_depth_size (Depth);
  Samples := BytesPerFragment / SampleSize;
!)
The size of the complete buffer is:
@longcode(!
  BufferSize := BytesPerFragment * buffer_count
!)
@bold(Note)

Unlike many Allegro objects, audio streams are not implicitly destroyed when Allegro is shut down. You must destroy them manually with al_destroy_audio_stream before the audio system is shut down.

@param(buffer_count How many fragments to use for the audio stream. Usually only two fragments are required - splitting the audio buffer in two halves. But it means that the only time when new data can be supplied is whenever one half has finished playing. When using many fragments, you usually will use fewer samples for one, so there always will be (small) fragments available to be filled with new data.)
@param(samples The size of a fragment in samples.)
@param(freq The frequency, in Hertz.)
@param(depth Must be one of the values listed for @link(ALLEGRO_AUDIO_DEPTH).)
@param(chan_conf Must be one of the values listed for @link(ALLEGRO_CHANNEL_CONF).)
#al5audio.al_destroy_audio_stream
Destroys an audio stream which was created with @link(al_create_audio_stream) or @link(al_load_audio_stream).

@bold(Note)

If the stream is still attached to a mixer or voice, @link(al_detach_audio_stream) is automatically called on it first.
@seealso(al_drain_audio_stream)
#al5audio.al_drain_audio_stream
You should call this to finalise an audio stream that you will no longer be feeding, to wait for all pending buffers to finish playing. The stream's playing state will change to @false.
@seealso(al_destroy_audio_stream)

#al5audio.al_get_audio_stream_frequency
Returns the stream frequency (in Hz).
#al5audio.al_get_audio_stream_length
Returns the stream length in samples.
#al5audio.al_get_audio_stream_fragments
Returns the number of fragments this stream uses. This is the same value as passed to @link(al_create_audio_stream) when a new stream is created.
@seealso(al_get_available_audio_stream_fragments)
#al5audio.al_get_available_audio_stream_fragments
Returns the number of available fragments in the stream, that is, fragments which are not currently filled with data for playback.
@seealso(al_get_audio_stream_fragment) @seealso(al_get_audio_stream_fragments)

#al5audio.al_get_audio_stream_speed
Returns the relative playback speed of the stream.
@seealso(al_set_audio_stream_speed)
#al5audio.al_get_audio_stream_gain
Returns the playback gain of the stream.
@seealso(al_set_audio_stream_gain)
#al5audio.al_get_audio_stream_pan
Gets the pan value of the stream.
@seealso(al_set_audio_stream_pan)

#al5audio.al_get_audio_stream_channels
Returns the stream channel configuration.
@seealso(ALLEGRO_CHANNEL_CONF)
#al5audio.al_get_audio_stream_depth
Returns the stream audio depth.
@seealso(ALLEGRO_AUDIO_DEPTH)
#al5audio.al_get_audio_stream_playmode
Returns the playback mode of the stream.
@seealso(ALLEGRO_PLAYMODE) @seealso(al_set_audio_stream_playmode)

#al5audio.al_get_audio_stream_playing
Returns @true if the stream is playing.
@seealso(al_set_audio_stream_playing)
#al5audio.al_get_audio_stream_attached
Returns whether the stream is attached to something.
@seealso(al_attach_audio_stream_to_mixer) @seealso(al_attach_audio_stream_to_voice) @seealso(al_detach_audio_stream)
#al5audio.al_get_audio_stream_played_samples
Gets the number of samples consumed by the parent since the audio stream was started.

#al5audio.al_get_audio_stream_fragment
When using Allegro's audio streaming, you will use this function to continuously provide new sample data to a stream.

If the stream is ready for new data, the function will return the address of an internal buffer to be filled with audio data. The length and format of the buffer are specified with @link(al_create_audio_stream) or can be queried with the various functions described here. Once the buffer is filled, you must signal this to Allegro by passing the buffer to @link(al_set_audio_stream_fragment).

If the stream is not ready for new data, the function will return @nil.

@bold(Note)

If you listen to events from the stream, an @link(ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) event will be generated whenever a new fragment is ready. However, getting an event is not a guarantee that @link(al_get_audio_stream_fragment) will not return @nil, so you still must check for it.
@seealso(al_set_audio_stream_fragment) @seealso(al_get_audio_stream_event_source) @seealso(al_get_audio_stream_frequency) @seealso(al_get_audio_stream_channels) @seealso(al_get_audio_stream_depth) @seealso(al_get_audio_stream_length)

#al5audio.al_set_audio_stream_speed
Sets the relative playback speed of the stream. 1.0 means normal speed.
@return(@true on success, @false on failure. Will fail if the audio stream is attached directly to a voice.)
@seealso(al_get_audio_stream_speed)
#al5audio.al_set_audio_stream_gain
Sets the playback gain of the stream.
@return(@true on success, @false on failure. Will fail if the audio stream is attached directly to a voice.)
@seealso(al_get_audio_stream_gain)
#al5audio.al_set_audio_stream_pan
Sets the pan value on an audio stream. A value of -1.0 means to play the stream only through the left speaker; +1.0 means only through the right speaker; 0.0 means the sample is centre balanced. A special value @link(ALLEGRO_AUDIO_PAN_NONE) disables panning and plays the stream at its original level. This will be louder than a pan value of 0.0.
@return(@true on success, @false on failure. Will fail if the audio stream is attached directly to a voice.)
@seealso(al_get_audio_stream_pan) @seealso(ALLEGRO_AUDIO_PAN_NONE)

#al5audio.al_set_audio_stream_playmode
Sets the playback mode of the stream.
@return(@true on success, @false on failure.)
@seealso(ALLEGRO_PLAYMODE) @seealso(al_get_audio_stream_playmode)

#al5audio.al_set_audio_stream_playing
Changes whether the stream is playing.
@return(@true on success, @false on failure.)
@seealso(al_get_audio_stream_playing)
#al5audio.al_detach_audio_stream
Detaches the stream from whatever it's attached to, if anything.
@seealso(al_attach_audio_stream_to_mixer) @seealso(al_attach_audio_stream_to_voice) @seealso(al_get_audio_stream_attached)
#al5audio.al_set_audio_stream_fragment
This function needs to be called for every successful call of @link(al_get_audio_stream_fragment) to indicate that the buffer (pointed to by @code(val)) is filled with new data.
@seealso(al_get_audio_stream_fragment)

#al5audio.al_rewind_audio_stream
Sets the streaming file playing position to the beginning. Currently this can only be called on streams created with @link(al_load_audio_stream), @link(al_load_audio_stream_f) and the format-specific functions underlying those functions.
@return(@true on success.)
#al5audio.al_seek_audio_stream_secs
Sets the streaming file playing position to time. Currently this can only be called on streams created with @link(al_load_audio_stream), @link(al_load_audio_stream_f) and the format-specific functions underlying those functions.
@return(@true on success.)
@seealso(al_get_audio_stream_position_secs) @seealso(al_get_audio_stream_length_secs)
#al5audio.al_get_audio_stream_position_secs
Returns the position of the stream in seconds. Currently this can only be called on streams created with @link(al_load_audio_stream).
@seealso(al_get_audio_stream_length_secs)
#al5audio.al_get_audio_stream_length_secs
Returns the length of the stream in seconds, if known. Otherwise returns zero.

Currently this can only be called on streams created with @link(al_load_audio_stream), @link(al_load_audio_stream_f) and the format-specific functions underlying those functions.
@seealso(al_get_audio_stream_position_secs)
#al5audio.al_set_audio_stream_loop_secs
Sets the loop points for the stream in seconds. Currently this can only be called on streams created with @link(al_load_audio_stream), @link(al_load_audio_stream_f) and the format-specific functions underlying those functions.

#al5audio.al_get_audio_stream_event_source
Retrieves the associated event source.

See @link(al_get_audio_stream_fragment) for a description of the @link(ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) event that audio streams emit.

#al5audio.al_create_mixer
Creates a mixer to attach sample instances, audio streams, or other mixers to. It will mix into a buffer at the requested frequency (in Hz) and channel count.

The only supported audio depths are @code(ALLEGRO_AUDIO_DEPTH_FLOAT32) and @code(ALLEGRO_AUDIO_DEPTH_INT16) (not yet complete).

To actually produce any output, the mixer will have to be attached to a voice.
@Return(@true on success, @false on error.)
@seealso(al_destroy_mixer) @seealso(ALLEGRO_AUDIO_DEPTH) @seealso(ALLEGRO_CHANNEL_CONF) @seealso(al_destroy_mixer)
#al5audio.al_destroy_mixer
Destroys the mixer.
@seealso(al_create_mixer)

#al5audio.al_attach_sample_instance_to_mixer
Attaches a sample instance to a mixer. The instance must not already be attached to anything.
@Return(@true on success, @false on failure.)
@seealso(al_detach_sample_instance)
#al5audio.al_attach_audio_stream_to_mixer
Attaches an audio stream to a mixer. The stream must not already be attached to anything.
@returns(@true on success, @false on failure.)
@seealso(al_detach_audio_stream)
#al5audio.al_attach_mixer_to_mixer
Attaches the mixer passed as the first argument onto the mixer passed as the second argument. The first mixer (that is going to be attached) must not already be attached to anything. Both mixers must use the same frequency, audio depth and channel configuration.

It is invalid to attach a mixer to itself.
@return(@true on success, @false on error.)
@seealso(al_detach_mixer)
#al5audio.al_set_mixer_postprocess_callback
Sets a post-processing filter function that's called after the attached streams have been mixed. The buffer's format will be whatever the mixer was created with. The sample count and user-data pointer is also passed.

@bold(Note)

The callback is called from a dedicated audio thread.

#al5audio.al_get_mixer_frequency
Returns the mixer frequency (in Hz). @seealso(al_set_mixer_frequency)
#al5audio.al_get_mixer_channels
Returns the mixer channel configuration.@seealso(ALLEGRO_CHANNEL_CONF)
#al5audio.al_get_mixer_depth
Returns the mixer audio depth.@seealso(ALLEGRO_AUDIO_DEPTH)
#al5audio.al_get_mixer_quality
Returns the mixer quality.@seealso(ALLEGRO_MIXER_QUALITY) @seealso(al_set_mixer_quality)
#al5audio.al_get_mixer_gain
Returns the mixer gain (amplification factor). The default is 1.0.@seealso(al_set_mixer_gain)
#al5audio.al_get_mixer_playing
Returns @true if the mixer is playing.@seealso(al_set_mixer_playing)
#al5audio.al_get_mixer_attached
Returns @true if the mixer is attached to something.
@seealso(al_attach_sample_instance_to_mixer) @seealso(al_attach_audio_stream_to_mixer) @seealso(al_attach_mixer_to_mixer) @seealso(al_detach_mixer)
#al5audio.al_set_mixer_frequency
Sets the mixer frequency (in Hz). This will only work if the mixer is not attached to anything.
@Return(@true on success, @false on failure.) @seealso(al_get_mixer_frequency)
#al5audio.al_set_mixer_quality
Sets the mixer quality. This can only succeed if the mixer does not have anything attached to it.
@returns(@true on success, @false on failure.)
@seealso(ALLEGRO_MIXER_QUALITY) @(al_get_mixer_quality)
#al5audio.al_set_mixer_gain
Sets the mixer gain (amplification factor).
@return(@true on success, @false on failure.) @seealso(al_get_mixer_gain)
#al5audio.al_set_mixer_playing
Changes whether the mixer is playing.
@returns(@true on success, @false on failure.) @seealso(al_get_mixer_playing)
#al5audio.al_detach_mixer
Detach the mixer from whatever it is attached to, if anything. @seealso(al_attach_mixer_to_mixer)

#al5audio.al_create_voice
Creates a voice structure and allocates a voice from the digital sound driver. The passed frequency (in HZ), sample format and channel configuration are used as a hint to what kind of data will be sent to the voice. However, the underlying sound driver is free to use non-matching values. For example, it may be the native format of the sound hardware.

If a mixer is attached to the voice, the mixer will handle the conversion of all its input streams to the voice format and care does not have to be taken for this. However if you access the voice directly, make sure to not rely on the parameters passed to this function, but instead query the returned voice for the actual settings.
@seealso(al_destroy_voice)
#al5audio.al_destroy_voice
Destroys the voice and deallocates it from the digital driver. Does nothing if the voice is @nil.
@seealso(al_create_voice)
#al5audio.al_attach_sample_instance_to_voice
Attaches a sample instance to a voice, and allows it to play. The instance's gain and loop mode will be ignored, and it must have the same frequency, channel configuration and depth (including signed-ness) as the voice. This function may fail if the selected driver doesn't support preloading sample data.

At this time, we don't recommend attaching sample instances directly to voices. Use a mixer inbetween.
@return(@true on success, @false on failure.) seealso(al_detach_voice)
#al5audio.al_attach_audio_stream_to_voice
Attaches an audio stream to a voice. The same rules as @link(al_attach_sample_instance_to_voice) apply. This may fail if the driver can't create a voice with the buffer count and buffer size the stream uses.

An audio stream attached directly to a voice has a number of limitations: The audio stream plays immediately and cannot be stopped. The stream position, speed, gain and panning cannot be changed. At this time, we don't recommend attaching audio streams directly to voices. Use a mixer inbetween.
@returns(@true on success, @false on failure.) @seealso(al_detach_voice)
#al5audio.al_attach_mixer_to_voice
Attaches a mixer to a voice. It must have the same frequency and channel configuration, but the depth may be different.
@Return(@true on success, @false on failure.) @seealso(al_detach_voice)
#al5audio.al_detach_voice
Detaches the mixer, sample instance or audio stream from the voice.
@seealso(al_attach_mixer_to_voice) @seealso(al_attach_sample_instance_to_voice) @seealso(al_attach_audio_stream_to_voice)

#al5audio.al_get_voice_frequency
Returns the frequency of the voice (in Hz), e.g. 44100.
#al5audio.al_get_voice_position
When the voice has a non-streaming object attached to it, e.g. a sample, returns the voice's current sample position. Otherwise, returns zero.
@seealso(al_set_voice_position)
#al5audio.al_get_voice_channels
Returns the channel configuration of the voice.
@seealso(ALLEGRO_CHANNEL_CONF)
#al5audio.al_get_voice_depth
Returns the audio depth of the voice.
@seealso(ALLEGRO_AUDIO_DEPTH)
#al5audio.al_get_voice_playing
Returns @true if the voice is currently playing.
@seealso(al_set_voice_playing)
#al5audio.al_set_voice_position
Sets the voice position. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance.
@return(@true on success, @false on failure.) @seealso(al_get_voice_position)
#al5audio.al_set_voice_playing
Changes whether a voice is playing or not. This can only work if the voice has a non-streaming object attached to it, e.g. a sample instance. On success the voice's current sample position is reset.
@return(@true on success, @false on failure.) @seealso(al_get_voice_playing)

#al5audio.al_install_audio
Installs the audio subsystem.

@bold(Note)

most users will call @code(al_reserve_samples) and @code(al_init_acodec_addon) after this.
@return(@true on success, @false on failure.)
@seealso(al_reserve_samples) @seealso(al_uninstall_audio) @seealso(al_is_audio_installed) @seealso(al_init_acodec_addon) *)
#al5audio.al_uninstall_audio
Uninstalls the audio subsystem. @seealso(al_install_audio)
#al5audio.al_is_audio_installed
Returns @true if @link(al_install_audio) was called previously and returned successfully.
#al5audio.al_get_allegro_audio_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).

#al5audio.al_get_channel_count
Returns the number of channels for the given channel configuration, which is one of the values listed under @link(ALLEGRO_CHANNEL_CONF).
#al5audio.al_get_audio_depth_size
Returns the size of a sample, in bytes, for the given format. The format is one of the values listed under @link(ALLEGRO_AUDIO_DEPTH).

#al5audio.al_fill_silence
Fills a buffer with silence, for the given format and channel configuration. The buffer must have enough space for the given number of samples, and be properly aligned.

#al5audio.al_get_num_audio_output_devices
Gets the number of available audio output devices on the system.
@return(@code(-1) for unsupported drivers.)
@seealso(al_get_audio_output_device)
#al5audio.al_get_audio_output_device
Gets the output audio device of the specified @code(index).
@seealso(al_get_num_audio_output_devices) @seealso(al_get_audio_device_name)
#al5audio.al_get_audio_device_name
Gets the user friendly display name of the device.
@seealso(al_get_audio_output_device)

#al5audio.al_reserve_samples
Reserves a number of sample instances, attaching them to the default mixer. If no default mixer is set when this function is called, then it will create one and attach it to the default voice. If no default voice has been set, it, too, will be created.

This diagram illustrates the structures that are set up:
@preformatted(
                                      sample instance 1
                                    / sample instance 2
default voice <-- default mixer <---         .
                                    \        .
                                      sample instance N
)
@return(@true on success, @false on error. @link(al_install_audio) must have been called first.)
@seealso(al_set_default_mixer) @seealso(al_play_sample)
#al5audio.al_get_default_mixer
Returns the default mixer, or @nil if one has not been set. Although different configurations of mixers and voices can be used, in most cases a single mixer attached to a voice is what you want. The default mixer is used by @link(al_play_sample).
@seealso(al_reserve_samples) @seealso(al_play_sample) @seealso(al_set_default_mixer) @seealso(al_restore_default_mixer)
#al5audio.al_set_default_mixer
Sets the default mixer. All samples started with @link(al_play_sample) will be stopped and all sample instances returned by @link(al_lock_sample_id) will be invalidated. If you are using your own mixer, this should be called before @link(al_reserve_samples).
@return(@true on success, @false on error.)
@seealso(al_reserve_samples) @seealso(al_play_sample) @seealso(al_get_default_mixer) @seealso(al_restore_default_mixer)
#al5audio.al_restore_default_mixer
Restores Allegro's default mixer and attaches it to the default voice. If the default mixer hasn't been created before, it will be created. If the default voice hasn't been set via @link(al_set_default_voice) or created before, it will also be created. All samples started with @link(al_play_sample) will be stopped and all sample instances returned by @link(al_lock_sample_id) will be invalidated.
@return(@true on success, @false on error.)
@seealso(al_get_default_mixer) @seealso(al_set_default_mixer) @seealso(al_reserve_samples)
#al5audio.al_play_sample
Plays a sample on one of the sample instances created by @link(al_reserve_samples).
@param(gain relative volume at which the sample is played; 1.0 is normal.)
@param(pan 0.0 is centred, -1.0 is left, 1.0 is right, or @code(ALLEGRO_AUDIO_PAN_NONE).)
@param(speed relative speed at which the sample is played; 1.0 is normal.)
@param(loop @code(ALLEGRO_PLAYMODE_ONCE), @code(ALLEGRO_PLAYMODE_LOOP), or
  	  @code(ALLEGRO_PLAYMODE_BIDIR).)
@param(ret_id if non-@nil the variable which this points to will be assigned
	  an id representing the sample being played.)
@return(@true on success, @false on failure. Playback may fail because all
	   the reserved sample instances are currently used.)
@seealso(ALLEGRO_PLAYMODE) @seealso(ALLEGRO_AUDIO_PAN_NONE)
@seealso(ALLEGRO_SAMPLE_ID) @seealso(al_stop_sample)
@seealso(al_stop_samples)
#al5audio.al_stop_sample
Stops the sample started by @link(al_play_sample). @seealso(al_stop_samples)
#al5audio.al_stop_samples
Stops all samples started by @link(al_play_sample). @seealso(al_stop_sample)
#al5audio.al_get_default_voice
Returns the default voice or @nil if there is none. @seealso(al_get_default_mixer)
#al5audio.al_set_default_voice
You can call this before calling @link(al_restore_default_mixer) to provide the voice which should be used. Any previous voice will be destroyed. You can also pass @nil to destroy the current default voice.
@seealso(al_get_default_mixer)

#al5audio.al_lock_sample_id
Locks a @link(ALLEGRO_SAMPLE_ID), returning the underlying @link(ALLEGRO_SAMPLE_INSTANCEptr). This allows you to adjust the various properties of the instance (such as volume, pan, etc) while the sound is playing.

This function will return @nil if the sound corresponding to the id is no longer playing.

While locked, @code(ALLEGRO_SAMPLE_ID) will be unavailable to additional calls to @link(al_play_sample), even if the sound stops while locked. To put the @code(ALLEGRO_SAMPLE_ID) back into the pool for reuse, make sure to call @link(al_unlock_sample_id) when you're done with the instance.

@bold(Unstable API:) New API.
@seealso(al_play_sample) @seealso(al_unlock_sample_id)
#al5audio.al_unlock_sample_id
Unlocks a @link(ALLEGRO_SAMPLE_ID), allowing future calls to @link(al_play_sample) to reuse it if possible. Note that after the id is unlocked, the @link(ALLEGRO_SAMPLE_INSTANCEptr) that was previously returned by @link(al_lock_sample_id) will possibly be playing a different sound, so you should only use it after locking the id again.

@bold(Unstable API:) New API.
@seealso(al_play_sample) @seealso(al_lock_sample_id)

#al5audio.al_register_sample_loader
Registers a handler for @link(al_load_sample). The given function will be used to handle the loading of sample files with the given extension.

The extension should include the leading dot (@code('.')) character. It will be matched case-insensitively.

The @code(loader) argument may be @nil to unregister an entry.
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_sample_loader_f) @seealso(al_register_sample_saver)
#al5audio.al_register_sample_saver
Registers a handler for @link(al_save_sample). The given function will be used to handle the saving of sample files with the given extension.

The extension should include the leading dot (@code('.')) character. It will be matched case-insensitively.

The @code(saver) argument may be @nil to unregister an entry.
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_sample_saver_f) @seealso(al_register_sample_loader)
#al5audio.al_register_audio_stream_loader
Registers a handler for @link(al_load_audio_stream). The given function will be used to open streams from files with the given extension.

The extension should include the leading dot (@code('.')) character. It will be matched case-insensitively.

The @code(stream_loader) argument may be @nil to unregister an entry.
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_audio_stream_loader_f)

#al5audio.al_register_sample_loader_f
Registers a handler for @link(al_load_sample_f). The given function will be used to handle the loading of sample files with the given extension.

The extension should include the leading dot (@code('.')) character. It will be matched case-insensitively.

The @code(loader) argument may be @nil to unregister an entry.
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_sample_loader)
#al5audio.al_register_sample_saver_f
Registers a handler for @link(al_save_sample_f). The given function will be used to handle the saving of sample files with the given extension.

The extension should include the leading dot (@code('.')) character. It will be matched case-insensitively.

The @code(saver) argument may be @nil to unregister an entry.

@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_sample_saver)
#al5audio.al_register_audio_stream_loader_f
Registers a handler for @link(al_load_audio_stream_f). The given function will be used to open streams from files with the given extension.

The extension should include the leading dot (@code('.')) character. It will be matched case-insensitively.

The @code(stream_loader) argument may be @nil to unregister an entry.
@return(@true on success, @false on error. Returns @false if unregistering an entry that doesn't exist.)
@seealso(al_register_audio_stream_loader)

#al5audio.al_register_sample_identifier
Registers an identify handler for al_identify_sample. The given function will be used to detect files for the given extension. It will be called with a single argument of type @link(ALLEGRO_FILEptr) which is a file handle opened for reading and located at the first byte of the file. The handler should try to read as few bytes as possible to safely determine if the given file contents correspond to the type with the extension and return true in that case, false otherwise. The file handle must not be closed but there is no need to reset it to the beginning.

The extension should include the leading dot (‘.’) character. It will be matched case-insensitively.

The identifier argument may be @nil to unregister an entry.
@returns(@true on success, @false on error. It returns @false if unregistering an entry that doesn’t exist.)
@seealso(al_identify_bitmap)

#al5audio.al_load_sample
Loads a few different audio file formats based on their extension.

Note that this stores the entire file in memory at once, which may be time
consuming. To read the file as it is needed, use @link(al_load_audio_stream).

@bold(Note)

the @code(al5audio) unit does not support any audio file
formats by default. You must use the @link(al5acodec) addon, or register
your own format handler.
@return(The sample on success, @nil on failure.)
@seealso(al_register_sample_loader) @seealso(al_init_acodec_addon)
#al5audio.al_save_sample
Writes a sample into a file. Currently, wav is the only supported format, and the extension must be @code('.wav').

@bold(Note)

the @code(al5acodec) unit does not support any audio file formats by default. You must use the @link(al5acodec) addon, or register your own format handler.
@return(@true on success, @false on error.)
@seealso(al_save_sample_f) @seealso(al_register_sample_saver) @seealso(al_init_acodec_addon)
#al5audio.al_load_audio_stream
Loads an audio file from disk as it is needed.

Unlike regular streams, the one returned by this function need not be fed by
the user; the library will automatically read more of the file as it is
needed. The stream will contain @code(buffer_count) buffers with
@code(samples) samples.

The audio stream will start in the playing state. It should be attached to a
voice or mixer to generate any output. See @link(ALLEGRO_AUDIO_STREAMptr)
for more details.

@bold(Note)

the @code(al5audio) library does not support any audio file
formats by default. You must use the @link(al5acodec) addon, or register
your own format handler.
@return(the stream on success, @nil on failure.)
@seealso(al_load_audio_stream_f) @seealso(al_register_audio_stream_loader) @seealso(al_init_acodec_addon)

#al5audio.al_load_sample_f
Loads an audio file from an @link(ALLEGRO_FILEptr) tream into an @link(ALLEGRO_SAMPLEptr). The file type is determined by the passed @code(ident) parameter, which is a file name extension including the leading dot.

Note that this stores the entire file in memory at once, which may be time consuming. To read the file as it is needed, use @link(al_load_audio_stream_f).

@bold(Note)

the @link(al5audio) add-on does not support any audio file formats by default. You must use the @link(al5acodec) addon, or register your own format handler.
@return(the sample on success, @nil on failure. The file remains open afterwards.)
@seealso(al_register_sample_loader_f) @seealso(al_init_acodec_addon)
#al5audio.al_save_sample_f
Writes a sample into a @link(ALLEGRO_FILEptr) filestream. Currently, wav is the only supported format, and the extension must be @code('.wav').

@bold(Note)

the @link(al5audio) add-on does not support any audio file formats by default. You must use the @link(al5acodec) addon, or register your own format handler.
@return(@true on success, @false on error. The file remains open afterwards.)
@seealso(al_save_sample) @seealso(al_register_sample_saver_f) @seealso(al_init_acodec_addon)
#al5audio.al_load_audio_stream_f
Loads an audio file from @link(ALLEGRO_FILEptr) stream as it is needed.

Unlike regular streams, the one returned by this function need not be fed by the user; the library will automatically read more of the file as it is needed. The stream will contain @code(buffer_count) buffers with samples samples.

The file type is determined by the passed @code(ident) parameter, which is a file name extension including the leading dot.

The audio stream will start in the playing state. It should be attached to a voice or mixer to generate any output. See @link(ALLEGRO_AUDIO_STREAMptr) for more details.

@bold(Note)

the @link(al5audio) library does not support any audio file formats by default. You must use the @link(al5acodec) addon, or register your own format handler.
@return(the stream on success, @nil on failure. On success the file should be considered owned by the audio stream, and will be closed when the audio stream is destroyed. On failure the file will be closed.)
@seealso(al_load_audio_stream) @seealso(al_register_audio_stream_loader_f) @seealso(al_init_acodec_addon)

#al5audio.al_identify_sample
This works exactly as @link(al_identify_sample_f) but you specify the filename of the file for which to detect the type and not a file handle.  The extension, if any, of the passed filename is not taken into account - only the file contents.
@seealso(al_init_acodec_addon) @seealso(al_identify_sample_f) @seealso(al_register_sample_identifier)

#al5audio.al_identify_sample_f
Tries to guess the audio file type of the open @link(ALLEGRO_FILEptr) by reading the first few bytes.  By default Allegro cannot recognize any file types, but calling @code(al_init_acodec_addon) will add detection of the types it can read.  You can also use @code(al_register_sample_identifier) to add identification for custom file types.

@return(a pointer to a static string with a file extension for the type, including the leading dot. For example @code('.wav') or @code('.ogg).  Returns @nil if the audio type cannot be determined.)
@seealso(al_init_acodec_addon) @code(al_identify_sample) @code(al_register_sample_identifier)

#al5audio.al_create_audio_recorder
Creates an audio recorder using the system's default recording device. (So if the returned device does not work, try updating the system's default recording device.)

Allegro will internally buffer several seconds of captured audio with minimal latency. (XXX: These settings need to be exposed via config or API calls.) Audio will be copied out of that private buffer into a fragment buffer of the size specified by the samples parameter. Whenever a new fragment is ready an event will be generated.

The total size of the fragment buffer is fragment_count * samples * bytes_per_sample. It is treated as a circular, never ending buffer. If you do not process the information fast enough, it will be overrun. Because of that, even if you only ever need to process one small fragment at a time, you should still use a large enough value for @code(fragment_count) to hold a few seconds of audio.

@code(frequency) is the number of samples per second to record. Common values are:
@unorderedlist(
  @item(8000 - telephone quality speech)
  @item(11025)
  @item(22050)
  @item(44100 - CD quality music @(if 16-bit, stereo@))
)
For maximum compatibility, use a depth of @code(ALLEGRO_AUDIO_DEPTH_UINT8) or @link(ALLEGRO_AUDIO_DEPTH_INT16), and a single (mono) channel.

The recorder will not record until you start it with @link(al_start_audio_recorder).

@bold(Unstable API:) The API may need a slight redesign.
@return(Pointer to recorder control object or @nil on failure.)
@seealso(al_start_audio_recorder) @seealso(al_get_audio_recorder_event_source) @seealso(al_destroy_audio_recorder)
#al5audio.al_start_audio_recorder
Begin recording into the fragment buffer. Once a complete fragment has been captured (as specified in @link(al_create_audio_recorder)), an @link(ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT) event will be triggered.
@return(@true if it was able to begin recording.)

@bold(Unstable API:) The API may need a slight redesign.
@seealso(al_stop_audio_recorder) @seealso(al_get_audio_recorder_event_source)
#al5audio.al_stop_audio_recorder
Stop capturing audio data. Note that the audio recorder is still active and consuming resources, so if you are finished recording you should destroy it with @link(al_destroy_audio_recorder).

You may still receive a few events after you call this function as the device flushes the buffer.

If you restart the recorder, it will begin recording at the beginning of the next fragment buffer.
@seealso(al_start_audio_recorder)
#al5audio.al_is_audio_recorder_recording
Returns @true if the audio recorder is currently capturing data and generating events.

@bold(Unstable API:) The API may need a slight redesign.
#al5audio.al_get_audio_recorder_event_source
Returns the event source for the recorder that generates the various recording events.

@bold(Unstable API:) The API may need a slight redesign.
@seealso(al_get_audio_recorder_event)
#al5audio.al_get_audio_recorder_event
Returns the event as an @link(ALLEGRO_AUDIO_RECORDER_EVENT).

@bold(Unstable API:) The API may need a slight redesign.
#al5audio.al_destroy_audio_recorder
Destroys the audio recorder and frees all resources associated with it. It is safe to destroy a recorder that is recording.

You may receive events after the recorder has been destroyed. They must be ignored, as the fragment buffer will no longer be valid.

@bold(Unstable API:) The API may need a slight redesign.



#al5color.al_get_allegro_color_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).
#al5color.al_color_hsv_to_rgb
Converts values in HSV color model to RGB color model.
@param(h Color hue angle in the range 0..360.)
@param(s Color saturation in the range 0..1.)
@param(v Color value in the range 0..1.)
@param(r Returns the R @(red@) value in the range 0..1.)
@param(g Returns the G @(green@) value in the range 0..1.)
@param(b Returns the B @(blue@) value in the range 0..1.)
@seealso(al_color_rgb_to_hsv) @seealso(al_color_hsv) @seealso(al_color_hsl_to_rgb)
#al5color.al_color_rgb_to_hsl
Given an RGB triplet with components in the range 0..1, returns the hue in degrees from 0..360 and saturation and lightness in the range 0..1.
@seealso(al_color_hsl_to_rgb) @seealso(al_color_hsl)
#al5color.al_color_rgb_to_hsv
Given an RGB triplet with components in the range 0..1, returns the hue in degrees from 0..360 and saturation and value in the range 0..1.
@seealso(al_color_hsv_to_rgb) @seealso(al_color_hsv)
#al5color.al_color_hsl_to_rgb
Converts values in HSL color model to RGB color model.
@param(h Color hue angle in the range 0..360.)
@param(s Color saturation in the range 0..1.)
@param(l Color lightness in the range 0..1.)
@param(r Returns the R @(red@) value in the range 0..1.)
@param(g Returns the G @(green@) value in the range 0..1.)
@param(b Returns the B @(blue@) value in the range 0..1.)
@seealso(al_color_rgb_to_hsl) @seealso(al_color_hsl) @seealso(al_color_hsv_to_rgb)
#al5color.al_color_name_to_rgb
Given a name, returns the RGB triplet.

The 148 recognized names are:

aliceblue, antiquewhite, aqua, aquamarine, azure, beige, bisque, black, blanchedalmond, blue, blueviolet, brown, burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, dodgerblue, firebrick, floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, goldenrod, gold, gray, green, greenyellow, honeydew, hotpink, indianred, indigo, ivory, khaki, lavenderblush, lavender, lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, lightslategray, lightsteelblue, lightyellow, lime, limegreen, linen, magenta, maroon, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, avajowhite, navy, oldlace, olive, olivedrab, orange, orangered, orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, purple, rebeccapurple, red, rosybrown, royalblue, saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, silver, skyblue, slateblue, slategray, snow, springgreen, steelblue, tan, teal, thistle, tomato, turquoise, violet, wheat, white, whitesmoke, yellow, yellowgreen

They are taken from CSS: @html(<a href="https://www.w3.org/TR/css-color-4/">https://www.w3.org/TR/css-color-4/</a>).

Note that these 9 colors have two names and so there are only 139 distinct colors: aqua = cyan, darkgray = darkgrey, darkslategray = darkslategrey, dimgray = dimgrey, fuchsia = purple, gray = grey, lightgray = lightgrey, lightslategray = lightslategrey, slategray = slategrey
@param(name The lowercase name of the color.)
@param(r Returns the R @(red@) value in the range 0..1.)
@param(g Returns the G @(green@) value in the range 0..1.)
@param(b Returns the B @(blue@) value in the range 0..1.)
@return(@true if a name from the list above was passed, else @false.)
@seealso(al_color_name) @seealso(al_color_rgb_to_name)
#al5color.al_color_rgb_to_name
Given an RGB triplet with components in the range 0..1, find a color name describing it approximately.
@seealso(al_color_name_to_rgb) @seealso(al_color_name)
#al5color.al_color_cmyk_to_rgb
Converts CMYK values to RGB values.
@seealso(al_color_cmyk) @seealso(al_color_rgb_to_cmyk)
#al5color.al_color_rgb_to_cmyk
Each RGB color can be represented in CMYK with a K component of 0 with the following formula:
@preformatted(
C = 1 - R
M = 1 - G
Y = 1 - B
K = 0
)
This function will instead find the representation with the maximal value for K and minimal color components.
@seealso(al_color_cmyk) @seealso(al_color_cmyk_to_rgb)
#al5color.al_color_yuv_to_rgb
Converts YUV color values to RGB color space.
@seealso(al_color_yuv) @seealso(al_color_rgb_to_yuv)
#al5color.al_color_rgb_to_yuv
Converts RGB values to YUV color space.
@seealso(al_color_yuv) @seealso(al_color_yuv_to_rgb)
#al5color.al_color_rgb_to_html
Creates an HTML-style string representation of an RGB triplet, e.g. @code(#00FAFF).

Example:

@longcode(#
VAR
  HTMLstring: STRING;
BEGIN
  HTMLstring := al_color_rgb_to_html (1, 0, 0);
#)
Now @code(HTMLstring) will contain "#ff0000".
@seealso(al_color_html) @seealso(al_color_html_to_rgb)
#al5color.al_color_html_to_rgb
Interprets an HTML-style hex number (e.g. @code(#00FAFF)) as a color. The only accepted formats are "#RRGGBB" and "RRGGBB" where R, G, B are hexadecimal digits @code([0-9A-Fa-f]).

@bold(Note)

the behaviour on invalid strings is different from Allegro 5.0.x.
@return(@true on success, @false on failure. On failure all components are set to zero.)
@seealso(al_color_html) @seealso(al_color_rgb_to_html)
#al5color.al_color_yuv
Returns an @link(ALLEGRO_COLOR) structure from YUV values.
@seealso(al_color_yuv_to_rgb) @seealso(al_color_rgb_to_yuv)
#al5color.al_color_cmyk
Returns an @link(ALLEGRO_COLOR) structure from CMYK values (cyan, magenta, yellow, black).
@seealso(al_color_cmyk_to_rgb) @seealso(al_color_rgb_to_cmyk)
#al5color.al_color_hsl
Returns an @link(ALLEGRO_COLOR) structure from HSL (hue, saturation, lightness) values.
@param(h Color hue angle in the range @code(0..360).)
@param(s Color saturation in the range @code(0..1).)
@param(l Color lightness in the range @code(0..1).)
@seealso(al_color_hsl_to_rgb) @seealso(al_color_hsv)
#al5color.al_color_hsv
Returns an @link(ALLEGRO_COLOR) structure from HSV (hue, saturation, value) values.
@param(h Color hue angle in the range @code(0..360).)
@param(s Color saturation in the range @code(0..1).)
@param(v Color value in the range @code(0..1).)
@seealso(al_color_hsv_to_rgb) @seealso(al_color_hsl)
#al5color.al_color_name
Returns an @link(ALLEGRO_COLOR) with the given name. If the color is not found then black is returned.

See @link(al_color_name_to_rgb) for the list of names.
#al5color.al_color_html
Interprets an HTML-style hex number (e.g. @code(#00FAFF) as a color. The accepted format is the same as @link(al_color_html_to_rgb).

@bold(Note)

the behaviour on invalid strings is different from Allegro 5.0.x.
@return(the interpreted color, or @code(@link(al_map_rgba) @(0, 0, 0, 0@)) if the string could not be parsed.)
@seealso(al_color_html_to_rgb) @seealso(al_color_rgb_to_html)
#al5color.al_color_xyz_to_rgb
Converts XYZ color values to RGB color space.
@seealso(al_color_xyz) @seealso(al_color_rgb_to_xyz)
#al5color.al_color_rgb_to_xyz
Converts RGB values to XYZ color space.
@seealso(al_color_xyz) @seealso(al_color_xyz_to_rgb)
#al5color.al_color_xyz
Returns an @link(ALLEGRO_COLOR) structure from XYZ values. The CIE 1931 XYZ color space consists of three components in the range @code(0..1). The Y component corresponds to luminance and the X and Z components define the color.

RGB components are always assumed to be in sRGB space.

@bold(Note)

The XYZ color space can represent more colors than are visible in sRGB and therefore conversion may result in RGB values outside of the @code(0..1) range. You can check for that case with @link(al_is_color_valid).
@seealso(al_color_xyz_to_rgb) @seealso(al_color_rgb_to_xyz)
#al5color.al_color_lab_to_rgb
Converts CIE L*a*b* color values to RGB color space.
@seealso(al_color_lab) @seealso(al_color_rgb_to_lab)
#al5color.al_color_rgb_to_lab
Converts RGB values to L*a*b color space.
@seealso(al_color_lab) @seealso(al_color_lab_to_rgb)
#al5color.al_color_lab
Returns an @link(ALLEGRO_COLOR) structure from CIE L*a*b* values. The L* component corresponds to luminance from @code(0..1). The a* and b* components are in the range @code(-1..+1).

@bold(Note)

The L*a*b* color space can represent more colors than are visible in sRGB and therefore conversion may result in RGB values outside of the @code(0..1) range. You can check for that case with @link(al_is_color_valid).

@bold(Note)

In some literature the range of L* is 0 to 100 and a* and b* are from -100 to +100. In that case divide all components by 100 before passing them to this function.
@seealso(al_color_lab_to_rgb) @seealso(al_color_rgb_to_lab)
#al5color.al_color_xyy_to_rgb
Converts xyY color values to RGB color space.
@seealso(al_color_xyy) @seealso(al_color_rgb_to_xyy)
#al5color.al_color_rgb_to_xyy
Converts RGB values to xyY color space.
@seealso(al_color_xyy) @seealso(al_color_xyy_to_rgb)
#al5color.al_color_xyy
Returns an @link(ALLEGRO_COLOR) structure from xyY values. The Y component in the xyY color space is the same as the Y in XYZ.

However the x and y values are computed from XYZ like this:
@preformatted(
x = X / @(X + Y + Z@)
y = Y / @(X + Y + Z@)
)
@seealso(al_color_xyy_to_rgb) @seealso(al_color_rgb_to_xyy)
#al5color.al_color_distance_ciede2000
This function computes the CIEDE2000 color difference between two RGB colors. This is a visually uniform color difference, unlike for example the RGB distance.

When using the RGB distance (Euklidean distance between two RGB triplets) there can be color pairs with the same distance, where the colors of one pair appear to be almost the same color, while the colors of the other pair look quite different. This is improved by using the L*a*b* color space which was designed with perceptual uniformity in mind. However it still is not completely uniform. The CIEDE2000 formula contains some additional transformations to fix that.

The returned color distance is roughly in the range 0 (identical color) to 1 (completely different color) - but values greater than one are possible.

@bold(Note)

This function uses @link(al_color_lab) internally which defines the L component to be in the range @code(0..1) (and not @code(0..100) as is sometimes seen).
#al5color.al_color_lch_to_rgb
Converts CIE LCH color values to RGB color space.
@seealso(al_color_lch) @seealso(al_color_rgb_to_lch)
#al5color.al_color_rgb_to_lch
Convert RGB values to CIE LCH color space.
@seealso(al_color_lch) @seealso(al_color_lch_to_rgb)
#al5color.al_color_lch
Returns an @link(ALLEGRO_COLOR) structure from CIE LCH values. LCH colors are very similar to HSL, with the same meaning of L and H and C corresponding to S. However LCH is more visually uniform. Furthermore, this function expects the angle for H in radians and not in degree.

The CIE LCH color space is a cylindrical representation of the L*a*b* color space. The L component is the same and C and H are computed like this:
@preformatted(
C = sqrt @(a * a + b * b@)
H = atan2 @(b, a@)
)
@seealso(al_color_lch_to_rgb) @seealso(al_color_rgb_to_lch)
#al5color.al_is_color_valid
Checks if all components of the color are between 0 and 1. Some of the color conversions in this addon support color spaces with more colors than can be represented in sRGB and when converted to RGB will result in invalid color components outside the @code(0..1) range.

#al5color.al_color_rgb_to_linear
Converts gamma corrected sRGB values (i.e. normal RGB) to linear sRGB space.
@seealso(al_color_linear) @seealso(al_color_linear_to_rgb)
#al5color.al_color_linear
Returns an @link(ALLEGRO_COLOR) structure from linear sRGB values. Allegro RGB values are assumed to be sRGB. The sRGB standard is in wide use by various display devices. It accounts for a standard gamma correction applied to RGB colors before they get displayed.

Gamma correction means if for example we have a medium gray color specified with @code(@link(al_map_rgb_f) @(0.5,0.5,0.5@)) then we do not want the monitor to set the pixel to exactly half the physical maximum intensity, but instead to an intensity that appears to be half as bright as the maximum to the person looking at it. In this case that would be closer to 21% of maximum intensity rather than to 50% intensity.

For some applications it may be useful to specify a color in linear sRGB components, in which case you can use this function. For example:
@longcode(#
var
  Gray: ALLEGRO_COLOR;
  Htm: String;
begin
  ...
  gray = al_color_linear (0.216, 0.216, 0.216);
  al_color_rgb_to_html (gray.r, gray.g, gray.b, html); { #808080 }
  ...
end.
#)
@seealso(al_color_linear_to_rgb) @seealso(al_color_rgb_to_linear)
#al5color.al_color_linear_to_rgb
Converts linear sRGB color values to gamma corrected (i.e. normal) RGB values.
@seealso(al_color_linear) @seealso(al_color_rgb_to_linear)

#al5font.ALLEGRO_FONTptr
A handle identifying any kind of font. Usually you will create it with @link(al_load_font) which supports loading all kinds of TrueType fonts supported by the FreeType library. If you instead pass the filename of a bitmap file, it will be loaded with @link(al_load_bitmap) and a font in Allegro's bitmap font format will be created from it with @link(al_grab_font_from_bitmap).

#al5font.al_load_bitmap_font
Load a bitmap font from a file. This is done by first calling @link(al_load_bitmap_flags) and then @link(al_grab_font_from_bitmap).

If you wanted to load an old A4 font, for example, it would be better to load the bitmap yourself in order to call @link(al_convert_mask_to_alpha) on it before passing it to @link(al_grab_font_from_bitmap).
@seealso(al_load_bitmap_font_flags) @seealso(al_load_font) @seealso(al_load_bitmap_flags)
#al5font.al_load_bitmap_font_flags
Like @link(al_load_bitmap_font) but additionally takes a flags parameter.  The flags parameter is a bitfield containing a combination of the following:
@definitionlist(
@itemlabel(ALLEGRO_NO_PREMULTIPLIED_ALPHA) @item(The same meaning as for al_load_bitmap_flags.)
)
@seealso(al_load_bitmap_font) @seealso(al_load_bitmap_flags)
#al5font.al_load_font
Loads a font from disk. This will use @link(al_load_bitmap_font_flags) if you pass the name of a known bitmap format, or else @link(al_load_ttf_font).

The flags parameter is passed through to either of those functions. Bitmap and TTF fonts are also affected by the current bitmap flags at the time the font is loaded.
@seealso(al_destroy_font) @seealso(al_init_font_addon) @seealso(al_load_bitmap_font_flags) @seealso(al_load_ttf_font)

#al5font.al_grab_font_from_bitmap
Creates a new font from an Allegro bitmap. You can delete the bitmap after  the function returns as the font will contain a copy for itself.

The bitmap format is as in the following example, which contains three glyphs for 1, 2 and 3.
@preformatted(
.............
. 1 .222.333.
. 1 .  2.  3.
. 1 .222.333.
. 1 .2  .  3.
. 1 .222.333.
.............
)
In the above illustration, the dot is for pixels having the background color. It is determined by the color of the top left pixel in the bitmap. There should be a border of at least 1 pixel with this color to the bitmap edge and between all glyphs.

Each glyph is inside a rectangle of pixels not containing the background color. The height of all glyph rectangles should be the same, but the width can vary.

The placement of the rectangles does not matter, except that glyphs are scanned from left to right and top to bottom to match them to the specified unicode codepoints.

The glyphs will simply be drawn using @link(al_draw_bitmap), so usually you will want the rectangles filled with full transparency and the glyphs drawn in opaque white.

@bold(Examples:)
@longcode(#
VAR
  Ranges: ARRAY [0..1] OF AL_INT = (32, 126);
  TextFont: ALLEGRO_FONTptr;
BEGIN
  TextFont := al_grab_font_from_bitmap (Bitmap, 1, Ranges)
END;

VAR
  Ranges: ARRAY [0..7] OF AL_INT = (
    $0020, $007F,  { ASCII }
    $00A1, $00FF,  { Latin 1 }
    $0100, $017F,  { Extended-A }
    $20AC, $20AC   { Euro }
  );
  TextFont: ALLEGRO_FONTptr;
BEGIN
  TextFont := al_grab_font_from_bitmap (Bitmap, 4, Ranges)
END;
#)
The first example will grab glyphs for the 95 standard printable ASCII characters, beginning with the space character (32) and ending with the tilde character (126).  The second example will map the first 96 glyphs found in the bitmap to ASCII range, the next 95 glyphs to Latin 1, the next 128 glyphs to Extended-A, and the last glyph to the Euro character. (This is just the characters found in the Allegro 4 font.)
@param(bmp The bitmap with the glyphs drawn onto it.)
@param(n Number of unicode ranges in the bitmap.)
@param(ranges @italic(n) pairs of first and last unicode point to map glyphs to for each range.)
@seealso(al_load_bitmap)
#al5font.al_create_builtin_font
Creates a monochrome bitmap font (8x8 pixels per character).

This font is primarily intended to be used for displaying information in environments or during early runtime states where no external font data is available or loaded (e.g. for debugging).

The builtin font contains the following unicode character ranges:
@preformatted(
0x0020 to 0x007F @(ASCII@)
0x00A1 to 0x00FF @(Latin 1@)
0x0100 to 0x017F @(Extended A@)
0x20AC to 0x20AC @(euro currency symbol@)
)
The font memory must be freed the same way as for any other font, using @link(al_destroy_font).
@return(@nil on an error.)
@seealso(al_load_bitmap_font) @seealso(al_destroy_font)

#al5font.al_draw_ustr
Like @link(al_draw_text), except the text is passed as an @link(ALLEGRO_USTR) instead of a @code(STRING).
@seealso(al_draw_text) @seealso(al_draw_justified_ustr) @seealso(al_draw_multiline_ustr)
#al5font.al_draw_text
Writes the string @code(str) onto the target bitmap at position @code(x), @code(y), using the specified @code(font).

The flags parameter can be 0 or one of the following flags:@unorderedlist(
  @item(@bold(@code(ALLEGRO_ALIGN_LEFT)) - Draw the text left-aligned @(same as 0@).)
  @item(@bold(@code(ALLEGRO_ALIGN_CENTRE)) - Draw the text centered around the given position.)
  @item(@bold(@code(ALLEGRO_ALIGN_RIGHT)) - Draw the text right-aligned to the given position.)
)
It can also be combined with this flag:@unorderedlist(
   @item(@bold(@code(ALLEGRO_ALIGN_INTEGER)) - Always draw text aligned to an integer pixel position. This was formerly the default behaviour.)
)
This function does not support newline characters (#10), but you can use @link(al_draw_multiline_text) for multi line text output.
@seealso(al_draw_ustr) @seealso(al_draw_justified_text) @seealso(al_draw_multiline_text)
#al5font.al_draw_justified_text
Like @link(al_draw_text), but justifies the string to the region @code(x1-x2).

The @code(diff) parameter is the maximum amount of horizontal space to allow between words. If justisfying the text would exceed diff pixels, or the string contains less than two words, then the string will be drawn left aligned.

The @code(flags) parameter can be 0 or one of the following flags:
@unorderedlist(
  @item(@bold(code(ALLEGRO_ALIGN_INTEGER)) - Draw text aligned to integer pixel positions.)
)
@seealso(al_draw_justified_textf) @seealso(al_draw_justified_ustr)
#al5font.al_draw_justified_ustr
Like @link(al_draw_justified_text), except the text is passed as an @link(ALLEGRO_USTR) instead of a @code(STRING).
@seealso(al_draw_justified_text) @seealso(al_draw_justified_textf)
#al5font.al_draw_textf
Formatted text output, using a @code(Format) style format string. All parameters have the same meaning as with @link(al_draw_text) otherwise.
@seealso(al_draw_text) @seealso(al_draw_ustr)
#al5font.al_draw_justified_textf
Formatted text output, using a @code(Format) style format string. All parameters have the same meaning as with @link(al_draw_justified_text) otherwise.
@seealso(al_draw_justified_text) @seealso(al_draw_justified_ustr)
#al5font.al_get_text_width
Calculates the length of a string in a particular font, in pixels.
@seealso(al_get_ustr_width) @seealso(al_get_font_line_height) @seealso(al_get_text_dimensions)
#al5font.al_get_ustr_width
Like @link(al_get_text_width) but expects an @link(ALLEGRO_USTR).
@seealso(al_get_text_width) @seealso(al_get_ustr_dimensions)
#al5font.al_get_font_line_height
Returns the usual height of a line of text in the specified font. For bitmap fonts this is simply the height of all glyph bitmaps. For truetype fonts it is whatever the font file specifies. In particular, some special glyphs may be higher than the height returned here.

If the X is the position you specify to draw text, the meaning of ascent and descent and the line height is like in the figure below.
@preformatted(
X------------------------
    /\         |        |
   /  \        |        |
  /____\       ascent   |
 /      \      |        |
/        \     |        height
----------------        |
               |        |
               descent  |
               |        |
-------------------------
)
@seealso(al_get_text_width) @seealso(al_get_text_dimensions) @seealso(al_get_font_ascent) @seealso(al_get_font_descent)
#al5font.al_get_font_ascent
Returns the ascent of the specified font.
@seealso(al_get_font_descent) @seealso(al_get_font_line_height)
#al5font.al_get_font_descent
Returns the descent of the specified font.
@seealso(al_get_font_ascent) @seealso(al_get_font_line_height)
#al5font.al_destroy_font
Frees the memory being used by a font structure. Does nothing if passed @nil.
@seealso(al_load_font)
#al5font.al_get_ustr_dimensions
Like @link(al_get_text_dimensions), except the text is passed as an @link(ALLEGRO_USTR) instead of @code(STRING).
@seealso(al_get_text_dimensions)
#al5font.al_get_text_dimensions
Sometimes, the @link(al_get_text_width) and @link(al_get_font_line_height) functions are not enough for exact text placement, so this function returns some additional information.

Returned variables (all in pixels):
@unorderedlist(
  @item(@bold(x, y) - Offset to upper left corner of bounding box.)
  @item(@bold(w, h) - Dimensions of bounding box.)
)
Note that glyphs may go to the left and upwards of the X, in which case @code(x) and @code(y) will have negative values.
@seealso(al_get_text_width) @seealso(al_get_font_line_height) @seealso(al_get_ustr_dimensions)
#al5font.al_init_font_addon
Initialises the font addon.

Note that if you intend to load bitmap fonts, you will need to initialise @link(al5image) separately (unless you are using another library to load images).

Similarly, if you wish to load truetype-fonts, do not forget to also call @link(al_init_ttf_addon).
@return(@true on success, @false on failure.)
@seealso(al_is_font_addon_initialized) @seealso(al_init_image_addon) @seealso(al_init_ttf_addon) @seealso(al_shutdown_font_addon)
#al5font.al_is_font_addon_initialized
Returns @true if the font addon is is initialized, otherwise returns false.
@seealso(al_init_font_addon) @seealso(al_shutdown_font_addon)
#al5font.al_shutdown_font_addon
Shuts down the font addon. This is done automatically at program exit, but can be called any time the user wishes as well.
@seealso(al_init_font_addon) @seealso(al_is_font_addon_initialized)
#al5font.al_get_allegro_font_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).
#al5font.al_get_font_ranges
Gets information about all glyphs contained in a font, as a list of ranges. Ranges have the same format as with @code(al_grab_font_from_bitmap).
@param(ranges_count Is the maximum number of ranges that will be returned.)
@param(ranges Should be an array with room for @code(ranges_count * 2) elements.  The even integers are the first unicode point in a range, the odd integers the last unicode point in a range.)
@return(The number of ranges contained in the font @(even if it is bigger than @code(ranges_count)@).)
@seealso(al_grab_font_from_bitmap)

#al5font.al_draw_glyph
Draws the glyph that corresponds with codepoint in the given color using the given font. If font does not have such a glyph, nothing will be drawn.

To draw a string as left to right horizontal text you will need to use @link(al_get_glyph_advance) to determine the position of each glyph. For drawing strings in other directions, such as top to down, use @link(al_get_glyph_dimensions) to determine the size and position of each glyph.

If you have to draw many glyphs at the same time, use @link(al_hold_bitmap_drawing) with @true as the parameter, before drawing the glyphs, and then call @link(al_hold_bitmap_drawing) again with @false as a parameter when done drawing the glyphs to further enhance performance.
@seealso(al_get_glyph_width) @seealso(al_get_glyph_dimensions) @seealso(al_get_glyph_advance)
#al5font.al_get_glyph_width
This function returns the width in pixels of the glyph that corresponds with codepoint in the font font. Returns zero if the font does not have such a glyph.
@seealso(al_draw_glyph) @seealso(al_get_glyph_dimensions) @seealso(al_get_glyph_advance)
#al5font.al_get_glyph_dimensions
Sometimes, the @link(al_get_glyph_width) or @link(al_get_glyph_advance) functions are not enough for exact glyph placement, so this function returns some additional information, particularly if you want to draw the font vertically.

The function itself returns @true if the character was present in font and @false if the character was not present in font.

Returned variables (all in pixel):@unorderedlist(
@item(@bold(bbx, bby) - Offset to upper left corner of bounding box.)
@item(@bold(bbw, bbh) - Dimensions of bounding box.)
)
These values are the same as @link(al_get_text_dimensions) would return for a string of a single character equal to the glyph passed to this function. Note that glyphs may go to the left and upwards of the X, in which case x and y will have negative values.

If you want to draw a string verticallly, for Japanese or as a game effect, then you should leave @code(bby + bbh) space between the glyphs in the y direction for a regular placement.

If you want to draw a string horizontally in an extra compact way, then you should leave @code(bbx + bbw) space between the glyphs in the x direction for a compact placement.

In the figure below is an example of what @code(bbx) and @code(bby) may be like for a @code(2) glyph, and a @code(g) glyph of the same font compared to the result of @code(al_get_glyph_width).
@preformatted(
   al_get_glyph_width ()    al_get_glyph_width ()
          __|___                   __|__
         /      \                 /     \  
     bbx    bbw                 bbx   bbw    
    <-->+<------>+           <-->+<----->+   X baseline
    ^   |        |           ^   |       |   
bby |   |        |       bby |   |       |   
    v   |        |           |   |       |   
    +---+--------+           |   |       |
    ^   | *****  |           |   |       |
    |   |*    ** |           v   |       |
bbh |   |    **  |       bbh +---+-------+
    |   |  **    |           ^   | ***** |
    v   |********|           |   |*     *|
    +---+--------+           |   | ***** |
                             |   |      *|
                             |   | *    *|
                             v   |  **** |
                             +---+-------+
)
@seealso(al_draw_glyph) @seealso(al_get_glyph_width) @seealso(al_get_glyph_advance) @seealso(al_get_glyph_advance)
#al5font.al_get_glyph_advance
This function returns by how much the x position should be advanced for left to right text drawing when the glyph that corresponds to @code(codepoint1) has been drawn, and the glyph that corresponds to @code(codepoint2) will be the next to be drawn. This takes into consideration the horizontal advance width of the glyph that corresponds with @code(codepoint1) as well as the kerning between the glyphs of @code(codepoint1) and @code(codepoint2).

Kerning is the process of adjusting the spacing between glyphs in a font, to obtain a more visually pleasing result. Kerning adjusts the space between two individual glyphs with an offset determined by the author of the font.

If you pass @code(ALLEGRO_NO_KERNING) as @code(codepoint1) then @code(al_get_glyph_advance) will return @code(0). this can be useful when drawing the first character of a string in a loop.

Pass @code(ALLEGRO_NO_KERNING) as @code(codepoint2) to get the horizontal advance width of the glyph that corresponds to @code(codepoint1) without taking any kerning into consideration. This can be used, for example, when drawing the last character of a string in a loop.

This function will return zero if the glyph of @code(codepoint1) is not present in the font. If the glyph of @code(codepoint2) is not present in the font, the horizontal advance width of the glyph that corresponds to @code(codepoint1) without taking any kerning into consideration is returned.

When drawing a string one glyph at the time from the left to the right with kerning, the x position of the glyph should be incremented by the result of @code(al_get_glyph_advance) applied to the previous glyph drawn and the next glyph to draw.

Note that the return value of this function is a recommended advance for optimal readability for left to right text determined by the author of the font. However, if you like, you may want to draw the glyphs of the font narrower or wider to each other than what @code(al_get_glyph_advance) returns for style or effect.

In the figure below is an example of what the result of @code(al_get_glyph_advance) may be like for two glypphs @code(A) and @code(l) of the same font that has kerning for the @code("Al") pair, without and with the @code(ALLEGRO_NO_KERNING) flag.
@preformatted(
al_get_glyph_advance (font, ORD ('A'), ORD ('l'))
     ___|___
    /       \
    -------------
        /\   -|
       /  \   |
      /____\  |
     /      \ |
    /        \ \_
    -------------


al_get_glyph_advance (font, ORD ('A'), ALLEGRO_NO_KERNING)
     ____|____
    /         \
    ---------------
        /\     -|
       /  \     |
      /____\    |
     /      \   |
    /        \   \_
    ---------------
)
@seealso(al_draw_glyph) @seealso(al_get_glyph_width) @seealso(al_get_glyph_dimensions)

#al5font.al_draw_multiline_text
Like @link(al_draw_text), but this function supports drawing multiple lines of text. It will break text in lines based on its contents and the max_width parameter. The lines are then layed out vertically depending on the @code(line_height) parameter and drawn each as if @link(al_draw_text) was called on them.

A newline @code(#10) in the text will cause a @italic("hard") line break after its occurrence in the string. The text after a hard break is placed on a new line. Carriage return @code(#12) is not supported, will not cause a line break, and will likely be drawn as a square or a space depending on the font.

The @code(max_width) parameter controls the maximum desired width of the lines. This function will try to introduce a @italic("soft") line break after the longest possible series of words that will fit in @code(max_length) when drawn with the given font. A @italic("soft") line break can occur either on a space or tab (@code(#7)) character.

However, it is possible that @code(max_width) is too small, or the words in text are too long to fit @code(max_width) when drawn with font. In that case, the word that is too wide will simply be drawn completely on a line by itself. If you don't want the text that overflows @code(max_width) to be visible, then use @link(al_set_clipping_rectangle) to clip it off and hide it.

The lines @code(str) was split into will each be drawn using the @code(font), @code(x), @code(color) and @code(flags) parameters, vertically starting at @code(y) and with a distance of @code(line_height) between them. If @code(line_height) is zero (@code(0)), the value returned by calling @link(al_get_font_line_height) on font will be used as a default instead.

The flags @code(ALLEGRO_ALIGN_LEFT), @code(ALLEGRO_ALIGN_CENTRE), @code(ALLEGRO_ALIGN_RIGHT) and @code(ALLEGRO_ALIGN_INTEGER) will be honoured by this function.

If you want to calculate the size of what this function will draw without actually drawing it, or if you need a complex and/or custom layout, you can use @link(al_do_multiline_text).
@seealso(al_do_multiline_text) @seealso(al_draw_multiline_ustr) @seealso(al_draw_multiline_textf)
#al5font.al_draw_multiline_textf
Formatted text output, using a @code(Format) style format string. All parameters have the same meaning as with @link(al_draw_multiline_text) otherwise.
@seealso(al_draw_multiline_text) @seealso(al_draw_multiline_ustr) @seealso(al_do_multiline_text)
#al5font.al_draw_multiline_ustr
Like @link(al_draw_multiline_text), except the text is passed as an @link(ALLEGRO_USTR) instead of a @code(STRING).
@seealso(al_draw_multiline_text) @seealso(al_draw_multiline_textf) @seealso(al_do_multiline_text)

#al5font.al_do_multiline_text
This function processes the text and splits it into lines as @link(al_draw_multiline_text) would, and then calls the callback @code(cb) once for every line. This is useful for custom drawing of multiline text, or for calculating the size of multiline text ahead of time. See the documentation on @link(al_draw_multiline_text) for an explanation of the splitting algorithm.

For every line that this function splits text into the callback @code(cb) will be called once with the following parameters:
@unorderedlist(
  @item(@bold(@code(line_num)) - the number of the line starting from zero and counting up.)
  @item(@bold(@code(line)) - a pointer to the beginning character of the line @(see below@).)
  @item(@bold(@code(size)) - the size of the line @(0 for empty lines@).)
  @item(@bold(@code(extra)) - the same pointer that was passed to @code(al_do_multiline_text).)
)
Note that line is not guaranteed to be a @italic(NUL-terminated) string (i.e. @code(ANSISTRING)), but will merely point to a character within text or to an empty string in case of an empty line. If you need a @italic(NUL-terminated) string, you will have to copy line to a buffer and @italic(NUL-terminate) it yourself (TODO: Check if it is done by the compiler when using @code(ANSISTRING)). You will also have to make your own copy if you need the contents of line after @code(cb) has returned, as line is not guaranteed to be valid after that. Remember that in some cases @code(STRING) is @italic(reference-counted) by Pascal/Delphi.

If the callback @code(cb) returns @false, @code(al_do_multiline_text) will stop immediately, otherwise it will continue on to the next line.
@seealso(al_draw_multiline_text)
#al5font.al_do_multiline_ustr
Like @link(al_do_multiline_text), but using @link(ALLEGRO_USTR) instead of a @code(STRING) for text.
@seealso(al_draw_multiline_ustr)

#al5font.al_set_fallback_font
Sets a font which is used instead if a character is not present. Can be chained, but make sure there is no loop as that would crash the application! Pass @nil to remove a fallback font again.
@seealso(al_get_fallback_font) @seealso(al_draw_glyph) @seealso(al_draw_text) @seealso(al_get_fallback_font)
#al5font.al_get_fallback_font
Retrieves the fallback font for this font or @nil.
@seealso(al_set_fallback_font)



#al5image.al_init_image_addon
Initializes the image addon. This registers bitmap format handlers for
@link(al_load_bitmap), @link(al_load_bitmap_f), @link(al_save_bitmap),
@link(al_save_bitmap_f).

The following types are built into the Allegro image addon and guaranteed to be
available: BMP, DDS, PCX, TGA. Every platform also supports JPEG and PNG via
external dependencies.

Other formats may be available depending on the operating system and installed
libraries, but are not guaranteed and should not be assumed to be universally
available.

The DDS format is only supported to load from, and only if the DDS file
contains textures compressed in the DXT1, DXT3 and DXT5 formats. Note that when
loading a DDS file, the created bitmap will always be a video bitmap and will
have the pixel format matching the format in the file.
@seealso(al_is_image_addon_initialized) @seealso(al_shutdown_image_addon)
#al5image.al_is_image_addon_initialized
Returns @true if the image addon is is initialized, otherwise returns false.
@seealso(al_init_image_addon) @seealso(al_shutdown_image_addon)
#al5image.al_shutdown_image_addon
Shuts down the image addon.  This is done automatically at program exit, but
can be called any time the user wishes as well.
@seealso(al_init_image_addon) @seealso(al_is_image_addon_initialized)
#al5image.al_get_allegro_image_version
Returns the (compiled) version of the addon, in the same format as
@link(al_get_allegro_version).



#al5memfile.al_open_memfile
Returns a file handle to the block of memory. All read and write operations act upon the memory directly, so it must not be freed while the file remains open.

The mode can be any combination of @code('r') (readable) and @code('w') (writable). Regardless of the mode, the file always opens at position 0. The file size is fixed and cannot be expanded. The file is always read from/written to in binary mode, which means that no newline translation is performed.

It should be closed with @link(al_fclose). After the file is closed, you are responsible for freeing the memory (if needed).
#al5memfile.al_get_allegro_memfile_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).



#al5opengl.al_get_opengl_version
Returns the OpenGL or OpenGL ES version number of the client (the computer the program is running on), for the current display. "1.0" is returned as @code($01000000), "1.2.1" is returned as @code($01020100), and "1.2.2" as @code($01020200) ,etc.

A valid OpenGL context must exist for this function to work, which means you may not call it before @link(al_create_display).
@seealso(al_get_opengl_variant)
#al5opengl.al_have_opengl_extension
This function is a helper to determine whether an OpenGL extension is available on the given display or not.

@bold(Example)
@longcode(%
packedpixels := al_have_opengl_extension ('GL_EXT_packed_pixels');
%)
If @italic(packedpixels) is @true then you can safely use the constants related to the packed pixels extension.
@return(@true if the extension is available; @false otherwise.)
@seealso(al_get_opengl_proc_address)
#al5opengl.al_get_opengl_proc_address
Helper to get the address of an OpenGL symbol.

@bold(Example)

How to get the function @code(glMultiTexCoord3fARB) that comes with ARB's Multitexture extension:
@longcode(%
TYPE
{ Define the type of the function. }
  MULTI_TEX_FUNC: PROCEDURE (a: GLenum; b, c, d: GLfloat); CDECL;
VAR
{ Declare the function pointer. }
  glMultiTexCoord3fARB: MULTI_TEX_FUNC;
BEGIN
{ get the address of the function. }
  glMultiTexCoord3fARB := MULTI_TEX_FUNC (al_get_opengl_proc_address ('glMultiTexCoord3fARB'))
END;
%)
If @code(glMultiTexCoord3fARB) is not @nil then it can be used as if it has been defined in the OpenGL core library.
@param(name The name of the symbol you want to link to.)
@return(A pointer to the symbol if available or @nil otherwise.)
@seealso(al_have_opengl_extension)
#al5opengl.al_get_opengl_texture
Returns the OpenGL texture id internally used by the given bitmap if it uses one, else @code(0).

@bold(Example)
@longcode(%
  Bitmap := al_load_bitmap ('my_texture.png');
  Texture := al_get_opengl_texture (Bitmap);
  IF texture <> NIL THEN glBindTexture (GL_TEXTURE_2D, Texture);
%)
#al5opengl.al_remove_opengl_fbo
Explicitly frees an OpenGL FBO created for a bitmap, if it has one. Usually you do not need to worry about freeing FBOs, unless you use al_get_opengl_fbo.

@seealso(al_get_opengl_fbo) @seealso(al_set_target_bitmap)
#al5opengl.al_get_opengl_fbo
Returns the OpenGL FBO id internally used by the given bitmap if it uses one, otherwise returns zero. No attempt will be made to create an FBO if the bitmap is not owned by the current display.

The FBO returned by this function will only be freed when the bitmap is destroyed, or if you call @link(al_remove_opengl_fbo) on the bitmap.

@bold(Note:) In Allegro 5.0.0 this function only returned an FBO which had previously been created by calling @link(al_set_target_bitmap). It would not attempt to create an FBO itself. This has since been changed.
@seealso(al_remove_opengl_fbo) @seealso(al_set_target_bitmap)
#al5opengl.al_get_opengl_texture_size
Retrieves the size of the texture used for the bitmap. This can be different from the bitmap size if OpenGL only supports power-of-two sizes or if it is a sub-bitmap.
@return(@true on success, @false on failure. Zero width and height are returned if the bitmap is not an OpenGL bitmap.)
@seealso(al_get_opengl_texture_position)
#al5opengl.al_get_opengl_texture_position
Returns the u/v coordinates for the top/left corner of the bitmap within the used texture, in pixels.
@seealso(al_get_opengl_texture_size)
#al5opengl.al_get_opengl_program_object
Returns the OpenGL program object associated with this shader, if the platform is @link(ALLEGRO_SHADER_GLSL). Otherwise, returns @code(0).
#al5opengl.al_set_current_opengl_context
Make the OpenGL context associated with the given display current for the calling thread. If there is a current target bitmap which belongs to a different OpenGL context, the target bitmap will be changed to @nil.

Normally you do not need to use this function, as the context will be made current when you call @link(al_set_target_bitmap) or @link(al_set_target_backbuffer). You might need it if you created an OpenGL "forward compatible" context. Then @link(al_get_backbuffer) only returns @nil, so it would not work to pass that to @link(al_set_target_bitmap).
#al5opengl.al_get_opengl_variant
Returns the variant or type of OpenGL used on the running platform. This function can be called before creating a display or setting properties for new displays. Possible values are:
@definitionlist(
@itemlabel(@code(@bold(ALLEGRO_DESKTOP_OPENGL))) @item(Regular OpenGL as seen on desktop/laptop computers.)
@itemlabel(@code(@bold(ALLEGRO_OPENGL_ES))) @item(Trimmed down version of OpenGL used on many small consumer electronic devices such as handheld (and sometimes full size) consoles.)
)
@seealso(al_get_opengl_version)



#al5primitives.ALLEGRO_PRIM_TYPE
Enumerates the types of primitives this addon can draw.
  @value(ALLEGRO_PRIM_POINT_LIST A list of points, each vertex defines a point.)
  @value(ALLEGRO_PRIM_LINE_LIST A list of lines, sequential pairs of vertices define disjointed lines.)
  @value(ALLEGRO_PRIM_LINE_STRIP A strip of lines, sequential vertices define a strip of lines.)
  @value(ALLEGRO_PRIM_LINE_LOOP Like a line strip, except at the end the first and the last vertices are also connected by a line.)
  @value(ALLEGRO_PRIM_TRIANGLE_LIST A list of triangles, sequential triplets of vertices define disjointed triangles.)
  @value(ALLEGRO_PRIM_TRIANGLE_STRIP A strip of triangles, sequential vertices define a strip of triangles.)
  @value(ALLEGRO_PRIM_TRIANGLE_FAN A fan of triangles, all triangles share the first vertex.)
#al5primitives.ALLEGRO_PRIM_ATTR
Enumerates the types of vertex attributes that a custom vertex may have.
  @value(ALLEGRO_PRIM_POSITION Position information, can be stored only in @code(ALLEGRO_PRIM_SHORT_2), @code(ALLEGRO_PRIM_FLOAT_2) and @code(ALLEGRO_PRIM_FLOAT_3).)
  @value(ALLEGRO_PRIM_COLOR_ATTR Color information, stored in an @link(ALLEGRO_COLOR). The storage field of @link(ALLEGRO_VERTEX_ELEMENT) is ignored.)
  @value(ALLEGRO_PRIM_TEX_COORD Texture coordinate information, can be stored only in @code(ALLEGRO_PRIM_FLOAT_2) and @code(ALLEGRO_PRIM_SHORT_2). These coordinates are normalized by the width and height of the texture, meaning that the bottom-right corner has texture coordinates of @code(@(1, 1@)).)
  @value(ALLEGRO_PRIM_TEX_COORD_PIXEL Texture coordinate information, can be stored only in @code(ALLEGRO_PRIM_FLOAT_2) and @code(ALLEGRO_PRIM_SHORT_2). These coordinates are measured in pixels.)
  @value(ALLEGRO_PRIM_USER_ATTR A user specified attribute. You can use any storage for this attribute. You may have at most 10 of these that you can specify by adding an index to the identifier, e.g. the first user attribute is @code(ALLEGRO_PRIM_USER_ATTR), the second is @code(ALLEGRO_PRIM_USER_ATTR2) and so on.

    To access these custom attributes from GLSL shaders you need to declare attributes that follow this nomenclature: @code(user_attr_#) where @code(#) is the index of the attribute.

    To access these custom attributes from HLSL you need to declare a parameter with the following semantics: @code(TEXCOORD{# + 2}) where @code(#) is the index of the attribute. E.g. the first attribute can be accessed via TEXCOORD2, second via TEXCOORD3 and so on.)
@seealso(ALLEGRO_VERTEX_DECLptr) @seealso(ALLEGRO_PRIM_STORAGE)
#al5primitives.ALLEGRO_PRIM_STORAGE
Enumerates the types of storage an attribute of a custom vertex may be stored in. Many of these can only be used for @link(ALLEGRO_PRIM_USER_ATTR) attributes and can only be accessed via shaders. Usually no matter what the storage is specified the attribute gets converted to single precision floating point when the shader is run. Despite that, it may be advantageous to use more dense storage formats (e.g. @code(ALLEGRO_PRIM_NORMALIZED_UBYTE_4) instead of @code(ALLEGRO_PRIM_FLOAT_4)) when bandwidth (amount of memory sent to the GPU) is an issue but precision is not.
  @value(ALLEGRO_PRIM_FLOAT_1 A single float.)
  @value(ALLEGRO_PRIM_FLOAT_2 A doublet of floats.)
  @value(ALLEGRO_PRIM_FLOAT_3 A triplet of floats.)
  @value(ALLEGRO_PRIM_FLOAT_4 A quad of floats.)
  @value(ALLEGRO_PRIM_SHORT_2 A doublet of shorts.)
  @value(ALLEGRO_PRIM_SHORT_4 A quad of shorts.)
  @value(ALLEGRO_PRIM_UBYTE_4 A quad of unsigned bytes.)
  @value(ALLEGRO_PRIM_NORMALIZED_SHORT_2 A doublet of shorts. Before being sent to the shader, each component is divided by 32767. Each component of the resultant float doublet ranges between -1.0 and 1.0.)
  @value(ALLEGRO_PRIM_NORMALIZED_SHORT_4 A quad of shorts. Before being sent to the shader, each component is divided by 32767. Each component of the resultant float quad ranges between -1.0 and 1.0.)
  @value(ALLEGRO_PRIM_NORMALIZED_UBYTE_4 A quad of unsigned bytes. Before being sent to the shader, each component is divided by 255. Each component of the resultant float quad ranges between 0.0 and 1.0.)
  @value(ALLEGRO_PRIM_NORMALIZED_USHORT_2 A doublet of unsigned shorts. Before being sent to the shader, each component is divided by 65535. Each component of the resultant float doublet ranges between 0.0 and 1.0.)
  @value(ALLEGRO_PRIM_NORMALIZED_USHORT_4 A quad of unsigned shorts. Before being sent to the shader, each component is divided by 65535. Each component of the resultant float quad ranges between 0.0 and 1.0.)
  @value(ALLEGRO_PRIM_HALF_FLOAT_2 A doublet of half-precision floats. Note that this storage format is not supported on all platforms. @link(al_create_vertex_decl) will return @nil if you use it on those platforms.)
  @value(ALLEGRO_PRIM_HALF_FLOAT_4 A quad of half-precision floats. Note that this storage format is not supported on all platforms. @link(al_create_vertex_decl) will return @nil if you use it on those platforms.)
@seealso(ALLEGRO_PRIM_STORAGE_NONE) @seealso(ALLEGRO_PRIM_ATTR)
#al5primitives.ALLEGRO_LINE_JOIN
See the picture for the difference.
@html(<figure>
 <img src="images/line_join.png" width="100%" title="Line joins" alt="[-]" />
 <figcaption>ALLEGRO_LINE_JOIN styles.</figcaption>
</figure>)
The maximum miter length (relative to the line width) can be specified as parameter to the polygon functions.
@seealso(al_draw_polygon) @seealso(ALLEGRO_LINE_JOIN_MITRE)
#al5primitives.ALLEGRO_LINE_CAP
See the picture for the difference.
@html(<figure>
 <img src="images/line_cap.png" width="100%" title="Line cap" alt="[-]" />
 <figcaption>ALLEGRO_LINE_CAP styles.</figcaption>
</figure>)
@code(ALLEGRO_LINE_CAP_CLOSED) is different from the others - it causes the polygon to have no caps. (And the @link(ALLEGRO_LINE_JOIN) style will determine how the vertex looks.)
@seealso(al_draw_polygon)
#al5primitives.ALLEGRO_PRIM_BUFFER_FLAGS
Flags to specify how to create a vertex or an index buffer.
  @value(ALLEGRO_PRIM_BUFFER_STREAM Hints to the driver that the buffer is written to often, but used only a few times per frame.)
  @value(ALLEGRO_PRIM_BUFFER_STATIC Hints to the driver that the buffer is written to once and is used often.)
  @value(ALLEGRO_PRIM_BUFFER_DYNAMIC Hints to the driver that the buffer is written to often and is used often.)
  @value(ALLEGRO_PRIM_BUFFER_READWRITE Specifies that you want to be able read from this buffer. By default this is disabled for performance. Some platforms (like OpenGL ES) do not support reading from vertex buffers, so if you pass this flag to @link(al_create_vertex_buffer) or @link(al_create_index_buffer) the call will fail.)
@seealso(al_create_vertex_buffer) @seealso(al_create_index_buffer)

#al5primitives.ALLEGRO_VERTEX_CACHE_SIZE
Defines the size of the transformation vertex cache for the software renderer. If you pass less than this many vertices to the primitive rendering functions you will get a speed boost. This also defines the size of the cache vertex buffer, used for the high-level primitives. This corresponds to the maximum number of line segments that will be used to form them.

#al5primitives.ALLEGRO_VERTEX_ELEMENT
A small structure describing a certain element of a vertex. E.g. the position of the vertex, or its color. These structures are used by the @link(al_create_vertex_decl) function to create the vertex declaration. For that they generally occur in an array. The last element of such an array should have the @code(attribute) field equal to @code(0), to signify that it is the end of the array. Here is an example code that would create a declaration describing the @link(ALLEGRO_VERTEX) structure (passing this as vertex declaration to @link(al_draw_prim) would be identical to passing @nil):
@longcode(%
CONST
  Elements: ARRAY [0..1] OF ALLEGRO_VERTEX_ELEMENT = (
    (attribute: ALLEGRO_PRIM_POSITION,        storage: ALLEGRO_PRIM_FLOAT_3,      offset: 0),
    (attribute: ALLEGRO_PRIM_TEX_COORD_PIXEL, storage: ALLEGRO_PRIM_FLOAT_2,      offset: SIZEOF (AL_FLOAT) * 3),
    (attribute: ALLEGRO_PRIM_COLOR_ATTR,      storage: ALLEGRO_PRIM_STORAGE_NONE, offset: SIZEOF (AL_FLOAT) * 5),
    (attribute: ALLEGRO_PRIM_ATTR_NONE,       storage: ALLEGRO_PRIM_STORAGE_NONE, offset: 0)
  );
  Declaration: ALLEGRO_VERTEX_DECLptr;
BEGIN
  Declaration := al_create_vertex_decl (Elements, SIZEOF (ALLEGRO_VERTEX));
%)
@member(attribute A member of the @link(ALLEGRO_PRIM_ATTR) enumeration, specifying what this attribute signifies.)
@member(storage A member of the @link(ALLEGRO_PRIM_STORAGE) enumeration, specifying how this attribute is stored.)
@member(offset Offset in bytes from the beginning of the custom vertex structure. The C function offsetof is very useful here.)
@seealso(al_create_vertex_decl) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(ALLEGRO_PRIM_ATTR) @seealso(ALLEGRO_PRIM_STORAGE)

#al5primitives.ALLEGRO_VERTEX_DECLptr
A vertex declaration. This opaque structure is responsible for describing the format and layout of a user defined custom vertex. It is created and destroyed by specialized functions.
@seealso(al_create_vertex_decl) @seealso(al_destroy_vertex_decl) @seealso(ALLEGRO_VERTEX_ELEMENT)
#al5primitives.ALLEGRO_VERTEX
Defines the generic vertex type, with a 3D position, color and texture coordinates for a single texture. Note that at this time, the software driver for this addon cannot render 3D primitives. If you want a 2D only primitive, set @code(z) to @code(0). Note that you must initialize all members of this struct when you're using it. One exception to this rule are the @code(u) and @code(v) variables which can be left uninitialized when you are not using textures.
@seealso(ALLEGRO_PRIM_ATTR)

#al5primitives.ALLEGRO_VERTEX_BUFFERptr
A GPU vertex buffer that you can use to store vertices on the GPU instead of uploading them afresh during every drawing operation.
@seealso(al_create_vertex_buffer) @seealso(al_destroy_vertex_buffer)

#al5primitives.ALLEGRO_INDEX_BUFFERptr
A GPU index buffer that you can use to store indices of vertices in a vertex buffer on the GPU instead of uploading them afresh during every drawing operation.
@seealso(al_create_index_buffer) @seealso(al_destroy_index_buffer)

#al5primitives.ALLEGRO_EMIT_TRIANGLE_PROC
Callback function used by @link(al_triangulate_polygon).
@param(a Index of the first triangle vertex.)
@param(b Index of the first triangle vertex.)
@param(c Index of the first triangle vertex.)
@param(p Pointer to user data.)
#al5primitives.ALLEGRO_INIT_TRIANGLE_PROC
Callback function used by @link(al_draw_soft_triangle).
@param(state Pointer to a user suplied struct.)
@param(v1 First vertex of the triangle.)
@param(v2 Second vertex of the triangle.)
@param(v3 third vertex of the triangle.)
#al5primitives.ALLEGRO_FIRST_TRIANGLE_PROC
Callback function used by @link(al_draw_soft_triangle).

It is passed 4 parameters, the first two are the coordinates of the initial pixel drawn in the segment. The second two are the left minor and the left major steps, respectively. They represent the sizes of two steps taken by the rasterizer as it walks on the left side of the triangle. From then on, each step will either be classified as a minor or a major step, corresponding to the above values.
#al5primitives.ALLEGRO_DRAW_TRIANGLE_PROC
Callback function used by @link(al_draw_soft_triangle).

The function is expected to draw the scanline starting with a point specified by the first two parameters (@code(x1), @code(y)) going to the right until it reaches the value of the third parameter (@code(x2)). All coordinates are inclusive.

#al5primitives.ALLEGRO_FIRST_LINE_PROC
Callback function used by @link(al_draw_soft_line).

It is passed the coordinates of this pixel, as well as the two vertices above. The passed vertices may have been altered by clipping.
#al5primitives.ALLEGRO_DRAW_LINE_PROC
Callback function used by @link(al_draw_soft_line).

The function is expected to draw the pixel at the coordinates passed to it.

#al5primitives.ALLEGRO_STEP_PROC
Callback function used to track the steps on some drawing functions.

#al5primitives.ALLEGRO_SPLINE_CONTROL_POINTS
An array that defines 4 pair of coordinates for spline lines.
@seealso(al_calculate_spline) @seealso(al_draw_spline)

#al5primitives.al_get_allegro_primitives_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).

#al5primitives.al_init_primitives_addon
Initializes the primitives addon.
@returns(@true on success, @false on failure.)
@seealso(al_shutdown_primitives_addon) @seealso(al_is_primitives_addon_initialized)
#al5primitives.al_is_primitives_addon_initialized
Returns @true if the primitives addon is is initialized, otherwise returns false.
@seealso(al_init_primitives_addon) @seealso(al_shutdown_primitives_addon)
#al5primitives.al_shutdown_primitives_addon
Shut down the primitives addon.  This is done automatically at program exit, but can be called any time the user wishes as well.
@seealso(al_init_primitives_addon) @seealso(al_is_primitives_addon_initialized)
#al5primitives.al_draw_prim
Draws a subset of the passed vertex array.

For example to draw a textured triangle you could use:
@longcode(%
VAR
  v: ARRAY [0..2] OF ALLEGRO_VERTEX = (
    (x: 128, y: 0,   z: 0, color: white, u: 128, v: 0),
    (x: 0,   y: 256, z: 0, color: white, u: 0,   v: 256),
    (x: 256, y: 256, z: 0, color: white, u: 256, v: 256)
  );
BEGIN
  al_draw_prim (v, Texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST)
END;
%)
@param(vtxs Pointer to an array of vertices.)
@param(texture Texture to use, pass @nil to use only color shaded primitves.)
@param(start Start index of the subset of the vertex array to draw.)
@param(end One past the last index of the subset of the vertex array to draw.)
@return(Number of primitives drawn.)
@Seealso(al_draw_prim_ex) @seealso(ALLEGRO_VERTEX) @seealso(ALLEGRO_PRIM_TYPE) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(al_draw_indexed_prim)
#al5primitives.al_draw_prim_ex
Extended version of @link(al_draw_prim) that allows to define your own vertex type.
@param(vtxs Pointer to an array of vertices.)
@param(decl Pointer to a vertex declaration. If set to @nil, the @code(vtx) are assumed to be of the @link(ALLEGRO_VERTEX) type.)
@param(texture Texture to use, pass @nil to use only color shaded primitves.)
@param(start Start index of the subset of the vertex array to draw.)
@param(end One past the last index of the subset of the vertex array to draw.)
@param(atype A member of the @link(ALLEGRO_PRIM_TYPE) enumeration, specifying what kind of primitive to draw.)
@return(Number of primitives drawn.)
@Seealso(al_draw_prim_ex) @seealso(ALLEGRO_VERTEX) @seealso(ALLEGRO_PRIM_TYPE) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(al_draw_indexed_prim)
#al5primitives.al_draw_indexed_prim
Draws a subset of the passed vertex array. This function uses an index array to specify which vertices to use.
@param(vtxs Pointer to an array of vertices.)
@param(texture Texture to use, pass @nil to use only color shaded primitves.)
@param(indices An array of indices into the vertex array.)
@param(num_vtx Number of indices from the indices array you want to draw.)
@param(atype A member of the @link(ALLEGRO_PRIM_TYPE) enumeration, specifying what kind of primitive to draw.)
@returns(Number of primitives drawn.)
@seealso(al_draw_indexed_prim_ex) @seealso(ALLEGRO_VERTEX) @seealso(ALLEGRO_PRIM_TYPE) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(al_draw_prim)
#al5primitives.al_draw_indexed_prim_ex
Extended version of @link(al_draw_indexed_prim) that allows to define your own vertex type.
@param(vtxs Pointer to an array of vertices.)
@param(decl Pointer to a vertex declaration. If set to @nil, the @code(vtxs) are assumed to be of the @link(ALLEGRO_VERTEX) type.)
@param(texture Texture to use, pass @nil to use only color shaded primitves.)
@param(indices An array of indices into the vertex array.)
@param(num_vtx Number of indices from the indices array you want to draw.)
@param(atype A member of the @link(ALLEGRO_PRIM_TYPE) enumeration, specifying what kind of primitive to draw.)
@returns(Number of primitives drawn.)
@seealso(al_draw_indexed_prim) @seealso(ALLEGRO_VERTEX) @seealso(ALLEGRO_PRIM_TYPE) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(al_draw_prim)
#al5primitives.al_draw_vertex_buffer
Draws a subset of the passed vertex buffer. The vertex buffer must not be locked. Additionally, to draw onto memory bitmaps or with memory bitmap textures the vertex buffer must support reading (i.e. it must be created with the @code(ALLEGRO_PRIM_BUFFER_READWRITE)).
@param(vertex_buffer Vertex buffer to draw.)
@param(texture Texture to use, pass @nil to use only color shaded primitves.)
@param(start Start index of the subset of the vertex buffer to draw.)
@param(end One past the last index of the subset of the vertex buffer to draw.)
@param(atype A member of the @link(ALLEGRO_PRIM_TYPE) enumeration, specifying what kind of primitive to draw.)
@return(Number of primitives drawn.)
@seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(ALLEGRO_PRIM_TYPE)
#al5primitives.al_draw_indexed_buffer
Draws a subset of the passed vertex buffer. This function uses an index buffer to specify which vertices to use. Both buffers must not be locked. Additionally, to draw onto memory bitmaps or with memory bitmap textures both buffers must support reading (i.e. they must be created with the @code(ALLEGRO_PRIM_BUFFER_READWRITE)).
@param(vertex_buffer Vertex buffer to draw.)
@param(texture Texture to use, pass @nil to use only color shaded primitves.)
@param(index_buffer Index buffer to use.)
@param(start Start index of the subset of the vertex buffer to draw.)
@param(end One past the last index of the subset of the vertex buffer to draw.)
@param(type A member of the @link(ALLEGRO_PRIM_TYPE) enumeration, specifying what kind of primitive to draw. Note that @code(ALLEGRO_PRIM_LINE_LOOP) and @code(ALLEGRO_PRIM_POINT_LIST) are not supported.)
@return(Number of primitives drawn.)
@seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(ALLEGRO_INDEX_BUFFERptr) @seealso(ALLEGRO_PRIM_TYPE)
#al5primitives.al_create_vertex_decl
Creates a vertex declaration, which describes a custom vertex format.
@param(elements An array of @link(ALLEGRO_VERTEX_ELEMENT) structures.)
@param(stride Size of the custom vertex structure.)
@return(Newly created vertex declaration.)
@seealso(ALLEGRO_VERTEX_ELEMENT) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(al_destroy_vertex_decl)
#al5primitives.al_destroy_vertex_decl
Destroys a vertex declaration.
@param(decl Vertex declaration to destroy.)
@seealso(ALLEGRO_VERTEX_ELEMENT) @seealso(ALLEGRO_VERTEX_DECLptr) @seealso(al_create_vertex_decl)

#al5primitives.al_create_vertex_buffer
Creates a vertex buffer. Can return @nil if the buffer could not be created (e.g. the system only supports write-only buffers).

@bold(Note)

    This is an advanced feature, often unsupported on lower-end video cards. Be extra mindful of this function failing and make arrangements for fallback drawing functionality or a nice error message for users with such lower-end cards.
@param(initial_data Memory buffer to copy from to initialize the vertex buffer.)
@param(flags A combination of the @link(ALLEGRO_PRIM_BUFFER_FLAGS) flags specifying how this buffer will be created.)
@seealso(al_create_vertex_buffer_ex) @seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(al_destroy_vertex_buffer)
#al5primitives.al_create_vertex_buffer_ex
Extended version of @link(al_create_vertex_buffer) that allows to define your own vertex type.
@param(decl Vertex type that this buffer will hold. @nil implies that this buffer will hold ALLEGRO_VERTEX vertices.)
@param(initial_data Memory buffer to copy from to initialize the vertex buffer. Can be @nil, in which case the buffer is uninitialized.)
@param(num_vertices Number of vertices the buffer will hold.)
@param(flags A combination of the @link(ALLEGRO_PRIM_BUFFER_FLAGS) flags specifying how this buffer will be created.)
@seealso(al_create_vertex_buffer) @seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(al_destroy_vertex_buffer)
#al5primitives.al_destroy_vertex_buffer
Destroys a vertex buffer. Does nothing if passed @nil.
@seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(al_create_vertex_buffer)
#al5primitives.al_lock_vertex_buffer
Locks a vertex buffer so you can access its data. Will return @nil if the parameters are invalid, if reading is requested from a write only buffer, or if the buffer is already locked.
@param(buffer Vertex buffer to lock.)
@param(offset Vertex index of the start of the locked range.)
@param(length How many vertices to lock.)
@param(flags @code(ALLEGRO_LOCK_READONLY), @code(ALLEGRO_LOCK_WRITEONLY) or @code(ALLEGRO_LOCK_READWRITE).)
@seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(al_unlock_vertex_buffer)
#al5primitives.al_unlock_vertex_buffer
Unlocks a previously locked vertex buffer.
@seealso(ALLEGRO_VERTEX_BUFFERptr) @seealso(al_lock_vertex_buffer)
#al5primitives.al_get_vertex_buffer_size
Returns the size of the vertex buffer.
@seealso(ALLEGRO_VERTEX_BUFFERptr)

#al5primitives.al_create_index_buffer
Creates an index buffer. Can return @nil if the buffer could not be created (e.g. the system only supports write-only buffers).

@bold(Note)

This is an advanced feature, often unsupported on lower-end video cards. Be extra mindful of this function failing and make arrangements for fallback drawing functionality or a nice error message for users with such lower-end cards.
@param(index_size Size of the index in bytes. Supported sizes are 2 for short integers and 4 for integers.)
@param(initial_data Memory buffer to copy from to initialize the index buffer. Can be @nil, in which case the buffer is uninitialized.)
@param(num_indices Number of indices the buffer will hold.)
@param(flags A combination of the @link(ALLEGRO_PRIM_BUFFER_FLAGS) flags specifying how this buffer will be created.)
@seealso(ALLEGRO_INDEX_BUFFERptr) @seealso(al_destroy_index_buffer)
#al5primitives.al_destroy_index_buffer
Destroys an index buffer. Does nothing if passed @nil.
@seealso(ALLEGRO_INDEX_BUFFERptr) @seealso(al_create_index_buffer)
#al5primitives.al_lock_index_buffer
Locks an index buffer so you can access its data. Will return @nil if the parameters are invalid, if reading is requested from a write only buffer and if the buffer is already locked.
@param(buffer Index buffer to lock.)
@param(offset Element index of the start of the locked range.)
@param(length How many indices to lock.)
@param(flags @code(ALLEGRO_LOCK_READONLY), @code(ALLEGRO_LOCK_WRITEONLY) or @code(ALLEGRO_LOCK_READWRITE).)
@seealso(ALLEGRO_INDEX_BUFFERptr) @seealso(al_unlock_index_buffer)
#al5primitives.al_unlock_index_buffer
Unlocks a previously locked index buffer.
@seealso(ALLEGRO_INDEX_BUFFERptr) @seealso(al_lock_index_buffer)
#al5primitives.al_get_index_buffer_size
Returns the size of the index buffer
@seealso(ALLEGRO_INDEX_BUFFERptr)

#al5primitives.al_triangulate_polygon
Divides a simple polygon into triangles, with zero or more other simple polygons subtracted from it - the holes. The holes cannot touch or intersect with the outline of the main polygon. Simple means the polygon does not have to be convex but must not be self-overlapping.
@param(vertices Interleaved array of (x, y) vertex coordinates for each of the polygons, including holes.)
@param(vertex_stride Distance (in bytes) between successive pairs of vertices in the array.)
@param(vertex_counts Number of vertices for each polygon. The number of vertices in the main polygon is given by vertex_counts[0] and must be at least three. Subsequent elements indicate the number of vertices in each hole. The array must be terminated with an element with value zero.)
@param(emit_triangle A function to be called for every set of three points that form a triangle. The function is passed the indices of the points in @code(vertices) and  @code(userdata).)
@param(userdata Arbitrary data to be passed to emit_triangle.)
@seealso(ALLEGRO_EMIT_TRIANGLE_PROC) @seealso(al_draw_filled_polygon_with_holes)

#al5primitives.al_draw_soft_triangle
Draws a triangle using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in @code(addons/primitives/tri_soft.c). The triangle is drawn in two segments, from top to bottom. The segments are deliniated by the vertically middle vertex of the triangle. One of the two segments may be absent if two vertices are horizontally collinear.

@bold(Parámetros sin terminar de describir.)  Alguna explicación habrá que ponerla en la descripción del tipo de parámetro.
@param(v1 The first vertex of the triangle.)
@param(v2 The second vertex of the triangle.)
@param(v3 The third vertex of the triangle.)
@param(state A pointer to a user supplied struct, this struct will be passed to all the pixel functions.)
@param(init Called once per call before any drawing is done. The three points passed to it may be altered by clipping.)
@param(first Called twice per call, once per triangle segment.)
@param(step Called once per scanline. The last parameter is set to 1 if the step is a minor step, and 0 if it is a major step.)
@param(draw Called once per scanline.)
@seealso(al_draw_triangle)
#al5primitives.al_draw_soft_line
Draws a line using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in @code(addons/primitives/line_soft.c). The line is drawn top to bottom.
@param(v1 Initial vertex of the line.)
@param(v2 Final vertex of the line.)
@param(state A pointer to a user supplied struct, this struct will be passed to all the pixel functions.)
@param(first Called before drawing the first pixel of the line.)
@param(step Called once per pixel. The second parameter is set to 1 if the step is a minor step, and 0 if this step is a major step. Minor steps are taken only either in x or y directions. Major steps are taken in both directions diagonally. In all cases, the absolute value of the change in coordinate is at most 1 in either direction.)
@param(draw Called once per pixel.)
@seealso(al_draw_line)

#al5primitives.al_draw_line
Draws a line segment between two points.
@param(x1 X start point of the line.)
@param(y1 Y start point of the line.)
@param(x2 X end point of the line.)
@param(y2 Y end point of the line.)
@param(color Color of the line.)
@param(thickness Thickness of the line, pass <= 0 to draw hairline lines.)
@seealso(al_draw_soft_line)
#al5primitives.al_draw_triangle
@param(x1 X coordinate of the first vertex.)
@param(y1 Y coordinate of the first vertex.)
@param(x2 X coordinate of the second vertex.)
@param(y2 Y coordinate of the second vertex.)
@param(x3 X coordinate of the third vertex.)
@param(y3 Y coordinate of the third vertex.)
@param(color Color of the triangle.)
@param(thickness Thickness of the lines, pass <= 0 to draw hairline lines.)
@seealso(al_draw_filled_triangle) @seealso(al_draw_soft_triangle)
#al5primitives.al_draw_rectangle
Draws an outlined rectangle.
@param(x1 Left side of the rectangle.)
@param(y1 Top side of the rectangle.)
@param(x2 Right side of the rectangle.)
@param(y2 Bottom side of the rectangle.)
@param(color Color of the rectangle.)
@param(thickness Thickness of the lines, pass <= 0 to draw hairline lines.)
@seealso(al_draw_filled_rectangle) @seealso(al_draw_rounded_rectangle)
#al5primitives.al_draw_rounded_rectangle
Draws an outlined rounded rectangle.
@param(x1 Left side of the rectangle.)
@param(y1 Top side of the rectangle.)
@param(x2 Right side of the rectangle.)
@param(y2 Bottom side of the rectangle.)
@param(rx Horizontal radius of the round.)
@param(ry Vertical radius of the round.)
@param(color Color of the rectangle.)
@param(thickness Thickness of the lines, pass <= 0 to draw hairline lines.)
@seealso(al_draw_filled_rounded_rectangle) @seealso(al_draw_rectangle)

#al5primitives.al_calculate_arc
When @code(thickness <= 0) this function computes positions of num_points regularly spaced points on an elliptical arc. When @code(thickness > 0) this function computes two sets of points, obtained as follows: the first set is obtained by taking the points computed in the @code(thickness <= 0) case and shifting them by @code(thickness / 2) outward, in a direction perpendicular to the arc curve. The second set is the same, but shifted @code(thickness / 2) inward relative to the arc. The two sets of points are interleaved in the destination buffer (i.e. the first pair of points will be collinear with the arc center, the first point of the pair will be farther from the center than the second point; the next pair will also be collinear, but at a different angle and so on).

The destination buffer dest is interpreted as a set of regularly spaced pairs of floats, each pair holding the coordinates of the corresponding point on the arc. The two floats in the pair are adjacent, and the distance (in bytes) between the addresses of the first float in two successive pairs is @code(stride). For example, if you have a tightly packed array of floats with no spaces between pairs, then stride will be exactly @code(2 * sizeof (float)).

Example with @code(thickness <= 0):
@longcode(%
CONST
  NumPoints = 4;
VAR
  Points: ARRAY [0..NumPoints-1, 0..1] OF AL_FLOAT;
BEGIN
  al_calculate_arc (
    Points,
    0, 0,			{ Center }
    10, 10,			{ Radii  }
    0, ALLEGRO_PI / 2,		{ Angles }
    0
  );
END;
%)
Example with @code(thickness > 0):
@longcode(%
CONST
  NumPoints = 4;
VAR
  Points: ARRAY [0..(NumPoints * 2)-1, 0..1] OF AL_FLOAT;
BEGIN
  al_calculate_arc (
    Points,
    0, 0,			{ Center }
    10, 10,			{ Radii  }
    0, ALLEGRO_PI / 2,		{ Angles }
    2
  );
END;
%)
@param(dest The destination buffer.)
@param(cx X coordinate of the center of the arc.)
@param(cy Y coordinate of the center of the arc.)
@param(rx Horizontal radius of the arc.)
@param(ry Vertical radius of the arc.)
@param(start_theta The initial angle from which the arc is calculated in radians.)
@param(delta_theta Angular span of the arc in radians (pass a negative number to switch direction).)
@param(thickness Thickness of the arc.)
@seealso(al_calculate_arc_ex) @seealso(al_draw_arc) @seealso(al_calculate_spline) @seealso(al_calculate_ribbon)
#al5primitives.al_calculate_arc_ex
Same than @link(al_calculate_arc) but using a pointer instead of an array.

Example with @code(thickness <= 0):
@longcode(%
CONST
  NumPoints = 4;
VAR
  Points: ARRAY [0..NumPoints-1, 0..1] OF AL_FLOAT;
BEGIN
  al_calculate_arc_ex (
    @points[0, 0],
    2 * sizeof (AL_FLOAT),
    0, 0,			{ Center }
    10, 10,			{ Radii  }
    0, ALLEGRO_PI / 2,		{ Angles }
    0,
    NumPoints
  );
END;
%)
Example with @code(thickness > 0):
@longcode(%
CONST
  NumPoints = 4;
VAR
  Points: ARRAY [0..(NumPoints * 2)-1, 0..1] OF AL_FLOAT;
BEGIN
  al_calculate_arc_ex (
    @points[0, 0],
    2 * sizeof (AL_FLOAT),
    0, 0,			{ Center }
    10, 10,			{ Radii  }
    0, ALLEGRO_PI / 2,		{ Angles }
    2,
    NumPoints
  );
END;
%)
@param(dest The destination buffer.)
@param(stride Distance (in bytes) between starts of successive pairs of points.)
@param(cx X coordinate of the center of the arc.)
@param(cy Y coordinate of the center of the arc.)
@param(rx Horizontal radius of the arc.)
@param(ry Vertical radius of the arc.)
@param(start_theta The initial angle from which the arc is calculated in radians.)
@param(delta_theta Angular span of the arc in radians (pass a negative number to switch direction).)
@param(thickness Thickness of the arc.)
@param(num_points The number of points to calculate.)
@seealso(al_calculate_arc) @seealso(al_draw_arc) @seealso(al_calculate_spline) @seealso(al_calculate_ribbon)
#al5primitives.al_draw_circle
Draws an outlined circle.
@param(cx X coordinate of the center of the circle.)
@param(cy Y coordinate of the center of the circle.)
@param(r Radius of the circle.)
@param(color Color of the circle.)
@param(thickness Thickness of the circle, pass <= 0 to draw a hairline circle.)
@seealso(al_draw_filled_circle) @seealso(al_draw_ellipse)
#al5primitives.al_draw_ellipse
Draws an outlined ellipse.
@param(cx X coordinate of the center of the ellipse.)
@param(cy Y coordinate of the center of the ellipse.)
@param(rx Horizontal radius of the ellipse.)
@param(ry Vertical radius of the ellipse.)
@param(color Color of the ellipse.)
@param(thickness Thickness of the ellipse, pass <= 0 to draw a hairline circle.)
@seealso(al_draw_filled_ellipse) @seealso(al_draw_circle)
#al5primitives.al_draw_arc
Draws an arc.
@param(cx X coordinate of the center of the arc.)
@param(cy Y coordinate of the center of the arc.)
@param(r Radius of the arc.)
@param(start_theta The initial angle from which the arc is calculated in radians.)
@param(delta_theta Angular span of the arc in radians (pass a negative number to switch direction).)
@param(color Color of the arc.)
@param(thickness Thickness of the circle, pass <= 0 to draw a hairline circle.)
@seealso(al_calculate_arc) @seealso(al_draw_elliptical_arc)
#al5primitives.al_draw_elliptical_arc
Draws an elliptical arc.
@param(cx X coordinate of the center of the arc.)
@param(cy Y coordinate of the center of the arc.)
@param(rx Horizontal radius of the arc.)
@param(ry Vertical radius of the arc.)
@param(start_theta The initial angle from which the arc is calculated in radians.)
@param(delta_theta Angular span of the arc in radians (pass a negative number to switch direction).)
@param(color Color of the arc.)
@param(thickness Thickness of the arc, pass <= 0 to draw a hairline circle.)
@seealso(al_calculate_arc) @seealso(al_draw_arc)
#al5primitives.al_draw_pieslice
Draws a pieslice (outlined circular sector).
@param(cx X coordinate of the center of the pieslice.)
@param(cy Y coordinate of the center of the pieslice.)
@param(r Radius of the pieslice.)
@param(start_theta The initial angle from which the arc is calculated in radians.)
@param(delta_theta Angular span of the arc in radians (pass a negative number to switch direction).)
@param(color Color of the pieslice.)
@param(thickness Thickness of the pieslice, pass <= 0 to draw a hairline circle.)
@seealso(al_draw_filled_pieslice)

#al5primitives.al_calculate_spline
Calculates a Bézier spline given 4 control points. If @code(thickness <= 0), then num_segments of points are required in the destination, otherwise twice as many are needed. The destination buffer should consist of regularly spaced (by distance of @code(stride) bytes) doublets of floats, corresponding to x and y coordinates of the vertices.
@param(dest The destination buffer.)
@param(stride Distance (in bytes) between starts of successive pairs of coordinates.)
@param(points An array of 4 pairs of coordinates of the 4 control points.)
@param(thickness Thickness of the spline ribbon.)
@param(num_segments The number of points to calculate.)
@seealso(al_draw_spline) @seealso(al_calculate_arc) @seealso(al_calculate_ribbon) @seealso(al_draw_spline)
#al5primitives.al_draw_spline
Draws a Bézier spline given 4 control points.
@param(points An array of 4 pairs of coordinates of the 4 control points.)
@param(color Color of the spline.)
@param(thickness Thickness of the spline, pass <= 0 to draw a hairline spline.)
@seealso(al_calculate_spline)

#al5primitives.al_calculate_ribbon
Calculates a ribbon given an array of points. The ribbon will go through all of the passed points. If @code(thickness <= 0), then @code(num_segments) of points are required in the destination buffer, otherwise twice as many are needed. The destination and the points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices.
@param(dest Pointer to the destination buffer.)
@param(dest_stride Distance (in bytes) between starts of successive pairs of coordinates in the destination buffer.)
@param(points An array of pairs of coordinates for each point.)
@param(points_stride Distance (in bytes) between starts of successive pairs of coordinates in the points buffer.)
@param(thickness Thickness of the spline ribbon.)
@param(num_segments The number of points to calculate.)
@seealso(al_draw_ribbon) @seealso(al_calculate_arc) @seealso(al_calculate_spline) @seealso(al_draw_ribbon)
#al5primitives.al_draw_ribbon
Draws a ribbon given an array of points. The ribbon will go through all of the passed points. The points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices.
@param(points An array of coordinate pairs (x and y) for each point.)
@param(points_stride Distance (in bytes) between starts of successive pairs of coordinates in the points buffer.)
@param(color Color of the spline.)
@param(thickness Thickness of the spline, pass <= 0 to draw hairline spline.)
@param(num_segments The number of segments.)
@seealso(al_calculate_ribbon)

#al5primitives.al_draw_filled_triangle
Draws a filled triangle.
@param(x1 X coordinate of the first vertex.)
@param(y1 Y coordinate of the first vertex.)
@param(x2 X coordinate of the second vertex.)
@param(y2 Y coordinate of the second vertex.)
@param(x3 X coordinate of the third vertex.)
@param(y3 Y coordinate of the third vertex.)
@param(color Color of the triangle.)
@seealso(al_draw_triangle)
#al5primitives.al_draw_filled_rectangle
Draws a filled rectangle.
@param(x1 Left side of the rectangle.)
@param(y1 Top side of the rectangle.)
@param(x2 Right side of the rectangle.)
@param(y2 Bottom side of the rectangle.)
@param(color Color of the rectangle.)
@seealso(al_draw_rectangle) @seealso(al_draw_filled_rounded_rectangle)
#al5primitives.al_draw_filled_ellipse
Draws a filled ellipse.
@param(cx X coordinate of the center of the ellipse.)
@param(cy Y coordinate of the center of the ellipse.)
@param(rx Horizontal radius of the ellipse.)
@param(ry Vertical radius of the ellipse.)
@param(color Color of the ellipse.)
@seealso(al_draw_ellipse) @seealso(al_draw_filled_circle)
#al5primitives.al_draw_filled_circle
Draws a filled circle.
@param(cx X coordinate of the center of the circle.)
@param(cy Y coordinate of the center of the circle.)
@param(r Radius of the circle.)
@param(color Color of the circle.)
@seealso(al_draw_circle) @seealso(al_draw_filled_ellipse)
#al5primitives.al_draw_filled_pieslice
Draws a filled pieslice (filled circular sector).
@param(cx X coordinate of the center of the pieslice.)
@param(cy Y coordinate of the center of the pieslice.)
@param(r Radius of the pieslice.)
@param(start_theta The initial angle from which the arc is calculated in radians.)
@param(delta_theta Angular span of the arc in radians (pass a negative number to switch direction).)
@param(color Color of the pieslice.)
@seealso(al_draw_pieslice)
#al5primitives.al_draw_filled_rounded_rectangle
Draws a filled rounded rectangle.
@param(x1 Left side of the rectangle.)
@param(y1 Top side of the rectangle.)
@param(x2 Right side of the rectangle.)
@param(y2 Bottom side of the rectangle.)
@param(rx Horizontal radius of the round.)
@param(ry Vertical radius of the round.)
@param(color Color of the rectangle.)
@seealso(al_draw_rounded_rectangle) @seealso(al_draw_filled_rectangle)

#al5primitives.al_draw_polyline
Draws a series of line segments.
@param(vertices Interleaved array of (x, y) vertex coordinates.)
@param(join_style Member of @link(ALLEGRO_LINE_JOIN) specifying how to render the joins between line segments.)
@param(cap_style Member of @link(ALLEGRO_LINE_CAP) specifying how to render the end caps.)
@param(color Color of the line.)
@param(thickness Thickness of the line, pass <= 0 to draw hairline lines.)
@param(miter_limit Parameter for miter join style.)
@seealso(al_draw_polygon) @seealso(ALLEGRO_LINE_JOIN) @seealso(ALLEGRO_LINE_CAP)
#al5primitives.al_draw_polyline_ex
An extended version of @link(al_draw_polyline).

The stride is normally @code(2 * sizeof (float)) but may be more if the vertex coordinates are in an array of some structure type, e.g.
@longcode(%
TYPE
  VertexInfo = RECORD
    x, y: AL_FLOAT;
    id: INTEGER;
  END;

PROCEDURE MyDraw (Verts: ARRAY OF VertexInfo; Clr: ALLEGRO_COLOR);
BEGIN
  al_draw_polyline_ex (
    POINTER (@Verts[0]),
    SIZEOF (VertexInfo),
    Length (Verts),
    ALLEGRO_LINE_JOIN_NONE,
    ALLEGRO_LINE_CAP_NONE,
    Clr,
    1, 1
  )
END;
%)
The stride may also be negative if the vertices are stored in reverse order.
@param(vertices Interleaved array of (x, y) vertex coordinates.)
@param(vertex_stride the number of bytes between pairs of vertices (the stride).)
@param(vertex_count Number of vertices in the array.)
@param(join_style Member of @link(ALLEGRO_LINE_JOIN) specifying how to render the joins between line segments.)
@param(cap_style Member of @link(ALLEGRO_LINE_CAP) specifying how to render the end caps.)
@param(color Color of the line.)
@param(thickness Thickness of the line, pass <= 0 to draw hairline lines.)
@param(miter_limit Parameter for miter join style.)
@seealso(al_draw_polygon) @seealso(ALLEGRO_LINE_JOIN) @seealso(ALLEGRO_LINE_CAP)

#al5primitives.al_draw_polygon
Draws an unfilled polygon. This is the same as passing @code(ALLEGRO_LINE_CAP) to @link(al_draw_polyline).
@param(vertex Interleaved array of (x, y) vertex coordinates.)
@param(join_style Member of @link(ALLEGRO_LINE_JOIN) specifying how to render the joins between line segments.)
@param(color Color of the line.)
@param(thickness Thickness of the line, pass <= 0 to draw hairline lines.)
@param(miter_limit Parameter for miter join style.)
@seealso(al_draw_filled_polygon) @seealso(al_draw_polyline) @seealso(ALLEGRO_LINE_JOIN)
#al5primitives.al_draw_filled_polygon
Draw a filled, simple polygon. Simple means it does not have to be convex but must not be self-overlapping.

When the y-axis is facing downwards (the usual), the coordinates must be ordered anti-clockwise.
@param(vertices Interleaved array of (x, y) vertex coordinates.)
@param(color Color of the filled polygon.)
@seealso(al_draw_polygon) @seealso(al_draw_filled_polygon_with_holes)
#al5primitives.al_draw_filled_polygon_with_holes
Draws a filled simple polygon with zero or more other simple polygons subtracted from it - the holes. The holes cannot touch or intersect with the outline of the filled polygon.

All hole vertices must use the opposite order (clockwise with y down) of the polygon vertices. All hole vertices must be inside the main polygon and no hole may overlap the main polygon.

For example:
@longcode(%
VAR
  Vertices: ARRAY [0..13] OF AL_FLOAT = (
      0,   0, { Filled polygon, upper left corner. }
      0, 100, { Filled polygon, lower left corner. }
    100, 100, { Filled polygon, lower right corner. }
    100,   0, { Filled polygon, upper right corner. }
     10,  10, { Hole, upper left. }
     90,  10, { Hole, upper right. }
     90,  90  { Hole, lower right. }
  );
  VertexCounts: ARRAY [0..2] OF AL_INT = (
    4, { number of vertices for filled polygon. }
    3, { number of vertices for hole. }
    0  { terminator. }
  );
%)
There are 7 vertices: four for an outer square from (0, 0) to (100, 100) in anti-clockwise order, and three more for an inner triangle in clockwise order. The outer main polygon uses vertices 0 to 3 (inclusive) and the hole uses vertices 4 to 6 (inclusive).
@param(vertices Interleaved array of (x, y) vertex coordinates for each of the polygons, including holes.)
@param(vertex_counts Number of vertices for each polygon. The number of vertices in the filled polygon is given by @code(vertex_counts[0]) and must be at least three. Subsequent elements indicate the number of vertices in each hole. The array must be terminated with an element with value zero.)
@param(color Color of the filled polygon.)
@seealso(al_draw_filled_polygon) @seealso(al_draw_filled_polygon_with_holes) @seealso(al_triangulate_polygon)



#al5strings.al_string_to_str
Converts Pascal strings to @link(AL_STR).
#al5strings.al_str_to_string
Converts @link(AL_STR) or @link(AL_STRptr) to a @code(STRING).
#al5strings.al_str_to_shortstring
Converts @link(AL_STR) or @link(AL_STRptr) to a Pascal string.
#al5strings.al_str_to_ansistring
Converts @link(AL_STR) or @link(AL_STRptr) to an @code(ANSISTRING).
#al5strings.al_str_to_unicodestring
Converts @link(AL_STR) or @link(AL_STRptr) to an @code(UNICODESTRING).

#al5strings.al_str_format
Formats a string with given arguments.

It works exactly like RTL @code(SysUtils.Format) but using @link(AL_STR) instead of @code(STRING).

#al5strings.ALLEGRO_USTR
An opaque type representing a string. @code(ALLEGRO_USTR)s normally
contain UTF-8 encoded strings, but they may be used to hold any byte
sequences, including @nil.
#al5strings.ALLEGRO_USTR_INFO
A type that holds additional information for an @link(ALLEGRO_USTR) that
references an external memory buffer.
@seealso(al_ref_cstr) @seealso(al_ref_buffer) @seealso(al_ref_ustr)

#al5strings.al_ustr_new
Creates a new string containing a copy of the C-style string @code(s). The
string must eventually be freed with @link(al_ustr_free).
@seealso(al_ustr_new_from_buffer) @seealso(al_ustr_assign)
@seealso(al_ustr_dup)
#al5strings.al_ustr_new_from_buffer
Creates a new string containing a copy of the buffer pointed to by @code(s)
of the given @code(size) in bytes. The string must eventually be freed with
@link(al_ustr_free).
@seealso(al_ustr_new)
#al5strings.al_ustr_free
Frees a previously allocated string. Does nothing if the argument is @nil.
@seealso(al_ustr_new) @seealso(al_ustr_new_from_buffer)
#al5strings.al_cstr
Gets a @code(AL_STRptr) pointer to the data in a string. This pointer will only be valid while the @code(ALLEGRO_USTR) object is not modified and not destroyed. The pointer may be passed to functions expecting C-style strings, with the following caveats:@unorderedlist(
  @item(@code(ALLEGRO_USTR)s are allowed to contain embedded @code(NUL) @(@code($00)@) bytes. That means @code(al_ustr_size @(u@)) and @code(Length @(al_cstr @(u@)@)) may not agree.)
  @item(An @code(ALLEGRO_USTR) may be created in such a way that it is not @code(NUL) terminated. A string which is dynamically allocated will always be @code(NUL) terminated, but a string which references the middle of another string or region of memory will not be @code(NUL) terminated.)
  @item(If the @code(ALLEGRO_USTR) references another string, the returned C string will point into the referenced string. Again, no @code(NUL) terminator will be added to the referenced string.)
)
@seealso(al_ustr_to_buffer) @seealso(al_cstr_dup) @seealso(al_ustr_assign_cstr)
#al5strings.al_ustr_to_buffer
Writes the contents of the string into a pre-allocated buffer of the given
size in bytes. The result will always be @code(NUL) terminated, so a maximum
of @code(size - 1) bytes will be copied.
@seealso(al_cstr) @seealso(al_cstr_dup)
#al5strings.al_cstr_dup
Creates a @code(NUL) (@code($00)) terminated copy of the string. Any embedded @code(NUL) bytes will still be presented in the returned string. The new string must eventually be freed with @code(al_free).

If an error occurs @nil is returned.
@seealso(al_cstr) @seealso(al_ustr_to_buffer) @seealso(al_free)
#al5strings.al_ustr_dup
Returns a duplicate copy of a string. The new string will need to be freed
with @code(al_ustr_free).
@seealso(al_ustr_dup_substr) @seealso(al_ustr_free)
#al5strings.al_ustr_dup_substr
Returns a new copy of a string, containing its contents in the byte interval @code([start_pos, end_pos@)). The new string will be @code(NUL) terminated and will need to be freed with @code(al_ustr_free).

If necessary, use @link(al_ustr_offset) to find the byte offsets for a given code point that you are interested in.
@seealso(al_ustr_dup) @seealso(al_ustr_free)

@bold(Note)

This is used because the way the C language works.  I didn't test
if Pascal do need this kind of stuff.  Future versions of Allegro.pas would not
include this function, so don't use it unless your really need to (and tell me
if you really need it to remove this warning from documentation).

#al5strings.al_ustr_empty_string
Returns a pointer to a static empty string. The string is read only and must not be freed.

#al5strings.al_ref_cstr
Creates a string that references the storage of a C-style string. The
information about the string (e.g. its size) is stored in the @code(info)
parameter. The string will not have any other storage allocated of its own,
so if you allocate the info structure on the stack then no explicit "free"
operation is required.

The string is valid until the underlying C string disappears.

Example:
@longcode(!
VAR
  Info: ALLEGRO_USTR_INFO;
  us: ALLEGRO_USTRptr;
BEGIN
  us := al_ref_cstr (Info, 'my string')
END;
!)
@seealso(al_ref_buffer) @seealso(al_ref_ustr)
#al5strings.al_ref_buffer
Creates a string that references the storage of an underlying buffer. The size of the buffer is given in bytes. You can use it to reference only part of a string or an arbitrary region of memory.

The string is valid while the underlying memory buffer is valid.
@seealso(al_ref_cstr) @seealso(al_ref_ustr)
#al5strings.al_ref_ustr
Creates a read-only string that references the storage of another @link(ALLEGRO_USTR) string. The information about the string (e.g. its size) is stored in the structure pointed to by the @code(info) parameter. The new string will not have any other storage allocated of its own, so if you allocate the info structure on the stack then no explicit "free" operation is required.

The referenced interval is @code([start_pos, end_pos@)). Both are byte offsets.

The string is valid until the underlying string is modified or destroyed.

If you need a range of code-points instead of bytes, use @link(al_ustr_offset) to find the byte offsets.
@seealso(al_ref_cstr) @seealso(al_ref_buffer)

#al5strings.al_ustr_size
Returns the size of the string in bytes. This is equal to the number of code points in the string if the string is empty or contains only 7-bit ASCII characters.
@seealso(al_ustr_length)
#al5strings.al_ustr_length
Returns the number of code points in the string. @seealso(al_ustr_size) @seealso(al_ustr_offset)
#al5strings.al_ustr_offset
Returns the byte offset (from the start of the string) of the code point at the specified @code(index) in the string. A zero index parameter will return the first character of the string. If @code(index) is negative, it counts backward from the end of the string, so an index of -1 will return an offset to the last code point.

If the @code(index) is past the end of the string, returns the offset of the end of the string.
@seealso(al_ustr_length)
#al5strings.al_ustr_next
Finds the byte offset of the next code point in string, beginning at
@code(aPos). @code(aPos) does not have to be at the beginning of a code point.

This function just looks for an appropriate byte; it doesn't check if found
offset is the beginning of a valid code point. If you are working with
possibly invalid UTF-8 strings then it could skip over some invalid bytes.
@return(@true on success, and @code(aPos) will be updated to the found
offset. Otherwise returns @false if @code(aPos) was already at the end of
the string, and @code(aPos) is unmodified.)
@seealso(al_ustr_prev)
#al5strings.al_ustr_prev
Finds the byte offset of the previous code point in string, before
@code(aPos). @code(aPos) does not have to be at the beginning of a code point.

This function just looks for an appropriate byte; it doesn't check if found
offset is the beginning of a valid code point. If you are working with
possibly invalid UTF-8 strings then it could skip over some invalid bytes.
@return(@true on success, and @code(aPos) will be updated to the found
offset. Otherwise returns @false if @code(aPos) was already at the end of
the string, and @code(aPos) is unmodified.)
@seealso(al_ustr_next)

#al5strings.al_ustr_insert_chr
Inserts a code point into @code(us) beginning at byte offset @code(aPos). @code(aPos) cannot be less than 0. If @code(aPos) is past the end of @code(us) then the space between the end of the string and @code(aPos) will be padded with @code(NUL) (@code('\0')) bytes.
@Return(The number of bytes inserted, or 0 on error.)
@seealso(al_ustr_offset) @seealso(al_ustr_remove_chr)

#al5strings.al_ustr_remove_chr
Removes the code point beginning at byte offset pos.

Use @link(al_ustr_offset) to find the byte offset for a code-points offset.
@Return(@true on success. If @code(apos) is out of range or @code(apos) is not the beginning of a valid code point, returns @false leaving the string unmodified.)
@seealso(al_ustr_offset) @seealso(al_ustr_insert_chr)

#al5strings.al_ustr_assign
Overwrites the string @code(us1) with another string @code(us2).
@returns(@true on success, @false on error.)
@seealso(al_ustr_assign_cstr)
#al5strings.al_ustr_assign_cstr
Overwrites the string @code(us1) with the contents of the string @code(s).
@return(@true on success, @false on error.)
@seealso(al_ustr_assign)

#al5strings.al_ustr_equal
Returns @true if the two strings are equal. This function is more efficient than @link(al_ustr_compare) so is preferable if ordering is not important.
@seealso(al_ustr_compare)
#al5strings.al_ustr_compare
This function compares @code(us1) and @code(us2) by code point values.  It returns zero if the strings are equal, a positive number if @code(us1) comes after @code(us2), else a negative number.

This does not take into account locale-specific sorting rules. For that you will need to use another library.
@seealso(al_ustr_ncompare) @seealso(al_ustr_equal)
#al5strings.al_ustr_ncompare
This function compares @code(us1) and @code(us2) by code point values. It returns zero if the strings are equal, a positive number if @code(us1) comes after @code(us2), else a negative number.

This does not take into account locale-specific sorting rules. For that you will need to use another library.
@seealso(al_ustr_compare) @seealso(al_ustr_equal)

#al5strings.al_utf8_width
Returns the number of bytes that would be occupied by the specified code point when encoded in UTF-8. This is between 1 and 4 bytes for legal code point values. Otherwise returns 0.



#al5ttf.al_init_ttf_addon
Initializes the TTF addon.  Call this after @link(al_init_font_addon) to make @link(al_load_font) recognize ".ttf" and other formats supported by @link(al_load_ttf_font).
@return(@true on success, @false on failure.)
#al5ttf.al_shutdown_ttf_addon
Unloads the TTF addon. You normally don't need to call this.
#al5ttf.al_get_allegro_ttf_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).

#al5ttf.al_load_ttf_font
Loads a TrueType font from a file using the FreeType library.  Quoting from the FreeType FAQ this means support for many different font formats:

@italic(TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and others)

The @code(size) parameter determines the size the font will be rendered at, specified in pixels. The standard font size is measured in @italic(units per EM), if you instead want to specify the size as the total height of glyphs in pixels, pass it as a negative value.

@bold(Note)

If you want to display text at multiple sizes, load the font multiple times with different size parameters.

The following flags are supported:
@unorderedlist(
  @item(@code(ALLEGRO_TTF_NO_KERNING) - Do not use any kerning even if the font file supports it.)
  @item(@code(ALLEGRO_TTF_MONOCHROME) - Load as a monochrome font @(which means no anti-aliasing of the font is done@).)
  @item(@code(ALLEGRO_TTF_NO_AUTOHINT) - Disable the Auto Hinter which is enabled by default in newer versions of FreeType.)
)
@seealso(al_init_ttf_addon) @seealso(al_load_ttf_font_f)
#al5ttf.al_load_ttf_font_f
Like @link(al_load_ttf_font), but the font is read from the file handle. The @code(filename) is only used to find possible additional files next to a font file.

@bold(Note)

The file handle is owned by the returned @code(ALLEGRO_FONTptr) object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time.
#al5ttf.al_load_ttf_font_stretch
Like @link(al_load_ttf_font), except it takes separate width (@code(w)) and height (@code(h)) parameters instead of a single size parameter.

If the height is a positive value, and the width zero or positive, then font will be stretched according to those parameters. The width must not be negative if the height is positive.

As with @link(al_load_ttf_font), the height may be a negative value to specify the total height in pixels. Then the width must also be a negative value, or zero.
@return(@nil if the height is positive while width is negative, or if the height is negative while the width is positive.)
@seealso(al_load_ttf_font) @seealso(al_load_ttf_font_stretch_f)
#al5ttf.al_load_ttf_font_stretch_f
Like @link(al_load_ttf_font_stretch), but the font is read from the file handle. The @code(filename) is only used to find possible additional files next to a font file.

@bold(Note)

The file handle is owned by the returned @code(ALLEGRO_FONTptr) object and must not be freed by the caller, as FreeType expects to be able to read from it at a later time.
@seealso(al_load_ttf_font_stretch)



#al5video.ALLEGRO_EVENT_VIDEO_FRAME_SHOW
This event is sent when it is time to show a new frame. Once you receive this event, you can draw the current frame (as returned by @link(al_get_video_frame)). @code(al_get_video_frame) will continue returning the same frame until the next @code(ALLEGRO_EVENT_VIDEO_FRAME_SHOW) is sent.

@code(user.data1) will contain a pointer to the video which generated the event.
#al5video.ALLEGRO_EVENT_VIDEO_FINISHED
This event is sent when the video is finished. Depending on the backend, it may be possible to seek to an earlier part of the video and set the video to play to resume playback.

@code(user.data1) will contain a pointer to the video which generated the event.
#al5video.ALLEGRO_VIDEO_POSITION_TYPE
Used with @link(al_get_video_position) to specify which position to retrieve. If these get out of sync, audio and video may be out of sync in the display of the video.
@value(ALLEGRO_VIDEO_POSITION_ACTUAL The amount of time the video has been playing. If the video has audio then this value can be ahead of ALLEGRO_VIDEO_POSITION_VIDEO_DECODE when video decoding lags.)
@value(ALLEGRO_VIDEO_POSITION_VIDEO_DECODE The amount of video that has been decoded. This may lag behind the "actual" and audio positions if decoding is slower than realtime.)
@value(ALLEGRO_VIDEO_POSITION_AUDIO_DECODE The amount of audio that has been decoded. This may be the same as ALLEGRO_VIDEO_POSITION_ACTUAL if audio decode is driving the position, which is common to keep audio and video in sync.)

#al5video.al_init_video_addon
Initializes the video addon.
#al5video.al_shutdown_video_addon
Shuts down the video addon. This is done automatically at program exit, but can be called any time the user wishes as well.
#al5video.al_get_allegro_video_version
Returns the (compiled) version of the addon, in the same format as @link(al_get_allegro_version).

#al5video.al_open_video
Reads a video file. This does not start streaming yet but reads the meta info so you can query e.g. the size or audio rate.
@seealso(al_close_video) @seealso(al_start_video)
#al5video.al_close_video
Closes the video and frees all allocated resources. The video pointer is invalid after the function returns.
@seealso(al_open_video)
#al5video.al_start_video
Starts streaming the video from the beginning.
@seealso(al_open_video) @seealso(al_start_video_with_voice) @seealso(al_get_video_event_source) @seealso(al_set_voice_playing)
#al5video.al_start_video_with_voice
Like @link(al_start_video) but audio is routed to the provided voice.
#al5video.al_get_video_event_source
Gets an event source for the video. The possible events are @link(ALLEGRO_EVENT_VIDEO_FRAME_SHOW) and @link(ALLEGRO_EVENT_VIDEO_FINISHED).
#al5video.al_set_video_playing
Paused or resumes playback.
@seealso(al_is_video_playing)
#al5video.al_is_video_playing
Returns @true if the video is currently playing.
#al5video.al_get_video_audio_rate
Returns the audio rate of the video, in Hz.
#al5video.al_get_video_fps
Returns the speed of the video in frames per second. Often this will not be an integer value.
#al5video.al_get_video_scaled_width
Returns the width with which the video frame should be drawn. Videos often do not use square pixels, so this will may return a value larger than the width of the frame bitmap.
@seealso(al_get_video_frame)
#al5video.al_get_video_scaled_height
Returns the height with which the video frame should be drawn. Videos often do not use square pixels, so this will may return a value larger than the height of the frame bitmap.
@seealso(al_get_video_frame)
#al5video.al_get_video_frame
Returns the current video frame. The bitmap is owned by the video so do not attempt to free it. The bitmap will stay valid until the next call to @code(al_get_video_frame).

Videos often do not use square pixels so the recommended way to draw a video frame would be using code like this:
@longcode(%
CONST
  Scale: 1.0; { Adjust this to fit your target bitmap dimensions. }
VAR
  Frame: ALLEGRO_BITMAPptr;
  sw, sh, dw, dh: REAL;
BEGIN
  frame = al_get_video_frame (Video);
  sw = al_get_bitmap_width (Frame);
  sh = al_get_bitmap_height (Frame);
  dw = Scale * al_get_video_scaled_width (Video);
  dh = Scale * al_get_video_scaled_height (Video);
  al_draw_scaled_bitmap (Frame, 0, 0, sw, sh, 0, 0, dw, dh, 0);
END;
%)
@seealso(al_get_video_scaled_width) @seealso(al_get_video_scaled_height)
#al5video.al_get_video_position
Returns the current position of the video stream in seconds since the beginning. The parameter is one of the @link(ALLEGRO_VIDEO_POSITION_TYPE) constants.
#al5video.al_seek_video
Seeks to a different position in the video. Currently only seeking to the beginning of the video is supported.
