This is refman.info, produced by makeinfo version 7.0.2 from
refman.texi.


File: refman.info,  Node: Top,  Next: Getting started guide,  Up: (dir)

Allegro 5 reference manual
**************************

* Menu:

* Getting started guide::
* Configuration files::
* Displays::
* Event system and events::
* File I/O::
* Fixed point math routines::
* File system routines::
* Fullscreen modes::
* Graphics routines::
* Haptic routines::
* Joystick routines::
* Keyboard routines::
* Memory management routines::
* Miscellaneous routines::
* Monitors::
* Mouse routines::
* Path structures::
* State::
* System routines::
* Threads::
* Time routines::
* Timer routines::
* Touch input::
* Transformations::
* UTF-8 string routines::
* Platform-specific functions::
* Direct3D integration::
* OpenGL integration::
* Audio addon::
* Audio codecs addon::
* Color addon::
* Font addons::
* Image I/O addon::
* Main addon::
* Memfile interface::
* Native dialogs support::
* PhysicsFS integration::
* Primitives addon::
* Shader routines::
* Video streaming addon::


File: refman.info,  Node: Getting started guide,  Next: Configuration files,  Prev: Top,  Up: Top

1 Getting started guide
***********************

* Menu:

* Introduction::
* Structure of the library and its addons::
* The main function::
* Initialisation::
* Opening a window::
* Display an image::
* Changing the drawing target::
* Event queues and input::
* Displaying some text::
* Drawing primitives::
* Blending::
* Sound::
* Unstable API::
* Not the end::


File: refman.info,  Node: Introduction,  Next: Structure of the library and its addons,  Up: Getting started guide

1.1 Introduction
================

Welcome to Allegro 5!

This short guide should point you at the parts of the API that you’ll
want to know about first.  It’s not a tutorial, as there isn’t much
discussion, only links into the manual.  The rest you’ll have to
discover for yourself.  Read the examples, and ask questions at
Allegro.cc (http://www.allegro.cc/forums/).

There is an unofficial tutorial at the wiki (http://wiki.allegro.cc/).
Be aware that, being on the wiki, it may be a little out of date, but
the changes should be minor.  Hopefully more will sprout when things
stabilise, as they did for earlier versions of Allegro.


File: refman.info,  Node: Structure of the library and its addons,  Next: The main function,  Prev: Introduction,  Up: Getting started guide

1.2 Structure of the library and its addons
===========================================

Allegro 5.0 is divided into a core library and multiple addons.  The
addons are bundled together and built at the same time as the core, but
they are distinct and kept in separate libraries.  The core doesn’t
depend on anything in the addons, but addons may depend on the core and
other addons and additional third party libraries.

Here are the addons and their dependencies:

allegro_main -> allegro

allegro_image -> allegro
allegro_primitives -> allegro
allegro_color -> allegro

allegro_font -> allegro
allegro_ttf -> allegro_font -> allegro

allegro_audio -> allegro
allegro_acodec -> allegro_audio -> allegro
allegro_video -> allegro_audio -> allegro

allegro_memfile -> allegro
allegro_physfs -> allegro

allegro_native_dialog -> allegro

The header file for the core library is ‘allegro5/allegro.h’.  The
header files for the addons are named ‘allegro5/allegro_image.h’,
‘allegro5/allegro_font.h’, etc.  The allegro_main addon does not have a
header file.


File: refman.info,  Node: The main function,  Next: Initialisation,  Prev: Structure of the library and its addons,  Up: Getting started guide

1.3 The main function
=====================

For the purposes of cross-platform compatibility Allegro puts some
requirements on your main function.  First, you must include the core
header (‘allegro5/allegro.h’) in the same file as your main function.
Second, if your main function is inside a C++ file, then it must have
this signature: ‘int main(int argc, char **argv)’.  Third, if you’re
using C/C++ then you need to link with the allegro_main addon when
building your program.


File: refman.info,  Node: Initialisation,  Next: Opening a window,  Prev: The main function,  Up: Getting started guide

1.4 Initialisation
==================

Before using Allegro you must call *note al_init: #al_init.  Some addons
have their own initialisation, e.g. *note al_init_image_addon:
#al_init_image_addon, *note al_init_font_addon: #al_init_font_addon,
*note al_init_ttf_addon: #al_init_ttf_addon.

To receive input, you need to initialise some subsystems like *note
al_install_keyboard: #al_install_keyboard, *note al_install_mouse:
#al_install_mouse, *note al_install_joystick: #al_install_joystick.


File: refman.info,  Node: Opening a window,  Next: Display an image,  Prev: Initialisation,  Up: Getting started guide

1.5 Opening a window
====================

*note al_create_display: #al_create_display. will open a window and
return an *note ALLEGRO_DISPLAY: #allegro_display.

To clear the display, call *note al_clear_to_color: #al_clear_to_color.
Use *note al_map_rgba: #al_map_rgba. or *note al_map_rgba_f:
#al_map_rgba_f. to obtain an *note ALLEGRO_COLOR: #allegro_color.
parameter.

Drawing operations are performed on a backbuffer.  To make the
operations visible, call *note al_flip_display: #al_flip_display.


File: refman.info,  Node: Display an image,  Next: Changing the drawing target,  Prev: Opening a window,  Up: Getting started guide

1.6 Display an image
====================

To load an image from disk, you need to have initialised the image I/O
addon with *note al_init_image_addon: #al_init_image_addon.  Then use
*note al_load_bitmap: #al_load_bitmap, which returns an *note
ALLEGRO_BITMAP: #allegro_bitmap.

Use *note al_draw_bitmap: #al_draw_bitmap, *note al_draw_scaled_bitmap:
#al_draw_scaled_bitmap. or *note al_draw_scaled_rotated_bitmap:
#al_draw_scaled_rotated_bitmap. to draw the image to the backbuffer.
Remember to call *note al_flip_display: #al_flip_display.


File: refman.info,  Node: Changing the drawing target,  Next: Event queues and input,  Prev: Display an image,  Up: Getting started guide

1.7 Changing the drawing target
===============================

Notice that *note al_clear_to_color: #al_clear_to_color. and *note
al_draw_bitmap: #al_draw_bitmap. didn’t take destination parameters: the
destination is implicit.  Allegro remembers the current “target bitmap”
for the current thread.  To change the target bitmap, call *note
al_set_target_bitmap: #al_set_target_bitmap.

The backbuffer of the display is also a bitmap.  You can get it with
*note al_get_backbuffer: #al_get_backbuffer. and then restore it as the
target bitmap.

Other bitmaps can be created with *note al_create_bitmap:
#al_create_bitmap, with options which can be adjusted with *note
al_set_new_bitmap_flags: #al_set_new_bitmap_flags. and *note
al_set_new_bitmap_format: #al_set_new_bitmap_format.


File: refman.info,  Node: Event queues and input,  Next: Displaying some text,  Prev: Changing the drawing target,  Up: Getting started guide

1.8 Event queues and input
==========================

Input comes from multiple sources: keyboard, mouse, joystick, timers,
etc.  Event queues aggregate events from all these sources, then you can
query the queue for events.

Create an event queue with *note al_create_event_queue:
#al_create_event_queue, then tell input sources to place new events into
that queue using *note al_register_event_source:
#al_register_event_source.  The usual input event sources can be
retrieved with *note al_get_keyboard_event_source:
#al_get_keyboard_event_source, *note al_get_mouse_event_source:
#al_get_mouse_event_source. and *note al_get_joystick_event_source:
#al_get_joystick_event_source.

Events can be retrieved with *note al_wait_for_event:
#al_wait_for_event. or *note al_get_next_event: #al_get_next_event.
Check the event type and other fields of *note ALLEGRO_EVENT:
#allegro_event. to react to the input.

Displays are also event sources, which emit events when they are
resized.  You’ll need to set the ALLEGRO_RESIZABLE flag with *note
al_set_new_display_flags: #al_set_new_display_flags. before creating the
display, then register the display with an event queue.  When you get a
resize event, call *note al_acknowledge_resize: #al_acknowledge_resize.

Timers are event sources which “tick” periodically, causing an event to
be inserted into the queues that the timer is registered with.  Create
some with *note al_create_timer: #al_create_timer.

*note al_get_time: #al_get_time. and *note al_rest: #al_rest. are more
direct ways to deal with time.


File: refman.info,  Node: Displaying some text,  Next: Drawing primitives,  Prev: Event queues and input,  Up: Getting started guide

1.9 Displaying some text
========================

To display some text, initialise the image and font addons with *note
al_init_image_addon: #al_init_image_addon. and *note al_init_font_addon:
#al_init_font_addon, then load a bitmap font with *note al_load_font:
#al_load_font.  Use *note al_draw_text: #al_draw_text. or *note
al_draw_textf: #al_draw_textf.

For TrueType fonts, you’ll need to initialise the TTF font addon with
*note al_init_ttf_addon: #al_init_ttf_addon. and load a TTF font with
*note al_load_ttf_font: #al_load_ttf_font.


File: refman.info,  Node: Drawing primitives,  Next: Blending,  Prev: Displaying some text,  Up: Getting started guide

1.10 Drawing primitives
=======================

The primitives addon provides some handy routines to draw lines (*note
al_draw_line: #al_draw_line.), rectangles (*note al_draw_rectangle:
#al_draw_rectangle.), circles (*note al_draw_circle: #al_draw_circle.),
etc.


File: refman.info,  Node: Blending,  Next: Sound,  Prev: Drawing primitives,  Up: Getting started guide

1.11 Blending
=============

To draw translucent or tinted images or primitives, change the blender
state with *note al_set_blender: #al_set_blender.

As with *note al_set_target_bitmap: #al_set_target_bitmap, this changes
Allegro’s internal state (for the current thread).  Often you’ll want to
save some part of the state and restore it later.  The functions *note
al_store_state: #al_store_state. and *note al_restore_state:
#al_restore_state. provide a convenient way to do that.


File: refman.info,  Node: Sound,  Next: Unstable API,  Prev: Blending,  Up: Getting started guide

1.12 Sound
==========

Use *note al_install_audio: #al_install_audio. to initialize sound.  To
load any sample formats, you will need to initialise the acodec addon
with *note al_init_acodec_addon: #al_init_acodec_addon.

After that, you can simply use *note al_reserve_samples:
#al_reserve_samples. and pass the number of sound effects typically
playing at the same time.  Then load your sound effects with *note
al_load_sample: #al_load_sample. and play them with *note
al_play_sample: #al_play_sample.  To stream large pieces of music from
disk, you can use *note al_load_audio_stream: #al_load_audio_stream. so
the whole piece will not have to be pre-loaded into memory.

If the above sounds too simple and you can’t help but think about
clipping and latency issues, don’t worry.  Allegro gives you full
control over how much or little you want its sound system to do.  The
*note al_reserve_samples: #al_reserve_samples. function mentioned above
only sets up a default mixer and a number of sample instances but you
don’t need to use it.

Instead, to get a “direct connection” to the sound system you would use
an *note ALLEGRO_VOICE: #allegro_voice. (but depending on the platform
only one such voice is guaranteed to be available and it might require a
specific format of audio data).  Therefore all sound can be first routed
through an *note ALLEGRO_MIXER: #allegro_mixer. which is connected to
such a voice (or another mixer) and will mix together all sample data
fed to it.

You can then directly stream real-time sample data to a mixer or a voice
using an *note ALLEGRO_AUDIO_STREAM: #allegro_audio_stream. or play
complete sounds using an *note ALLEGRO_SAMPLE_INSTANCE:
#allegro_sample_instance.  The latter simply points to an *note
ALLEGRO_SAMPLE: #allegro_sample. and will stream it for you.


File: refman.info,  Node: Unstable API,  Next: Not the end,  Prev: Sound,  Up: Getting started guide

1.13 Unstable API
=================

Some of Allegro’s API is marked as unstable, which means that in future
versions of Allegro it may change or even be removed entirely!  If you
want to experiment with the unstable API, define ‘ALLEGRO_UNSTABLE’
macro before including Allegro’s headers.

Note that when you define that macro, the version check performed by
*note al_install_system: #al_install_system. and *note al_init:
#al_init. becomes more scrict.  See documentation of those functions for
details.


File: refman.info,  Node: Not the end,  Prev: Unstable API,  Up: Getting started guide

1.14 Not the end
================

There’s a heap of stuff we haven’t even mentioned yet.

Enjoy!


File: refman.info,  Node: Configuration files,  Next: Displays,  Prev: Getting started guide,  Up: Top

2 Configuration files
*********************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

Allegro supports reading and writing of configuration files with a
simple, INI file-like format.

A configuration file consists of key-value pairs separated by newlines.
Keys are separated from values by an equals sign (‘=’).  All whitespace
before the key, after the value and immediately adjacent to the equals
sign is ignored.  Keys and values may have whitespace characters within
them.  Keys do not need to be unique, but all but the last one are
ignored.

The hash (‘#’) character is used a comment when it is the first
non-whitespace character on the line.  All characters following that
character are ignored to the end of the line.  The hash character
anywhere else on the line has no special significance.

Key-value pairs can be optionally grouped into sections, which are
declared by surrounding a section name with square brackets (‘[’ and
‘]’) on a single line.  Whitespace before the opening bracket is
ignored.  All characters after the trailing bracket are also ignored.

All key-value pairs that follow a section declaration belong to the last
declared section.  Key-value pairs that don’t follow any section
declarations belong to the global section.  Sections do not nest.

Here is an example configuration file:

## Monster description
monster name = Allegro Developer

[weapon 0]
damage = 443

[weapon 1]
damage = 503

It can then be accessed like this (make sure to check for errors in an
actual program):

ALLEGRO_CONFIG* cfg = al_load_config_file("test.cfg");
printf("%s\n", al_get_config_value(cfg, "", "monster name")); /* Prints: Allegro Developer */
printf("%s\n", al_get_config_value(cfg, "weapon 0", "damage")); /* Prints: 443 */
printf("%s\n", al_get_config_value(cfg, "weapon 1", "damage")); /* Prints: 503 */
al_destroy_config(cfg);

* Menu:

* ALLEGRO_CONFIG::
* ALLEGRO_CONFIG_SECTION::
* ALLEGRO_CONFIG_ENTRY::
* al_create_config::
* al_destroy_config::
* al_load_config_file::
* al_load_config_file_f::
* al_save_config_file::
* al_save_config_file_f::
* al_add_config_section::
* al_remove_config_section::
* al_add_config_comment::
* al_get_config_value::
* al_set_config_value::
* al_remove_config_key::
* al_get_first_config_section::
* al_get_next_config_section::
* al_get_first_config_entry::
* al_get_next_config_entry::
* al_merge_config::
* al_merge_config_into::


File: refman.info,  Node: ALLEGRO_CONFIG,  Next: ALLEGRO_CONFIG_SECTION,  Up: Configuration files

2.1 ALLEGRO_CONFIG
==================

typedef struct ALLEGRO_CONFIG ALLEGRO_CONFIG;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/config.h#L12)

An abstract configuration structure.


File: refman.info,  Node: ALLEGRO_CONFIG_SECTION,  Next: ALLEGRO_CONFIG_ENTRY,  Prev: ALLEGRO_CONFIG,  Up: Configuration files

2.2 ALLEGRO_CONFIG_SECTION
==========================

typedef struct ALLEGRO_CONFIG_SECTION ALLEGRO_CONFIG_SECTION;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/config.h#L16)

An opaque structure used for iterating across sections in a
configuration structure.

See also: *note al_get_first_config_section:
#al_get_first_config_section, *note al_get_next_config_section:
#al_get_next_config_section.


File: refman.info,  Node: ALLEGRO_CONFIG_ENTRY,  Next: al_create_config,  Prev: ALLEGRO_CONFIG_SECTION,  Up: Configuration files

2.3 ALLEGRO_CONFIG_ENTRY
========================

typedef struct ALLEGRO_CONFIG_ENTRY ALLEGRO_CONFIG_ENTRY;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/config.h#L20)

An opaque structure used for iterating across entries in a configuration
section.

See also: *note al_get_first_config_entry: #al_get_first_config_entry,
*note al_get_next_config_entry: #al_get_next_config_entry.


File: refman.info,  Node: al_create_config,  Next: al_destroy_config,  Prev: ALLEGRO_CONFIG_ENTRY,  Up: Configuration files

2.4 al_create_config
====================

ALLEGRO_CONFIG *al_create_config(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L37)

Create an empty configuration structure.

See also: *note al_load_config_file: #al_load_config_file, *note
al_destroy_config: #al_destroy_config.


File: refman.info,  Node: al_destroy_config,  Next: al_load_config_file,  Prev: al_create_config,  Up: Configuration files

2.5 al_destroy_config
=====================

void al_destroy_config(ALLEGRO_CONFIG *config)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L559)

Free the resources used by a configuration structure.  Does nothing if
passed NULL.

See also: *note al_create_config: #al_create_config, *note
al_load_config_file: #al_load_config_file.


File: refman.info,  Node: al_load_config_file,  Next: al_load_config_file_f,  Prev: al_destroy_config,  Up: Configuration files

2.6 al_load_config_file
=======================

ALLEGRO_CONFIG *al_load_config_file(const char *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L311)

Read a configuration file from disk.  Returns NULL on error.  The
configuration structure should be destroyed with *note
al_destroy_config: #al_destroy_config.

See also: *note al_load_config_file_f: #al_load_config_file_f, *note
al_save_config_file: #al_save_config_file.


File: refman.info,  Node: al_load_config_file_f,  Next: al_save_config_file,  Prev: al_load_config_file,  Up: Configuration files

2.7 al_load_config_file_f
=========================

ALLEGRO_CONFIG *al_load_config_file_f(ALLEGRO_FILE *file)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L328)

Read a configuration file from an already open file.

Returns NULL on error.  The configuration structure should be destroyed
with *note al_destroy_config: #al_destroy_config.  The file remains open
afterwards.

See also: *note al_load_config_file: #al_load_config_file.


File: refman.info,  Node: al_save_config_file,  Next: al_save_config_file_f,  Prev: al_load_config_file_f,  Up: Configuration files

2.8 al_save_config_file
=======================

bool al_save_config_file(const char *filename, const ALLEGRO_CONFIG *config)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L432)

Write out a configuration file to disk.  Returns true on success, false
on error.

See also: *note al_save_config_file_f: #al_save_config_file_f, *note
al_load_config_file: #al_load_config_file.


File: refman.info,  Node: al_save_config_file_f,  Next: al_add_config_section,  Prev: al_save_config_file,  Up: Configuration files

2.9 al_save_config_file_f
=========================

bool al_save_config_file_f(ALLEGRO_FILE *file, const ALLEGRO_CONFIG *config)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L449)

Write out a configuration file to an already open file.

Returns true on success, false on error.  The file remains open
afterwards.

See also: *note al_save_config_file: #al_save_config_file.


File: refman.info,  Node: al_add_config_section,  Next: al_remove_config_section,  Prev: al_save_config_file_f,  Up: Configuration files

2.10 al_add_config_section
==========================

void al_add_config_section(ALLEGRO_CONFIG *config, const char *name)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L110)

Add a section to a configuration structure with the given name.  If the
section already exists then nothing happens.


File: refman.info,  Node: al_remove_config_section,  Next: al_add_config_comment,  Prev: al_add_config_section,  Up: Configuration files

2.11 al_remove_config_section
=============================

bool al_remove_config_section(ALLEGRO_CONFIG *config, char const *section)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L658)

Remove a section of a configuration.

Returns true if the section was removed, or false if the section did not
exist.

Since: 5.1.5


File: refman.info,  Node: al_add_config_comment,  Next: al_get_config_value,  Prev: al_remove_config_section,  Up: Configuration files

2.12 al_add_config_comment
==========================

void al_add_config_comment(ALLEGRO_CONFIG *config,
   const char *section, const char *comment)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L225)

Add a comment in a section of a configuration.  If the section doesn’t
yet exist, it will be created.  The section can be NULL or “” 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.

See also: *note al_add_config_section: #al_add_config_section.


File: refman.info,  Node: al_get_config_value,  Next: al_set_config_value,  Prev: al_add_config_comment,  Up: Configuration files

2.13 al_get_config_value
========================

const char *al_get_config_value(const ALLEGRO_CONFIG *config,
   const char *section, const char *key)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L268)

Gets a pointer to an internal character buffer that will only remain
valid as long as the ALLEGRO_CONFIG structure is not destroyed.  Copy
the value if you need a copy.  The section can be NULL or “” for the
global section.  Returns NULL if the section or key do not exist.

See also: *note al_set_config_value: #al_set_config_value.


File: refman.info,  Node: al_set_config_value,  Next: al_remove_config_key,  Prev: al_get_config_value,  Up: Configuration files

2.14 al_set_config_value
========================

void al_set_config_value(ALLEGRO_CONFIG *config,
   const char *section, const char *key, const char *value)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L164)

Set 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 NULL or “” 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.

See also: *note al_get_config_value: #al_get_config_value.


File: refman.info,  Node: al_remove_config_key,  Next: al_get_first_config_section,  Prev: al_set_config_value,  Up: Configuration files

2.15 al_remove_config_key
=========================

bool al_remove_config_key(ALLEGRO_CONFIG *config, char const *section,
   char const *key)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L700)

Remove a key and its associated value in a section of a configuration.

Returns true if the entry was removed, or false if the entry did not
exist.

Since: 5.1.5


File: refman.info,  Node: al_get_first_config_section,  Next: al_get_next_config_section,  Prev: al_remove_config_key,  Up: Configuration files

2.16 al_get_first_config_section
================================

char const *al_get_first_config_section(ALLEGRO_CONFIG const *config,
   ALLEGRO_CONFIG_SECTION **iterator)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L581)

Returns the name of the first section in the given config file.  Usually
this will return an empty string for the global section, even it
contains no values.  The ‘iterator’ parameter will receive an opaque
iterator which is used by *note al_get_next_config_section:
#al_get_next_config_section. to iterate over the remaining sections.

The returned string and the iterator are only valid as long as no change
is made to the passed ALLEGRO_CONFIG.

See also: *note al_get_next_config_section: #al_get_next_config_section.


File: refman.info,  Node: al_get_next_config_section,  Next: al_get_first_config_entry,  Prev: al_get_first_config_section,  Up: Configuration files

2.17 al_get_next_config_section
===============================

char const *al_get_next_config_section(ALLEGRO_CONFIG_SECTION **iterator)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L596)

Returns the name of the next section in the given config file or NULL if
there are no more sections.  The ‘iterator’ must have been obtained with
*note al_get_first_config_section: #al_get_first_config_section. first.

See also: *note al_get_first_config_section:
#al_get_first_config_section.


File: refman.info,  Node: al_get_first_config_entry,  Next: al_get_next_config_entry,  Prev: al_get_next_config_section,  Up: Configuration files

2.18 al_get_first_config_entry
==============================

char const *al_get_first_config_entry(ALLEGRO_CONFIG const *config,
   char const *section, ALLEGRO_CONFIG_ENTRY **iterator)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L612)

Returns the name of the first key in the given section in the given
config or NULL if the section is empty.  The ‘iterator’ works like the
one for *note al_get_first_config_section: #al_get_first_config_section.

The returned string and the iterator are only valid as long as no change
is made to the passed *note ALLEGRO_CONFIG: #allegro_config.

See also: *note al_get_next_config_entry: #al_get_next_config_entry.


File: refman.info,  Node: al_get_next_config_entry,  Next: al_merge_config,  Prev: al_get_first_config_entry,  Up: Configuration files

2.19 al_get_next_config_entry
=============================

char const *al_get_next_config_entry(ALLEGRO_CONFIG_ENTRY **iterator)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L640)

Returns the next key for the iterator obtained by *note
al_get_first_config_entry: #al_get_first_config_entry.  The ‘iterator’
works like the one for *note al_get_next_config_section:
#al_get_next_config_section.


File: refman.info,  Node: al_merge_config,  Next: al_merge_config_into,  Prev: al_get_next_config_entry,  Up: Configuration files

2.20 al_merge_config
====================

ALLEGRO_CONFIG *al_merge_config(const ALLEGRO_CONFIG *cfg1,
    const ALLEGRO_CONFIG *cfg2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L523)

Merge two configuration structures, and return the result as a new
configuration.  Values in configuration ‘cfg2’ override those in ‘cfg1’.
Neither of the input configuration structures are modified.  Comments
from ‘cfg2’ are not retained.

See also: *note al_merge_config_into: #al_merge_config_into.


File: refman.info,  Node: al_merge_config_into,  Prev: al_merge_config,  Up: Configuration files

2.21 al_merge_config_into
=========================

void al_merge_config_into(ALLEGRO_CONFIG *master, const ALLEGRO_CONFIG *add)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/config.c#L515)

Merge one configuration structure into another.  Values in configuration
‘add’ override those in ‘master’.  ‘master’ is modified.  Comments from
‘add’ are not retained.

See also: *note al_merge_config: #al_merge_config.


File: refman.info,  Node: Displays,  Next: Event system and events,  Prev: Configuration files,  Up: Top

3 Displays
**********

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

All drawing operations end up being visible on a display which is the
same as a window in windowed environments.  Thus, before anything is
displayed, a display needs to be created.

Before creating a display with *note al_create_display:
#al_create_display, flags and options can be set with *note
al_set_new_display_flags: #al_set_new_display_flags. and *note
al_set_new_display_option: #al_set_new_display_option.  For example, you
can enable the use of shaders or choose between the OpenGL and Direct3D
backends (on platforms that support both) with *note
al_set_new_display_flags: #al_set_new_display_flags.  Display options
are rather optional settings that do not affect Allegro itself,
e.g. they allow you to specify whether you want a depth buffer or enable
multisampling.

The actual properties of a display that has been successfully created
can be queried via *note al_get_display_option: #al_get_display_option,
*note al_get_display_flags: #al_get_display_flags, *note
al_get_display_width: #al_get_display_width. etc.  Note that you can
query some additional read-only properties such as the maximum allowed
bitmap (i.e. texture) size via *note al_get_display_option:
#al_get_display_option.

Each display has a backbuffer associated to it which is the default
target for any drawing operations.  In order to make visible what has
been drawn previously, you have to to call *note al_flip_display:
#al_flip_display.  Note that it is generally advisable to redraw the
whole screen (or *note clear: #al_clear_to_color. it in advance) to
avoid artefacts of uninitialised memory becoming visible with some
drivers.

You don’t have to use Allegro’s drawing routines, however: since
creating a display implies the creation of an OpenGL context or Direct3D
device respectively, you can use these APIs directly if you prefer to do
so.  Allegro provides integration for both (see the OpenGL / Direct3D
sections), so you can retrieve the underlying textures of *note
ALLEGRO_BITMAP: #allegro_bitmap.s, for example.

In order to write a well-behaved application, it is necessary to
remember that displays will also inform you about important *note
events: #allegro_event_display_expose. via their *note event sources:
#al_get_display_event_source.

* Menu:

* Display creation::
* Display operations::
* Display size and position::
* Display settings::
* Drawing halts::
* Screensaver::
* Clipboard::


File: refman.info,  Node: Display creation,  Next: Display operations,  Up: Displays

3.1 Display creation
====================

* Menu:

* ALLEGRO_DISPLAY::
* al_create_display::
* al_destroy_display::
* al_get_new_display_flags::
* al_set_new_display_flags::
* al_get_new_display_option::
* al_set_new_display_option::
* al_reset_new_display_options::
* al_get_new_window_position::
* al_set_new_window_position::
* al_get_new_display_refresh_rate::
* al_set_new_display_refresh_rate::


File: refman.info,  Node: ALLEGRO_DISPLAY,  Next: al_create_display,  Up: Display creation

3.1.1 ALLEGRO_DISPLAY
---------------------

typedef struct ALLEGRO_DISPLAY ALLEGRO_DISPLAY;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/display.h#L112)

An opaque type representing an open display or window.


File: refman.info,  Node: al_create_display,  Next: al_destroy_display,  Prev: ALLEGRO_DISPLAY,  Up: Display creation

3.1.2 al_create_display
-----------------------

ALLEGRO_DISPLAY *al_create_display(int w, int h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L38)

Create a display, or window, with the specified dimensions.  The
parameters of the display are determined by the last calls to
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.

Returns NULL on error.

Each display that uses OpenGL as a backend has a distinct OpenGL
rendering context associated with it.  See *note al_set_target_bitmap:
#al_set_target_bitmap. for the discussion about rendering contexts.

See also: *note al_set_new_display_flags: #al_set_new_display_flags,
*note al_set_new_display_option: #al_set_new_display_option, *note
al_set_new_display_refresh_rate: #al_set_new_display_refresh_rate, *note
al_set_new_display_adapter: #al_set_new_display_adapter, *note
al_set_new_window_title: #al_set_new_window_title. *note
al_set_window_position: #al_set_window_position.


File: refman.info,  Node: al_destroy_display,  Next: al_get_new_display_flags,  Prev: al_create_display,  Up: Display creation

3.1.3 al_destroy_display
------------------------

void al_destroy_display(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L143)

Destroy a display.

If the target bitmap of the calling thread is tied to the display, then
it implies a call to “al_set_target_bitmap(NULL);” 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.

See also: *note al_set_target_bitmap: #al_set_target_bitmap.


File: refman.info,  Node: al_get_new_display_flags,  Next: al_set_new_display_flags,  Prev: al_destroy_display,  Up: Display creation

3.1.4 al_get_new_display_flags
------------------------------

int al_get_new_display_flags(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L261)

Get the display flags to be used when creating new displays on the
calling thread.

See also: *note al_set_new_display_flags: #al_set_new_display_flags,
*note al_set_display_flag: #al_set_display_flag.


File: refman.info,  Node: al_set_new_display_flags,  Next: al_get_new_display_option,  Prev: al_get_new_display_flags,  Up: Display creation

3.1.5 al_set_new_display_flags
------------------------------

void al_set_new_display_flags(int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L248)

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:

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. *note
     al_create_display: #al_create_display. will fail if more than one
     adapter is attempted to be used.

ALLEGRO_FULLSCREEN_WINDOW

     Make the window span the entire screen.  Unlike 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
     ALLEGRO_FULLSCREEN flag - even if the 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.

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.

          _Note:_ Prefer using 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.  ALLEGRO_FULLSCREEN is typically less
          well supported compared to ALLEGRO_FULLSCREEN_WINDOW.
ALLEGRO_RESIZABLE

     The display is resizable (only applicable if combined with
     ALLEGRO_WINDOWED).
ALLEGRO_MAXIMIZED

     The display window will be maximized (only applicable if combined
     with ALLEGRO_RESIZABLE). Since: 5.1.12
ALLEGRO_OPENGL

     Require the driver to provide an initialized OpenGL context after
     returning successfully.
ALLEGRO_OPENGL_3_0

     Require the driver to provide an initialized OpenGL context
     compatible with OpenGL version 3.0.
ALLEGRO_OPENGL_FORWARD_COMPATIBLE

     If this flag is set, the OpenGL context created with
     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
     ALLEGRO_COMPATIBLE_DISPLAY will be set to false.
ALLEGRO_OPENGL_ES_PROFILE

     Used together with ALLEGRO_OPENGL, requests that the OpenGL context
     uses the OpenGL ES profile.  A specific version can be requested
     with *note al_set_new_display_option: #al_set_new_display_option.
     Note: Currently this is only supported by the X11/GLX driver.
     Since: 5.1.13
ALLEGRO_OPENGL_CORE_PROFILE

     Used together with ALLEGRO_OPENGL, requests that the OpenGL context
     uses the OpenGL Core profile.  A specific version can be requested
     with *note al_set_new_display_option: #al_set_new_display_option.
     Note: Currently this is only supported by the X11/GLX driver.
     Since: 5.2.7
ALLEGRO_DIRECT3D

     Require the driver to do rendering with Direct3D and provide a
     Direct3D device.
ALLEGRO_PROGRAMMABLE_PIPELINE

     Require a programmable graphics pipeline.  This flag is required to
     use *note ALLEGRO_SHADER: #allegro_shader. objects.  Since: 5.1.6
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.  Since: 5.0.7, 5.1.2
ALLEGRO_NOFRAME

     Original name for ALLEGRO_FRAMELESS. This works with older versions
     of Allegro.
ALLEGRO_GENERATE_EXPOSE_EVENTS

     Let the display generate expose events.
ALLEGRO_GTK_TOPLEVEL

     Create a GTK toplevel window for the display, on X. This flag is
     conditionally defined by the native dialog addon.  You must call
     *note al_init_native_dialog_addon: #al_init_native_dialog_addon.
     for it to succeed.  ALLEGRO_GTK_TOPLEVEL is incompatible with
     ALLEGRO_FULLSCREEN. Since: 5.1.5

0 can be used for default values.

See also: *note al_set_new_display_option: #al_set_new_display_option,
*note al_get_display_option: #al_get_display_option, *note
al_set_display_option: #al_set_display_option.


File: refman.info,  Node: al_get_new_display_option,  Next: al_set_new_display_option,  Prev: al_set_new_display_flags,  Up: Display creation

3.1.6 al_get_new_display_option
-------------------------------

int al_get_new_display_option(int option, int *importance)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display_settings.c#L64)

Retrieve an extra display setting which was previously set with *note
al_set_new_display_option: #al_set_new_display_option.


File: refman.info,  Node: al_set_new_display_option,  Next: al_reset_new_display_options,  Prev: al_get_new_display_option,  Up: Display creation

3.1.7 al_set_new_display_option
-------------------------------

void al_set_new_display_option(int option, int value, int importance)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display_settings.c#L29)

Set 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 ‘importance’ parameter can be either:

   • ALLEGRO_REQUIRE - The display will not be created if the setting
     can not be met.
   • 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 *note al_get_display_option: #al_get_display_option. after
     the display has been created.
   • 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:

ALLEGRO_COLOR_SIZE

     This can be used to ask for a specific bit depth.  For example to
     force a 16-bit framebuffer set this to 16.
ALLEGRO_RED_SIZE, ALLEGRO_GREEN_SIZE, ALLEGRO_BLUE_SIZE,
     ALLEGRO_ALPHA_SIZE

     Individual color component size in bits.
ALLEGRO_RED_SHIFT, ALLEGRO_GREEN_SHIFT, ALLEGRO_BLUE_SHIFT,
     ALLEGRO_ALPHA_SHIFT

     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.
ALLEGRO_ACC_RED_SIZE, ALLEGRO_ACC_GREEN_SIZE,
     ALLEGRO_ACC_BLUE_SIZE, ALLEGRO_ACC_ALPHA_SIZE

     This can be used to define the required accumulation buffer size.
ALLEGRO_STEREO

     Whether the display is a stereo display.
ALLEGRO_AUX_BUFFERS

     Number of auxiliary buffers the display should have.
ALLEGRO_DEPTH_SIZE

     How many depth buffer (z-buffer) bits to use.
ALLEGRO_STENCIL_SIZE

     How many bits to use for the stencil buffer.
ALLEGRO_SAMPLE_BUFFERS

     Whether to use multisampling (1) or not (0).
ALLEGRO_SAMPLES

     If the above is 1, the number of samples to use per pixel.  Else 0.
ALLEGRO_RENDER_METHOD:

     0 if hardware acceleration is not used with this display.
ALLEGRO_FLOAT_COLOR

     Whether to use floating point color components.
ALLEGRO_FLOAT_DEPTH

     Whether to use a floating point depth buffer.
ALLEGRO_SINGLE_BUFFER

     Whether the display uses a single buffer (1) or another update
     method (0).
ALLEGRO_SWAP_METHOD

     If the above is 0, this is set to 1 to indicate the display is
     using a copying method to make the next buffer in the flip chain
     available, or to 2 to indicate a flipping or other method.
ALLEGRO_COMPATIBLE_DISPLAY

     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.
ALLEGRO_UPDATE_DISPLAY_REGION

     Set to 1 if the display is capable of updating just a region, and 0
     if calling *note al_update_display_region:
     #al_update_display_region. is equivalent to *note al_flip_display:
     #al_flip_display.
ALLEGRO_VSYNC

     Set to 1 to tell the driver to wait for vsync in *note
     al_flip_display: #al_flip_display, or to 2 to force vsync off.  The
     default of 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.
ALLEGRO_MAX_BITMAP_SIZE

     When queried this returns the maximum size (width as well as
     height) a bitmap can have for this display.  Calls to *note
     al_create_bitmap: #al_create_bitmap. or *note al_load_bitmap:
     #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).
ALLEGRO_SUPPORT_NPOT_BITMAP

     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.
ALLEGRO_CAN_DRAW_INTO_BITMAP

     Set to 1 if you can use *note al_set_target_bitmap:
     #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).
ALLEGRO_SUPPORT_SEPARATE_ALPHA

     This is set to 1 if the *note al_set_separate_blender:
     #al_set_separate_blender. function is supported.  Otherwise the
     alpha parameters will be ignored.
ALLEGRO_AUTO_CONVERT_BITMAPS

     This is on by default.  It causes any existing memory bitmaps with
     the ALLEGRO_CONVERT_BITMAP flag to be converted to a display bitmap
     of the newly created display with the option set.

     Since: 5.1.0

ALLEGRO_SUPPORTED_ORIENTATIONS

     This is a bit-combination of the orientations supported by the
     application.  The orientations are the same as for *note
     al_get_display_orientation: #al_get_display_orientation. with the
     additional possibilities:

        • ALLEGRO_DISPLAY_ORIENTATION_PORTRAIT
        • ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE
        • ALLEGRO_DISPLAY_ORIENTATION_ALL

     PORTRAIT means only the two portrait orientations are supported,
     LANDSCAPE means only the two landscape orientations and 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 *note
     ALLEGRO_EVENT_DISPLAY_RESIZE: #allegro_event_display_resize.
     message which should be handled by calling *note
     al_acknowledge_resize: #al_acknowledge_resize.

     Since: 5.1.0

ALLEGRO_OPENGL_MAJOR_VERSION

     Request a specific OpenGL major version.

     Since: 5.1.13

ALLEGRO_OPENGL_MINOR_VERSION

     Request a specific OpenGL minor version.

     Since: 5.1.13

ALLEGRO_DEFAULT_SHADER_PLATFORM

     Specify the shader platform to use for the default shader.  See
     *note ALLEGRO_SHADER_PLATFORM: #allegro_shader_platform.  The
     default is ALLEGRO_SHADER_AUTO.

     Since: 5.2.8

See also: *note al_set_new_display_flags: #al_set_new_display_flags,
*note al_get_display_option: #al_get_display_option.


File: refman.info,  Node: al_reset_new_display_options,  Next: al_get_new_window_position,  Prev: al_set_new_display_option,  Up: Display creation

3.1.8 al_reset_new_display_options
----------------------------------

void al_reset_new_display_options(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display_settings.c#L104)

This undoes any previous call to *note al_set_new_display_option:
#al_set_new_display_option. on the calling thread.


File: refman.info,  Node: al_get_new_window_position,  Next: al_set_new_window_position,  Prev: al_reset_new_display_options,  Up: Display creation

3.1.9 al_get_new_window_position
--------------------------------

void al_get_new_window_position(int *x, int *y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L343)

Get the position where new non-fullscreen displays created by the
calling thread will be placed.

See also: *note al_set_new_window_position: #al_set_new_window_position.


File: refman.info,  Node: al_set_new_window_position,  Next: al_get_new_display_refresh_rate,  Prev: al_get_new_window_position,  Up: Display creation

3.1.10 al_set_new_window_position
---------------------------------

void al_set_new_window_position(int x, int y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L330)

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 (INT_MAX, INT_MAX).

See also: *note al_get_new_window_position: #al_get_new_window_position.


File: refman.info,  Node: al_get_new_display_refresh_rate,  Next: al_set_new_display_refresh_rate,  Prev: al_set_new_window_position,  Up: Display creation

3.1.11 al_get_new_display_refresh_rate
--------------------------------------

int al_get_new_display_refresh_rate(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L287)

Get the requested refresh rate to be used when creating new displays on
the calling thread.

See also: *note al_set_new_display_refresh_rate:
#al_set_new_display_refresh_rate.


File: refman.info,  Node: al_set_new_display_refresh_rate,  Prev: al_get_new_display_refresh_rate,  Up: Display creation

3.1.12 al_set_new_display_refresh_rate
--------------------------------------

void al_set_new_display_refresh_rate(int refresh_rate)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L274)

Sets the refresh rate to use when creating new displays on the calling
thread.  If the refresh rate is not available, *note al_create_display:
#al_create_display. will fail.  A list of modes with refresh rates can
be found with *note al_get_num_display_modes: #al_get_num_display_modes.
and *note al_get_display_mode: #al_get_display_mode.

The default setting is zero (don’t care).

See also: *note al_get_new_display_refresh_rate:
#al_get_new_display_refresh_rate.


File: refman.info,  Node: Display operations,  Next: Display size and position,  Prev: Display creation,  Up: Displays

3.2 Display operations
======================

* Menu:

* al_get_display_event_source::
* al_get_backbuffer::
* al_flip_display::
* al_update_display_region::
* al_wait_for_vsync::


File: refman.info,  Node: al_get_display_event_source,  Next: al_get_backbuffer,  Up: Display operations

3.2.1 al_get_display_event_source
---------------------------------

ALLEGRO_EVENT_SOURCE *al_get_display_event_source(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L490)

Retrieve the associated event source.  See the *note documentation on
events: #allegro_event_display_expose. for a list of the events displays
will generate.


File: refman.info,  Node: al_get_backbuffer,  Next: al_flip_display,  Prev: al_get_display_event_source,  Up: Display operations

3.2.2 al_get_backbuffer
-----------------------

ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L177)

Return 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 *note
al_draw_bitmap: #al_draw_bitmap.).  Only untransformed operations are
hardware accelerated.  These consist of *note al_draw_bitmap:
#al_draw_bitmap. and *note al_draw_bitmap_region:
#al_draw_bitmap_region. when the current transformation is the identity.
If the transformation 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 *note al_draw_bitmap: #al_draw_bitmap. and *note
al_draw_bitmap_region: #al_draw_bitmap_region.), and then use that
temporary bitmap as the source bitmap.


File: refman.info,  Node: al_flip_display,  Next: al_update_display_region,  Prev: al_get_backbuffer,  Up: Display operations

3.2.3 al_flip_display
---------------------

void al_flip_display(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L190)

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.

     _Note:_ If not using the ALLEGRO_SINGLE_BUFFER option, you
     typically want to redraw every pixel of the backbuffer bitmap to
     avoid uninitialized memory artifacts.
Several display options change how this function behaves:

   • With 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.

   • The ALLEGRO_SWAP_METHOD option may have additional information
     about what kind of operation is used internally to flip the front
     and back buffers.

   • If ALLEGRO_VSYNC is 1, this function will force waiting for vsync.
     If 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 ALLEGRO_VSYNC will not be set; in this case
     *note al_flip_display: #al_flip_display. will wait for vsync
     depending on the settings set in the system’s graphics preferences.

See also: *note al_set_new_display_flags: #al_set_new_display_flags,
*note al_set_new_display_option: #al_set_new_display_option.


File: refman.info,  Node: al_update_display_region,  Next: al_wait_for_vsync,  Prev: al_flip_display,  Up: Display operations

3.2.4 al_update_display_region
------------------------------

void al_update_display_region(int x, int y, int width, int height)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L204)

Does the same as *note al_flip_display: #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 *note
al_flip_display: #al_flip_display.  You can query the support for this
function using ‘al_get_display_option(display,
ALLEGRO_UPDATE_DISPLAY_REGION)’.

See also: *note al_flip_display: #al_flip_display, *note
al_get_display_option: #al_get_display_option.


File: refman.info,  Node: al_wait_for_vsync,  Prev: al_update_display_region,  Up: Display operations

3.2.5 al_wait_for_vsync
-----------------------

bool al_wait_for_vsync(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L332)

Wait for the beginning of a vertical retrace.  Some driver/card/monitor
combinations may not be capable of this.

Note how *note al_flip_display: #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.

See also: *note al_flip_display: #al_flip_display.


File: refman.info,  Node: Display size and position,  Next: Display settings,  Prev: Display operations,  Up: Displays

3.3 Display size and position
=============================

* Menu:

* al_get_display_width::
* al_get_display_height::
* al_resize_display::
* al_acknowledge_resize::
* al_get_window_position::
* al_set_window_position::
* al_get_window_constraints::
* al_set_window_constraints::
* al_apply_window_constraints::


File: refman.info,  Node: al_get_display_width,  Next: al_get_display_height,  Up: Display size and position

3.3.1 al_get_display_width
--------------------------

int al_get_display_width(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L269)

Gets the width of the display.  This is like SCREEN_W in Allegro 4.x.

See also: *note al_get_display_height: #al_get_display_height.


File: refman.info,  Node: al_get_display_height,  Next: al_resize_display,  Prev: al_get_display_width,  Up: Display size and position

3.3.2 al_get_display_height
---------------------------

int al_get_display_height(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L280)

Gets the height of the display.  This is like SCREEN_H in Allegro 4.x.

See also: *note al_get_display_width: #al_get_display_width.


File: refman.info,  Node: al_resize_display,  Next: al_acknowledge_resize,  Prev: al_get_display_height,  Up: Display size and position

3.3.3 al_resize_display
-----------------------

bool al_resize_display(ALLEGRO_DISPLAY *display, int width, int height)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L235)

Resize the display.  Returns true on success, or false on error.  This
works on both fullscreen and windowed displays, regardless of the
ALLEGRO_RESIZABLE flag.

Adjusts the clipping rectangle to the full size of the backbuffer.

See also: *note al_acknowledge_resize: #al_acknowledge_resize.


File: refman.info,  Node: al_acknowledge_resize,  Next: al_get_window_position,  Prev: al_resize_display,  Up: Display size and position

3.3.4 al_acknowledge_resize
---------------------------

bool al_acknowledge_resize(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L218)

When the user receives a *note resize event:
#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.  Returns true
on success.

Adjusts the clipping rectangle to the full size of the backbuffer.  This
also resets the backbuffers projection transform to default orthographic
transform (see *note al_use_projection_transform:
#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.

See also: *note al_resize_display: #al_resize_display, *note
ALLEGRO_EVENT: #allegro_event.


File: refman.info,  Node: al_get_window_position,  Next: al_set_window_position,  Prev: al_acknowledge_resize,  Up: Display size and position

3.3.5 al_get_window_position
----------------------------

void al_get_window_position(ALLEGRO_DISPLAY *display, int *x, int *y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L393)

Gets the position of a non-fullscreen display.

See also: *note al_set_window_position: #al_set_window_position.


File: refman.info,  Node: al_set_window_position,  Next: al_get_window_constraints,  Prev: al_get_window_position,  Up: Display size and position

3.3.6 al_set_window_position
----------------------------

void al_set_window_position(ALLEGRO_DISPLAY *display, int x, int y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L377)

Sets the position on screen of a non-fullscreen display.

See also: *note al_get_window_position: #al_get_window_position.


File: refman.info,  Node: al_get_window_constraints,  Next: al_set_window_constraints,  Prev: al_set_window_position,  Up: Display size and position

3.3.7 al_get_window_constraints
-------------------------------

bool al_get_window_constraints(ALLEGRO_DISPLAY *display,
   int *min_w, int *min_h, int *max_w, int *max_h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L447)

Gets the constraints for a non-fullscreen resizable display.

Since: 5.1.0

See also: *note al_set_window_constraints: #al_set_window_constraints.


File: refman.info,  Node: al_set_window_constraints,  Next: al_apply_window_constraints,  Prev: al_get_window_constraints,  Up: Display size and position

3.3.8 al_set_window_constraints
-------------------------------

bool al_set_window_constraints(ALLEGRO_DISPLAY *display,
   int min_w, int min_h, int max_w, int max_h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L409)

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 *note
al_apply_window_constraints: #al_apply_window_constraints. function
call.

Since: 5.1.0

See also: *note al_apply_window_constraints:
#al_apply_window_constraints, *note al_get_window_constraints:
#al_get_window_constraints.


File: refman.info,  Node: al_apply_window_constraints,  Prev: al_set_window_constraints,  Up: Display size and position

3.3.9 al_apply_window_constraints
---------------------------------

void al_apply_window_constraints(ALLEGRO_DISPLAY *display, bool onoff)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L650)

Enable or disable previously set constraints by *note
al_set_window_constraints: #al_set_window_constraints. function.

If enabled, the specified display will be automatically resized to new
sizes to conform constraints in next cases:

   • The specified display is resizable, not maximized and is not in
     fullscreen mode.
   • If the appropriate current display size (width or height) is less
     than the value of constraint.  Applied to minimum constraints.
   • 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.

See also: *note al_get_window_constraints: #al_get_window_constraints,
*note al_set_window_constraints: #al_set_window_constraints.


File: refman.info,  Node: Display settings,  Next: Drawing halts,  Prev: Display size and position,  Up: Displays

3.4 Display settings
====================

* Menu:

* al_get_display_flags::
* al_set_display_flag::
* al_get_display_option::
* al_set_display_option::
* al_get_display_format::
* al_get_display_orientation::
* al_get_display_refresh_rate::
* al_set_window_title::
* al_set_new_window_title::
* ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE::
* al_get_new_window_title::
* al_set_display_icon::
* al_set_display_icons::


File: refman.info,  Node: al_get_display_flags,  Next: al_set_display_flag,  Up: Display settings

3.4.1 al_get_display_flags
--------------------------

int al_get_display_flags(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L311)

Gets the flags of the display.

In addition to the flags set for the display at creation time with *note
al_set_new_display_flags: #al_set_new_display_flags. it can also have
the 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.

See also: *note al_set_new_display_flags: #al_set_new_display_flags,
*note al_set_display_flag: #al_set_display_flag.


File: refman.info,  Node: al_set_display_flag,  Next: al_get_display_option,  Prev: al_get_display_flags,  Up: Display settings

3.4.2 al_set_display_flag
-------------------------

bool al_set_display_flag(ALLEGRO_DISPLAY *display, int flag, bool onoff)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L468)

Enable or disable one of the display flags.  The flags are the same as
for *note al_set_new_display_flags: #al_set_new_display_flags.  The only
flags that can be changed after creation are:

   • ALLEGRO_FULLSCREEN_WINDOW
   • ALLEGRO_FRAMELESS
   • ALLEGRO_MAXIMIZED

Returns true if the driver supports toggling the specified flag else
false.  You can use *note al_get_display_flags: #al_get_display_flags.
to query whether the given display property actually changed.

Since: 5.0.7, 5.1.2

See also: *note al_set_new_display_flags: #al_set_new_display_flags,
*note al_get_display_flags: #al_get_display_flags.


File: refman.info,  Node: al_get_display_option,  Next: al_set_display_option,  Prev: al_set_display_flag,  Up: Display settings

3.4.3 al_get_display_option
---------------------------

int al_get_display_option(ALLEGRO_DISPLAY *display, int option)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display_settings.c#L94)

Return an extra display setting of the display.

See also: *note al_set_new_display_option: #al_set_new_display_option.


File: refman.info,  Node: al_set_display_option,  Next: al_get_display_format,  Prev: al_get_display_option,  Up: Display settings

3.4.4 al_set_display_option
---------------------------

void al_set_display_option(ALLEGRO_DISPLAY *display, int option, int value)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display_settings.c#L82)

Change an option that was previously set for a display.  After displays
are created, they take on the options set with *note
al_set_new_display_option: #al_set_new_display_option.  Calling *note
al_set_new_display_option: #al_set_new_display_option. subsequently only
changes options for newly created displays, and doesn’t touch the
options of already created displays.  *note al_set_display_option:
#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.

   • ALLEGRO_SUPPORTED_ORIENTATIONS - This can be changed to allow new
     or restrict previously enabled orientations of the screen/device.
     See *note al_set_new_display_option: #al_set_new_display_option.
     for more information on this option.

Since: 5.1.5

See also: *note al_set_new_display_option: #al_set_new_display_option.


File: refman.info,  Node: al_get_display_format,  Next: al_get_display_orientation,  Prev: al_set_display_option,  Up: Display settings

3.4.5 al_get_display_format
---------------------------

int al_get_display_format(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L290)

Gets the pixel format of the display.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format.


File: refman.info,  Node: al_get_display_orientation,  Next: al_get_display_refresh_rate,  Prev: al_get_display_format,  Up: Display settings

3.4.6 al_get_display_orientation
--------------------------------

int al_get_display_orientation(ALLEGRO_DISPLAY* display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L321)

Return the display orientation, which can be one of the following:

   • ALLEGRO_DISPLAY_ORIENTATION_UNKNOWN
   • ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES
   • ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES
   • ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES
   • ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES
   • ALLEGRO_DISPLAY_ORIENTATION_FACE_UP
   • ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN

Since: 5.1.0


File: refman.info,  Node: al_get_display_refresh_rate,  Next: al_set_window_title,  Prev: al_get_display_orientation,  Up: Display settings

3.4.7 al_get_display_refresh_rate
---------------------------------

int al_get_display_refresh_rate(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L300)

Gets the refresh rate of the display.

See also: *note al_set_new_display_refresh_rate:
#al_set_new_display_refresh_rate.


File: refman.info,  Node: al_set_window_title,  Next: al_set_new_window_title,  Prev: al_get_display_refresh_rate,  Up: Display settings

3.4.8 al_set_window_title
-------------------------

void al_set_window_title(ALLEGRO_DISPLAY *display, const char *title)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L481)

Set the title on a display.

See also: *note al_set_display_icon: #al_set_display_icon, *note
al_set_display_icons: #al_set_display_icons.


File: refman.info,  Node: al_set_new_window_title,  Next: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE,  Prev: al_set_window_title,  Up: Display settings

3.4.9 al_set_new_window_title
-----------------------------

void al_set_new_window_title(const char *title)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L207)

Set the title that will be used when a new display is created.  Allegro
uses a static buffer of *note ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE:
#allegro_new_window_title_max_size. to store this, so the length of the
titme you set must be less than this.

See also: *note al_set_window_title: #al_set_window_title, *note
al_get_new_window_title: #al_get_new_window_title, *note
al_create_display: #al_create_display, *note
ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE: #allegro_new_window_title_max_size.

Since: 5.1.12


File: refman.info,  Node: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE,  Next: al_get_new_window_title,  Prev: al_set_new_window_title,  Up: Display settings

3.4.10 ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE
----------------------------------------

#define ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE 255

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/display.h#L117)

This is the maximum size of the title that can be set with *note
al_set_new_window_title: #al_set_new_window_title.

See also: *note al_set_new_window_title: #al_set_new_window_title.

Since: 5.1.12


File: refman.info,  Node: al_get_new_window_title,  Next: al_set_display_icon,  Prev: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE,  Up: Display settings

3.4.11 al_get_new_window_title
------------------------------

const char *al_get_new_window_title(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L228)

Returns the title that will be used when a new display is created.  This
returns the value that *note al_set_window_title: #al_set_window_title.
was called with.  If that function wasn’t called yet, the value of *note
al_get_app_name: #al_get_app_name. is returned as a default.  The
current implementation returns a pointer to a static buffer of which you
should make a copy if you want to modify it.

See also: *note al_set_window_title: #al_set_window_title, *note
al_set_new_window_title: #al_set_new_window_title, *note
al_create_display: #al_create_display.

Since: 5.1.12


File: refman.info,  Node: al_set_display_icon,  Next: al_set_display_icons,  Prev: al_get_new_window_title,  Up: Display settings

3.4.12 al_set_display_icon
--------------------------

void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L347)

Changes the icon associated with the display (window).  Same as *note
al_set_display_icons: #al_set_display_icons. with one icon.

See also: *note al_set_display_icons: #al_set_display_icons, *note
al_set_window_title: #al_set_window_title.


File: refman.info,  Node: al_set_display_icons,  Prev: al_set_display_icon,  Up: Display settings

3.4.13 al_set_display_icons
---------------------------

void al_set_display_icons(ALLEGRO_DISPLAY *display,
   int num_icons, ALLEGRO_BITMAP *icons[])

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L358)

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.

     _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.
Since: 5.0.9, 5.1.5

See also: *note al_set_display_icon: #al_set_display_icon, *note
al_set_window_title: #al_set_window_title.


File: refman.info,  Node: Drawing halts,  Next: Screensaver,  Prev: Display settings,  Up: Displays

3.5 Drawing halts
=================

* Menu:

* al_acknowledge_drawing_halt::
* al_acknowledge_drawing_resume::


File: refman.info,  Node: al_acknowledge_drawing_halt,  Next: al_acknowledge_drawing_resume,  Up: Drawing halts

3.5.1 al_acknowledge_drawing_halt
---------------------------------

void al_acknowledge_drawing_halt(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L577)

Call this in response to the *note ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
#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.

Since: 5.1.0

See also: *note ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
#allegro_event_display_halt_drawing.


File: refman.info,  Node: al_acknowledge_drawing_resume,  Prev: al_acknowledge_drawing_halt,  Up: Drawing halts

3.5.2 al_acknowledge_drawing_resume
-----------------------------------

void al_acknowledge_drawing_resume(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L586)

Call this in response to the *note ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
#allegro_event_display_resume_drawing. event.

Since: 5.1.1

See also: *note ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
#allegro_event_display_resume_drawing.


File: refman.info,  Node: Screensaver,  Next: Clipboard,  Prev: Drawing halts,  Up: Displays

3.6 Screensaver
===============

* Menu:

* al_inhibit_screensaver::


File: refman.info,  Node: al_inhibit_screensaver,  Up: Screensaver

3.6.1 al_inhibit_screensaver
----------------------------

bool al_inhibit_screensaver(bool inhibit)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L459)

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.  It returns true
if the state was set successfully, otherwise false.


File: refman.info,  Node: Clipboard,  Prev: Screensaver,  Up: Displays

3.7 Clipboard
=============

With the clipboard API of Allegro, text can be copied from and to the
clipboard.  Currentlly, only UTF8 encoded text is supported.  It
currently works on Linux, Windows, OSX, Android and IOS.

* Menu:

* al_get_clipboard_text::
* al_set_clipboard_text::
* al_clipboard_has_text::


File: refman.info,  Node: al_get_clipboard_text,  Next: al_set_clipboard_text,  Up: Clipboard

3.7.1 al_get_clipboard_text
---------------------------

char *al_get_clipboard_text(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/clipboard.c#L29)

This function returns a pointer to a string, allocated with *note
al_malloc: #al_malloc. with the text contents of the clipboard if
available.  If no text is available on the clipboard then this function
returns NULL. You must call *note al_free: #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.

Since: 5.1.12

See also: *note al_set_clipboard_text: #al_set_clipboard_text, *note
al_clipboard_has_text: #al_clipboard_has_text.


File: refman.info,  Node: al_set_clipboard_text,  Next: al_clipboard_has_text,  Prev: al_get_clipboard_text,  Up: Clipboard

3.7.2 al_set_clipboard_text
---------------------------

bool al_set_clipboard_text(ALLEGRO_DISPLAY *display, const char *text)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/clipboard.c#L46)

This function pastes the text given as an argument to the clipboard.

Since: 5.1.12

See also: *note al_get_clipboard_text: #al_get_clipboard_text, *note
al_clipboard_has_text: #al_clipboard_has_text.


File: refman.info,  Node: al_clipboard_has_text,  Prev: al_set_clipboard_text,  Up: Clipboard

3.7.3 al_clipboard_has_text
---------------------------

bool al_clipboard_has_text(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/clipboard.c#L64)

This function returns true if and only if the clipboard has text
available.

Since: 5.1.12

See also: *note al_set_clipboard_text: #al_set_clipboard_text, *note
al_get_clipboard_text: #al_get_clipboard_text.


File: refman.info,  Node: Event system and events,  Next: File I/O,  Prev: Displays,  Up: Top

4 Event system and events
*************************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

Events are generated by event sources.  Most notably, each of the input
subsystems provides an event source, but also timers, displays, and
audio streams will generate events.

Event sources are registered to event queues which aggregate events from
multiple sources.  A single event source can also be registered to
multiple event queues.

Event queues can then be queried for events.  In particular, it is
possible to wait until events become available in order to save CPU
time.  You can combine this with *note timers: #allegro_timer. to make
your main-loop run at a specific speed without wasting CPU time or
missing events.

In addition to the predefined event types, Allegro also allows for
user-defined events that can be generated by user-defined event sources.

The appropriate reaction to an event is determined by examining the
fields of the *note ALLEGRO_EVENT: #allegro_event. union according to
the event type.

In addition to the events sent by Allegro core, there’s also events send
by the addons, see *note ALLEGRO_AUDIO_EVENT_TYPE:
#allegro_audio_event_type. and *note ALLEGRO_VIDEO_EVENT_TYPE:
#allegro_video_event_type.

* Menu:

* ALLEGRO_EVENT::
* ALLEGRO_USER_EVENT::
* ALLEGRO_EVENT_QUEUE::
* ALLEGRO_EVENT_SOURCE::
* ALLEGRO_EVENT_TYPE::
* ALLEGRO_GET_EVENT_TYPE::
* ALLEGRO_EVENT_TYPE_IS_USER::
* al_create_event_queue::
* al_destroy_event_queue::
* al_register_event_source::
* al_unregister_event_source::
* al_is_event_source_registered::
* al_pause_event_queue::
* al_is_event_queue_paused::
* al_is_event_queue_empty::
* al_get_next_event::
* al_peek_next_event::
* al_drop_next_event::
* al_flush_event_queue::
* al_wait_for_event::
* al_wait_for_event_timed::
* al_wait_for_event_until::
* al_init_user_event_source::
* al_destroy_user_event_source::
* al_emit_user_event::
* al_unref_user_event::
* al_get_event_source_data::
* al_set_event_source_data::


File: refman.info,  Node: ALLEGRO_EVENT,  Next: ALLEGRO_USER_EVENT,  Up: Event system and events

4.1 ALLEGRO_EVENT
=================

typedef union ALLEGRO_EVENT ALLEGRO_EVENT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L202)

An ALLEGRO_EVENT is a 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:

type (ALLEGRO_EVENT_TYPE)

     Indicates the type of event.
any.source (ALLEGRO_EVENT_SOURCE *)

     The event source which generated the event.
any.timestamp (double)

     When the event was generated.

By examining the ‘type’ field you can then access type-specific fields.
The ‘any.source’ field tells you which event source generated that
particular event.  The ‘any.timestamp’ field tells you when the event
was generated.  The time is referenced to the same starting point as
*note al_get_time: #al_get_time.

Each event is of one of the following types, with the usable fields
given.

* Menu:

* ALLEGRO_EVENT_JOYSTICK_AXIS::
* ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN::
* ALLEGRO_EVENT_JOYSTICK_BUTTON_UP::
* ALLEGRO_EVENT_JOYSTICK_CONFIGURATION::
* ALLEGRO_EVENT_KEY_DOWN::
* ALLEGRO_EVENT_KEY_UP::
* ALLEGRO_EVENT_KEY_CHAR::
* ALLEGRO_EVENT_MOUSE_AXES::
* ALLEGRO_EVENT_MOUSE_BUTTON_DOWN::
* ALLEGRO_EVENT_MOUSE_BUTTON_UP::
* ALLEGRO_EVENT_MOUSE_WARPED::
* ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY::
* ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY::
* ALLEGRO_EVENT_TOUCH_BEGIN::
* ALLEGRO_EVENT_TOUCH_END::
* ALLEGRO_EVENT_TOUCH_MOVE::
* ALLEGRO_EVENT_TOUCH_CANCEL::
* ALLEGRO_EVENT_TIMER::
* ALLEGRO_EVENT_DISPLAY_EXPOSE::
* ALLEGRO_EVENT_DISPLAY_RESIZE::
* ALLEGRO_EVENT_DISPLAY_CLOSE::
* ALLEGRO_EVENT_DISPLAY_LOST::
* ALLEGRO_EVENT_DISPLAY_FOUND::
* ALLEGRO_EVENT_DISPLAY_SWITCH_OUT::
* ALLEGRO_EVENT_DISPLAY_SWITCH_IN::
* ALLEGRO_EVENT_DISPLAY_ORIENTATION::
* ALLEGRO_EVENT_DISPLAY_HALT_DRAWING::
* ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING::
* ALLEGRO_EVENT_DISPLAY_CONNECTED::
* ALLEGRO_EVENT_DISPLAY_DISCONNECTED::


File: refman.info,  Node: ALLEGRO_EVENT_JOYSTICK_AXIS,  Next: ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN,  Up: ALLEGRO_EVENT

4.1.1 ALLEGRO_EVENT_JOYSTICK_AXIS
---------------------------------

A joystick axis value changed.

joystick.id (ALLEGRO_JOYSTICK *)

     The joystick which generated the event.  This is not the same as
     the event source ‘joystick.source’.
joystick.stick (int)

     The stick number, counting from zero.  Axes on a joystick are
     grouped into “sticks”.
joystick.axis (int)

     The axis number on the stick, counting from zero.
joystick.pos (float)

     The axis position, from -1.0 to +1.0.


File: refman.info,  Node: ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN,  Next: ALLEGRO_EVENT_JOYSTICK_BUTTON_UP,  Prev: ALLEGRO_EVENT_JOYSTICK_AXIS,  Up: ALLEGRO_EVENT

4.1.2 ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN
----------------------------------------

A joystick button was pressed.

joystick.id (ALLEGRO_JOYSTICK *)

     The joystick which generated the event.
joystick.button (int)

     The button which was pressed, counting from zero.


File: refman.info,  Node: ALLEGRO_EVENT_JOYSTICK_BUTTON_UP,  Next: ALLEGRO_EVENT_JOYSTICK_CONFIGURATION,  Prev: ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN,  Up: ALLEGRO_EVENT

4.1.3 ALLEGRO_EVENT_JOYSTICK_BUTTON_UP
--------------------------------------

A joystick button was released.

joystick.id (ALLEGRO_JOYSTICK *)

     The joystick which generated the event.
joystick.button (int)

     The button which was released, counting from zero.


File: refman.info,  Node: ALLEGRO_EVENT_JOYSTICK_CONFIGURATION,  Next: ALLEGRO_EVENT_KEY_DOWN,  Prev: ALLEGRO_EVENT_JOYSTICK_BUTTON_UP,  Up: ALLEGRO_EVENT

4.1.4 ALLEGRO_EVENT_JOYSTICK_CONFIGURATION
------------------------------------------

A joystick was plugged in or unplugged.  See *note
al_reconfigure_joysticks: #al_reconfigure_joysticks. for details.


File: refman.info,  Node: ALLEGRO_EVENT_KEY_DOWN,  Next: ALLEGRO_EVENT_KEY_UP,  Prev: ALLEGRO_EVENT_JOYSTICK_CONFIGURATION,  Up: ALLEGRO_EVENT

4.1.5 ALLEGRO_EVENT_KEY_DOWN
----------------------------

A keyboard key was pressed.

keyboard.keycode (int)

     The code corresponding to the physical key which was pressed.  See
     the *note Key codes: #key-codes. section for the list of
     ALLEGRO_KEY_* constants.
keyboard.display (ALLEGRO_DISPLAY *)

     The display which had keyboard focus when the event occurred.

     _Note:_ this event is about the physical keys being pressed on the
     keyboard.  Look for ALLEGRO_EVENT_KEY_CHAR events for character
     input.


File: refman.info,  Node: ALLEGRO_EVENT_KEY_UP,  Next: ALLEGRO_EVENT_KEY_CHAR,  Prev: ALLEGRO_EVENT_KEY_DOWN,  Up: ALLEGRO_EVENT

4.1.6 ALLEGRO_EVENT_KEY_UP
--------------------------

A keyboard key was released.

keyboard.keycode (int)

     The code corresponding to the physical key which was released.  See
     the *note Key codes: #key-codes. section for the list of
     ALLEGRO_KEY_* constants.
keyboard.display (ALLEGRO_DISPLAY *)

     The display which had keyboard focus when the event occurred.


File: refman.info,  Node: ALLEGRO_EVENT_KEY_CHAR,  Next: ALLEGRO_EVENT_MOUSE_AXES,  Prev: ALLEGRO_EVENT_KEY_UP,  Up: ALLEGRO_EVENT

4.1.7 ALLEGRO_EVENT_KEY_CHAR
----------------------------

A character was typed on the keyboard, or a character was auto-repeated.

keyboard.keycode (int)

     The code corresponding to the physical key which was last pressed.
     See the *note Key codes: #key-codes. section for the list of
     ALLEGRO_KEY_* constants.
keyboard.unichar (int)

     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.

keyboard.modifiers (unsigned)

     This is a bitfield of the modifier keys which were pressed when the
     event occurred.  See “Keyboard modifier flags” for the constants.
keyboard.repeat (bool)

     Indicates if this is a repeated character.
keyboard.display (ALLEGRO_DISPLAY *)

     The display which had keyboard focus when the event occurred.

     _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.


File: refman.info,  Node: ALLEGRO_EVENT_MOUSE_AXES,  Next: ALLEGRO_EVENT_MOUSE_BUTTON_DOWN,  Prev: ALLEGRO_EVENT_KEY_CHAR,  Up: ALLEGRO_EVENT

4.1.8 ALLEGRO_EVENT_MOUSE_AXES
------------------------------

One or more mouse axis values changed.

mouse.x (int)

     x-coordinate
mouse.y (int)

     y-coordinate
mouse.z (int)

     z-coordinate.  This usually means the vertical axis of a mouse
     wheel, where up is positive and down is negative.
mouse.w (int)

     w-coordinate.  This usually means the horizontal axis of a mouse
     wheel.
mouse.dx (int)

     Change in the x-coordinate value since the previous
     ALLEGRO_EVENT_MOUSE_AXES event.
mouse.dy (int)

     Change in the y-coordinate value since the previous
     ALLEGRO_EVENT_MOUSE_AXES event.
mouse.dz (int)

     Change in the z-coordinate value since the previous
     ALLEGRO_EVENT_MOUSE_AXES event.
mouse.dw (int)

     Change in the w-coordinate value since the previous
     ALLEGRO_EVENT_MOUSE_AXES event.
mouse.pressure (float)

     Pressure, ranging from ‘0.0’ to ‘1.0’.
mouse.display (ALLEGRO_DISPLAY *)

     The display which had mouse focus.

     _Note:_ Calling *note al_set_mouse_xy: #al_set_mouse_xy. also will
     result in a change of axis values, but such a change is reported
     with *note ALLEGRO_EVENT_MOUSE_WARPED: #allegro_event_mouse_warped.
     events instead which are identical except for their type.
     _Note:_ currently mouse.display may be NULL if an event is
     generated in response to *note al_set_mouse_axis:
     #al_set_mouse_axis.


File: refman.info,  Node: ALLEGRO_EVENT_MOUSE_BUTTON_DOWN,  Next: ALLEGRO_EVENT_MOUSE_BUTTON_UP,  Prev: ALLEGRO_EVENT_MOUSE_AXES,  Up: ALLEGRO_EVENT

4.1.9 ALLEGRO_EVENT_MOUSE_BUTTON_DOWN
-------------------------------------

A mouse button was pressed.

mouse.x (int)

     x-coordinate
mouse.y (int)

     y-coordinate
mouse.z (int)

     z-coordinate
mouse.w (int)

     w-coordinate
mouse.button (unsigned)

     The mouse button which was pressed, numbering from 1.
mouse.pressure (float)

     Pressure, ranging from ‘0.0’ to ‘1.0’.
mouse.display (ALLEGRO_DISPLAY *)

     The display which had mouse focus.


File: refman.info,  Node: ALLEGRO_EVENT_MOUSE_BUTTON_UP,  Next: ALLEGRO_EVENT_MOUSE_WARPED,  Prev: ALLEGRO_EVENT_MOUSE_BUTTON_DOWN,  Up: ALLEGRO_EVENT

4.1.10 ALLEGRO_EVENT_MOUSE_BUTTON_UP
------------------------------------

A mouse button was released.

mouse.x (int)

     x-coordinate
mouse.y (int)

     y-coordinate
mouse.z (int)

     z-coordinate
mouse.w (int)

     w-coordinate
mouse.button (unsigned)

     The mouse button which was released, numbering from 1.
mouse.pressure (float)

     Pressure, ranging from ‘0.0’ to ‘1.0’.
mouse.display (ALLEGRO_DISPLAY *)

     The display which had mouse focus.


File: refman.info,  Node: ALLEGRO_EVENT_MOUSE_WARPED,  Next: ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY,  Prev: ALLEGRO_EVENT_MOUSE_BUTTON_UP,  Up: ALLEGRO_EVENT

4.1.11 ALLEGRO_EVENT_MOUSE_WARPED
---------------------------------

*note al_set_mouse_xy: #al_set_mouse_xy. was called to move the mouse.
This event is identical to ALLEGRO_EVENT_MOUSE_AXES otherwise.


File: refman.info,  Node: ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY,  Next: ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY,  Prev: ALLEGRO_EVENT_MOUSE_WARPED,  Up: ALLEGRO_EVENT

4.1.12 ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY
----------------------------------------

The mouse cursor entered a window opened by the program.

mouse.x (int)

     x-coordinate
mouse.y (int)

     y-coordinate
mouse.z (int)

     z-coordinate
mouse.w (int)

     w-coordinate
mouse.display (ALLEGRO_DISPLAY *)

     The display which had mouse focus.


File: refman.info,  Node: ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY,  Next: ALLEGRO_EVENT_TOUCH_BEGIN,  Prev: ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY,  Up: ALLEGRO_EVENT

4.1.13 ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY
----------------------------------------

The mouse cursor left the boundaries of a window opened by the program.

mouse.x (int)

     x-coordinate
mouse.y (int)

     y-coordinate
mouse.z (int)

     z-coordinate
mouse.w (int)

     w-coordinate
mouse.display (ALLEGRO_DISPLAY *)

     The display which had mouse focus.


File: refman.info,  Node: ALLEGRO_EVENT_TOUCH_BEGIN,  Next: ALLEGRO_EVENT_TOUCH_END,  Prev: ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY,  Up: ALLEGRO_EVENT

4.1.14 ALLEGRO_EVENT_TOUCH_BEGIN
--------------------------------

The touch input device registered a new touch.

touch.display (ALLEGRO_DISPLAY)

     The display which was touched.
touch.id (int)

     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.
touch.x (float)

     The x coordinate of the touch in pixels.
touch.y (float)

     The y coordinate of the touch in pixels.
touch.dx (float)

     Movement speed in pixels in x direction.
touch.dy (float)

     Movement speed in pixels in y direction.
touch.primary (bool)

     Whether this is the only/first touch or an additional touch.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_EVENT_TOUCH_END,  Next: ALLEGRO_EVENT_TOUCH_MOVE,  Prev: ALLEGRO_EVENT_TOUCH_BEGIN,  Up: ALLEGRO_EVENT

4.1.15 ALLEGRO_EVENT_TOUCH_END
------------------------------

A touch ended.

Has the same fields as *note ALLEGRO_EVENT_TOUCH_BEGIN:
#allegro_event_touch_begin.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_EVENT_TOUCH_MOVE,  Next: ALLEGRO_EVENT_TOUCH_CANCEL,  Prev: ALLEGRO_EVENT_TOUCH_END,  Up: ALLEGRO_EVENT

4.1.16 ALLEGRO_EVENT_TOUCH_MOVE
-------------------------------

The position of a touch changed.

Has the same fields as *note ALLEGRO_EVENT_TOUCH_BEGIN:
#allegro_event_touch_begin.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_EVENT_TOUCH_CANCEL,  Next: ALLEGRO_EVENT_TIMER,  Prev: ALLEGRO_EVENT_TOUCH_MOVE,  Up: ALLEGRO_EVENT

4.1.17 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 *note ALLEGRO_EVENT_TOUCH_BEGIN:
#allegro_event_touch_begin.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_EVENT_TIMER,  Next: ALLEGRO_EVENT_DISPLAY_EXPOSE,  Prev: ALLEGRO_EVENT_TOUCH_CANCEL,  Up: ALLEGRO_EVENT

4.1.18 ALLEGRO_EVENT_TIMER
--------------------------

A *note timer: #allegro_timer. counter incremented.

timer.source (ALLEGRO_TIMER *)

     The timer which generated the event.
timer.count (int64_t)

     The timer count value.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_EXPOSE,  Next: ALLEGRO_EVENT_DISPLAY_RESIZE,  Prev: ALLEGRO_EVENT_TIMER,  Up: ALLEGRO_EVENT

4.1.19 ALLEGRO_EVENT_DISPLAY_EXPOSE
-----------------------------------

The display (or a portion thereof) has become visible.

display.source (ALLEGRO_DISPLAY *)

     The display which was exposed.
display.x (int)

     The X position of the top-left corner of the rectangle which was
     exposed.
display.y (int)

     The Y position of the top-left corner of the rectangle which was
     exposed.
display.width (int)

     The width of the rectangle which was exposed.
display.height (int)

     The height of the rectangle which was exposed.

     _Note:_ The display needs to be created with
     ALLEGRO_GENERATE_EXPOSE_EVENTS flag for these events to be
     generated.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_RESIZE,  Next: ALLEGRO_EVENT_DISPLAY_CLOSE,  Prev: ALLEGRO_EVENT_DISPLAY_EXPOSE,  Up: ALLEGRO_EVENT

4.1.20 ALLEGRO_EVENT_DISPLAY_RESIZE
-----------------------------------

The window has been resized.

display.source (ALLEGRO_DISPLAY *)

     The display which was resized.
display.x (int)

     The X position of the top-left corner of the display.
display.y (int)

     The Y position of the top-left corner of the display.
display.width (int)

     The new width of the display.
display.height (int)

     The new height of the display.

You should normally respond to these events by calling *note
al_acknowledge_resize: #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.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_CLOSE,  Next: ALLEGRO_EVENT_DISPLAY_LOST,  Prev: ALLEGRO_EVENT_DISPLAY_RESIZE,  Up: ALLEGRO_EVENT

4.1.21 ALLEGRO_EVENT_DISPLAY_CLOSE
----------------------------------

The close button of the window has been pressed.

display.source (ALLEGRO_DISPLAY *)

     The display which was closed.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_LOST,  Next: ALLEGRO_EVENT_DISPLAY_FOUND,  Prev: ALLEGRO_EVENT_DISPLAY_CLOSE,  Up: ALLEGRO_EVENT

4.1.22 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 ALLEGRO_NO_PRESERVE_TEXTURE flag)
and restore them when the device is “found” (see *note
ALLEGRO_EVENT_DISPLAY_FOUND: #allegro_event_display_found.).  However,
this is not 100% fool proof (see discussion in *note al_create_bitmap:
#al_create_bitmap.’s documentation).

     _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.
display.source (ALLEGRO_DISPLAY *)

     The display which was lost.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_FOUND,  Next: ALLEGRO_EVENT_DISPLAY_SWITCH_OUT,  Prev: ALLEGRO_EVENT_DISPLAY_LOST,  Up: ALLEGRO_EVENT

4.1.23 ALLEGRO_EVENT_DISPLAY_FOUND
----------------------------------

Generated when a lost device is restored to operating state.  See *note
ALLEGRO_EVENT_DISPLAY_LOST: #allegro_event_display_lost.

display.source (ALLEGRO_DISPLAY *)

     The display which was found.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_SWITCH_OUT,  Next: ALLEGRO_EVENT_DISPLAY_SWITCH_IN,  Prev: ALLEGRO_EVENT_DISPLAY_FOUND,  Up: ALLEGRO_EVENT

4.1.24 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 *note al_clear_keyboard_state: #al_clear_keyboard_state.
(possibly passing display.source as its argument) in order to prevent
Allegro’s keyboard state from getting out of sync.

display.source (ALLEGRO_DISPLAY *)

     The display which was switched out of.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_SWITCH_IN,  Next: ALLEGRO_EVENT_DISPLAY_ORIENTATION,  Prev: ALLEGRO_EVENT_DISPLAY_SWITCH_OUT,  Up: ALLEGRO_EVENT

4.1.25 ALLEGRO_EVENT_DISPLAY_SWITCH_IN
--------------------------------------

The window is the active one again.

display.source (ALLEGRO_DISPLAY *)

     The display which was switched into.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_ORIENTATION,  Next: ALLEGRO_EVENT_DISPLAY_HALT_DRAWING,  Prev: ALLEGRO_EVENT_DISPLAY_SWITCH_IN,  Up: ALLEGRO_EVENT

4.1.26 ALLEGRO_EVENT_DISPLAY_ORIENTATION
----------------------------------------

Generated when the rotation or orientation of a display changes.

display.source (ALLEGRO_DISPLAY *)

     The display which generated the event.
event.display.orientation

     Contains one of the following values:

        • ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES
        • ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES
        • ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES
        • ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES
        • ALLEGRO_DISPLAY_ORIENTATION_FACE_UP
        • ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_HALT_DRAWING,  Next: ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING,  Prev: ALLEGRO_EVENT_DISPLAY_ORIENTATION,  Up: ALLEGRO_EVENT

4.1.27 ALLEGRO_EVENT_DISPLAY_HALT_DRAWING
-----------------------------------------

When a display receives this event it should stop doing any drawing and
then call *note al_acknowledge_drawing_halt:
#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
*note ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
#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.

     _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 *note
     al_acknowledge_drawing_halt: #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.
     _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 *note al_stop_timer: #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
     NULL to *note al_set_default_voice: #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.
Since: 5.1.0

See also: *note ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING:
#allegro_event_display_resume_drawing.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING,  Next: ALLEGRO_EVENT_DISPLAY_CONNECTED,  Prev: ALLEGRO_EVENT_DISPLAY_HALT_DRAWING,  Up: ALLEGRO_EVENT

4.1.28 ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING
-------------------------------------------

When a display receives this event, it may resume drawing again, and it
must call *note al_acknowledge_drawing_resume:
#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 *note
ALLEGRO_EVENT_DISPLAY_SWITCH_IN: #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.

     _Note:_ Unlike *note ALLEGRO_EVENT_DISPLAY_FOUND:
     #allegro_event_display_found. it is not necessary to reload any
     bitmaps when you receive this event.
Since: 5.1.0

See also: *note ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
#allegro_event_display_halt_drawing.


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_CONNECTED,  Next: ALLEGRO_EVENT_DISPLAY_DISCONNECTED,  Prev: ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING,  Up: ALLEGRO_EVENT

4.1.29 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.

display.source (ALLEGRO_DISPLAY *)

     The display which was connected.

Since: 5.1.1


File: refman.info,  Node: ALLEGRO_EVENT_DISPLAY_DISCONNECTED,  Prev: ALLEGRO_EVENT_DISPLAY_CONNECTED,  Up: ALLEGRO_EVENT

4.1.30 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.

display.source (ALLEGRO_DISPLAY *)

     The display which was disconnected.


File: refman.info,  Node: ALLEGRO_USER_EVENT,  Next: ALLEGRO_EVENT_QUEUE,  Prev: ALLEGRO_EVENT,  Up: Event system and events

4.2 ALLEGRO_USER_EVENT
======================

typedef struct ALLEGRO_USER_EVENT ALLEGRO_USER_EVENT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L186)

An event structure that can be emitted by user event sources.  These are
the public fields:

   • ALLEGRO_EVENT_SOURCE *source;
   • intptr_t data1;
   • intptr_t data2;
   • intptr_t data3;
   • intptr_t data4;

Like all other event types this structure is a part of the ALLEGRO_EVENT
union.  To access the fields in an ALLEGRO_EVENT variable ‘ev’, you
would use:

   • 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:

ALLEGRO_EVENT_SOURCE my_event_source;
ALLEGRO_EVENT my_event;
float some_var;

al_init_user_event_source(&my_event_source);

my_event.user.type = ALLEGRO_GET_EVENT_TYPE('M','I','N','E');
my_event.user.data1 = 1;
my_event.user.data2 = &some_var;

al_emit_user_event(&my_event_source, &my_event, NULL);

Event type identifiers for user events are assigned by the user.  Please
see the documentation for *note ALLEGRO_GET_EVENT_TYPE:
#allegro_get_event_type. for the rules you should follow when assigning
identifiers.

See also: *note al_emit_user_event: #al_emit_user_event, *note
ALLEGRO_GET_EVENT_TYPE: #allegro_get_event_type, *note
al_init_user_event_source: #al_init_user_event_source.


File: refman.info,  Node: ALLEGRO_EVENT_QUEUE,  Next: ALLEGRO_EVENT_SOURCE,  Prev: ALLEGRO_USER_EVENT,  Up: Event system and events

4.3 ALLEGRO_EVENT_QUEUE
=======================

typedef struct ALLEGRO_EVENT_QUEUE ALLEGRO_EVENT_QUEUE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L243)

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.

See also: *note al_create_event_queue: #al_create_event_queue, *note
al_destroy_event_queue: #al_destroy_event_queue.


File: refman.info,  Node: ALLEGRO_EVENT_SOURCE,  Next: ALLEGRO_EVENT_TYPE,  Prev: ALLEGRO_EVENT_QUEUE,  Up: Event system and events

4.4 ALLEGRO_EVENT_SOURCE
========================

typedef struct ALLEGRO_EVENT_SOURCE ALLEGRO_EVENT_SOURCE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L72)

An event source is any object which can generate events.  For example,
an ALLEGRO_DISPLAY can generate events, and you can get the
ALLEGRO_EVENT_SOURCE pointer from an ALLEGRO_DISPLAY with *note
al_get_display_event_source: #al_get_display_event_source.

You may create your own “user” event sources that emit custom events.

See also: *note ALLEGRO_EVENT: #allegro_event, *note
al_init_user_event_source: #al_init_user_event_source, *note
al_emit_user_event: #al_emit_user_event.


File: refman.info,  Node: ALLEGRO_EVENT_TYPE,  Next: ALLEGRO_GET_EVENT_TYPE,  Prev: ALLEGRO_EVENT_SOURCE,  Up: Event system and events

4.5 ALLEGRO_EVENT_TYPE
======================

typedef unsigned int ALLEGRO_EVENT_TYPE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L13)

An integer used to distinguish between different types of events.

See also: *note ALLEGRO_EVENT: #allegro_event, *note
ALLEGRO_GET_EVENT_TYPE: #allegro_get_event_type, *note
ALLEGRO_EVENT_TYPE_IS_USER: #allegro_event_type_is_user.


File: refman.info,  Node: ALLEGRO_GET_EVENT_TYPE,  Next: ALLEGRO_EVENT_TYPE_IS_USER,  Prev: ALLEGRO_EVENT_TYPE,  Up: Event system and events

4.6 ALLEGRO_GET_EVENT_TYPE
==========================

#define ALLEGRO_GET_EVENT_TYPE(a, b, c, d)   AL_ID(a, b, c, d)

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L67)

Make 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:

#define MY_EVENT_TYPE   ALLEGRO_GET_EVENT_TYPE('M','I','N','E')

IDs less than 1024 are reserved for Allegro or its addons.  Don’t use
anything lower than ‘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:

#define BASE_EVENT   ALLEGRO_GET_EVENT_TYPE('M','I','N','E')
#define BARK_EVENT   (BASE_EVENT + 0)
#define MEOW_EVENT   (BASE_EVENT + 1)
#define SQUAWK_EVENT (BASE_EVENT + 2)

/* Alternatively */
enum {
   BARK_EVENT = ALLEGRO_GET_EVENT_TYPE('M','I','N','E'),
   MEOW_EVENT,
   SQUAWK_EVENT
};

See also: *note ALLEGRO_EVENT: #allegro_event, *note ALLEGRO_USER_EVENT:
#allegro_user_event, *note ALLEGRO_EVENT_TYPE_IS_USER:
#allegro_event_type_is_user.


File: refman.info,  Node: ALLEGRO_EVENT_TYPE_IS_USER,  Next: al_create_event_queue,  Prev: ALLEGRO_GET_EVENT_TYPE,  Up: Event system and events

4.7 ALLEGRO_EVENT_TYPE_IS_USER
==============================

#define ALLEGRO_EVENT_TYPE_IS_USER(t)        ((t) >= 512)

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/events.h#L62)

A macro which evaluates to true if the event type is not a builtin event
type, i.e. one of those described in *note ALLEGRO_EVENT_TYPE:
#allegro_event_type.


File: refman.info,  Node: al_create_event_queue,  Next: al_destroy_event_queue,  Prev: ALLEGRO_EVENT_TYPE_IS_USER,  Up: Event system and events

4.8 al_create_event_queue
=========================

ALLEGRO_EVENT_QUEUE *al_create_event_queue(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L90)

Create a new, empty event queue, returning a pointer to the newly
created object if successful.  Returns NULL on error.

See also: *note al_register_event_source: #al_register_event_source,
*note al_destroy_event_queue: #al_destroy_event_queue, *note
ALLEGRO_EVENT_QUEUE: #allegro_event_queue.


File: refman.info,  Node: al_destroy_event_queue,  Next: al_register_event_source,  Prev: al_create_event_queue,  Up: Event system and events

4.9 al_destroy_event_queue
==========================

void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L120)

Destroy the event queue specified.  All event sources currently
registered with the queue will be automatically unregistered before the
queue is destroyed.

See also: *note al_create_event_queue: #al_create_event_queue, *note
ALLEGRO_EVENT_QUEUE: #allegro_event_queue.


File: refman.info,  Node: al_register_event_source,  Next: al_unregister_event_source,  Prev: al_destroy_event_queue,  Up: Event system and events

4.10 al_register_event_source
=============================

void al_register_event_source(ALLEGRO_EVENT_QUEUE *queue,
   ALLEGRO_EVENT_SOURCE *source)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L161)

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.

See also: *note al_unregister_event_source: #al_unregister_event_source,
*note ALLEGRO_EVENT_SOURCE: #allegro_event_source.


File: refman.info,  Node: al_unregister_event_source,  Next: al_is_event_source_registered,  Prev: al_register_event_source,  Up: Event system and events

4.11 al_unregister_event_source
===============================

void al_unregister_event_source(ALLEGRO_EVENT_QUEUE *queue,
   ALLEGRO_EVENT_SOURCE *source)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L181)

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.

See also: *note al_register_event_source: #al_register_event_source.


File: refman.info,  Node: al_is_event_source_registered,  Next: al_pause_event_queue,  Prev: al_unregister_event_source,  Up: Event system and events

4.12 al_is_event_source_registered
==================================

bool al_is_event_source_registered(ALLEGRO_EVENT_QUEUE *queue, 
      ALLEGRO_EVENT_SOURCE *source)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L147)

Return true if the event source is registered.

See also: *note al_register_event_source: #al_register_event_source.

Since: 5.2.0


File: refman.info,  Node: al_pause_event_queue,  Next: al_is_event_queue_paused,  Prev: al_is_event_source_registered,  Up: Event system and events

4.13 al_pause_event_queue
=========================

void al_pause_event_queue(ALLEGRO_EVENT_QUEUE *queue, bool pause)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L208)

Pause or resume 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.

See also: *note al_is_event_queue_paused: #al_is_event_queue_paused.

Since: 5.1.0


File: refman.info,  Node: al_is_event_queue_paused,  Next: al_is_event_queue_empty,  Prev: al_pause_event_queue,  Up: Event system and events

4.14 al_is_event_queue_paused
=============================

bool al_is_event_queue_paused(const ALLEGRO_EVENT_QUEUE *queue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L221)

Return true if the event queue is paused.

See also: *note al_pause_event_queue: #al_pause_event_queue.

Since: 5.1.0


File: refman.info,  Node: al_is_event_queue_empty,  Next: al_get_next_event,  Prev: al_is_event_queue_paused,  Up: Event system and events

4.15 al_is_event_queue_empty
============================

bool al_is_event_queue_empty(ALLEGRO_EVENT_QUEUE *queue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L248)

Return true if the event queue specified is currently empty.

See also: *note al_get_next_event: #al_get_next_event, *note
al_peek_next_event: #al_peek_next_event.


File: refman.info,  Node: al_get_next_event,  Next: al_peek_next_event,  Prev: al_is_event_queue_empty,  Up: Event system and events

4.16 al_get_next_event
======================

bool al_get_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L299)

Take the next event out of the event queue specified, and copy the
contents into ‘ret_event’, returning true.  The original event will be
removed from the queue.  If the event queue is empty, return false and
the contents of ‘ret_event’ are unspecified.

See also: *note ALLEGRO_EVENT: #allegro_event, *note al_peek_next_event:
#al_peek_next_event, *note al_wait_for_event: #al_wait_for_event.


File: refman.info,  Node: al_peek_next_event,  Next: al_drop_next_event,  Prev: al_get_next_event,  Up: Event system and events

4.17 al_peek_next_event
=======================

bool al_peek_next_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L324)

Copy the contents of the next event in the event queue specified into
‘ret_event’ and return 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 ‘ret_event’ are unspecified.

See also: *note ALLEGRO_EVENT: #allegro_event, *note al_get_next_event:
#al_get_next_event, *note al_drop_next_event: #al_drop_next_event.


File: refman.info,  Node: al_drop_next_event,  Next: al_flush_event_queue,  Prev: al_peek_next_event,  Up: Event system and events

4.18 al_drop_next_event
=======================

bool al_drop_next_event(ALLEGRO_EVENT_QUEUE *queue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L349)

Drop (remove) the next event from the queue.  If the queue is empty,
nothing happens.  Returns true if an event was dropped.

See also: *note al_flush_event_queue: #al_flush_event_queue, *note
al_is_event_queue_empty: #al_is_event_queue_empty.


File: refman.info,  Node: al_flush_event_queue,  Next: al_wait_for_event,  Prev: al_drop_next_event,  Up: Event system and events

4.19 al_flush_event_queue
=========================

void al_flush_event_queue(ALLEGRO_EVENT_QUEUE *queue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L372)

Drops all events, if any, from the queue.

See also: *note al_drop_next_event: #al_drop_next_event, *note
al_is_event_queue_empty: #al_is_event_queue_empty.


File: refman.info,  Node: al_wait_for_event,  Next: al_wait_for_event_timed,  Prev: al_flush_event_queue,  Up: Event system and events

4.20 al_wait_for_event
======================

void al_wait_for_event(ALLEGRO_EVENT_QUEUE *queue, ALLEGRO_EVENT *ret_event)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L398)

Wait until the event queue specified is non-empty.  If ‘ret_event’ is
not NULL, the first event in the queue will be copied into ‘ret_event’
and removed from the queue.  If ‘ret_event’ is NULL the first event is
left at the head of the queue.

See also: *note ALLEGRO_EVENT: #allegro_event, *note
al_wait_for_event_timed: #al_wait_for_event_timed, *note
al_wait_for_event_until: #al_wait_for_event_until, *note
al_get_next_event: #al_get_next_event.


File: refman.info,  Node: al_wait_for_event_timed,  Next: al_wait_for_event_until,  Prev: al_wait_for_event,  Up: Event system and events

4.21 al_wait_for_event_timed
============================

bool al_wait_for_event_timed(ALLEGRO_EVENT_QUEUE *queue,
   ALLEGRO_EVENT *ret_event, float secs)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L430)

Wait until the event queue specified is non-empty.  If ‘ret_event’ is
not NULL, the first event in the queue will be copied into ‘ret_event’
and removed from the queue.  If ‘ret_event’ is NULL the first event is
left at the head of the queue.

‘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, ‘secs’ must be 2,147,483.647
seconds or less.

See also: *note ALLEGRO_EVENT: #allegro_event, *note al_wait_for_event:
#al_wait_for_event, *note al_wait_for_event_until:
#al_wait_for_event_until.


File: refman.info,  Node: al_wait_for_event_until,  Next: al_init_user_event_source,  Prev: al_wait_for_event_timed,  Up: Event system and events

4.22 al_wait_for_event_until
============================

bool al_wait_for_event_until(ALLEGRO_EVENT_QUEUE *queue,
   ALLEGRO_EVENT *ret_event, ALLEGRO_TIMEOUT *timeout)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L452)

Wait until the event queue specified is non-empty.  If ‘ret_event’ is
not NULL, the first event in the queue will be copied into ‘ret_event’
and removed from the queue.  If ‘ret_event’ is NULL the first event is
left at the head of the queue.

‘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, ‘timeout’ must be 2,147,483.647
seconds or less.

See also: *note ALLEGRO_EVENT: #allegro_event, *note ALLEGRO_TIMEOUT:
#allegro_timeout, *note al_init_timeout: #al_init_timeout, *note
al_wait_for_event: #al_wait_for_event, *note al_wait_for_event_timed:
#al_wait_for_event_timed.


File: refman.info,  Node: al_init_user_event_source,  Next: al_destroy_user_event_source,  Prev: al_wait_for_event_until,  Up: Event system and events

4.23 al_init_user_event_source
==============================

void al_init_user_event_source(ALLEGRO_EVENT_SOURCE *src)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/evtsrc.c#L195)

Initialise 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 ALLEGRO_EVENT_SOURCE at the head, e.g.

typedef struct THING THING;

struct THING {
    ALLEGRO_EVENT_SOURCE event_source;
    int field1;
    int field2;
    /* etc. */
};

THING *create_thing(void)
{
    THING *thing = malloc(sizeof(THING));

    if (thing) {
        al_init_user_event_source(&thing->event_source);
        thing->field1 = 0;
        thing->field2 = 0;
    }

    return thing;
}

The advantage here is that the THING pointer will be the same as the
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 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 *note al_destroy_user_event_source:
#al_destroy_user_event_source.

See also: *note ALLEGRO_EVENT_SOURCE: #allegro_event_source, *note
al_destroy_user_event_source: #al_destroy_user_event_source, *note
al_emit_user_event: #al_emit_user_event, *note ALLEGRO_USER_EVENT:
#allegro_user_event.


File: refman.info,  Node: al_destroy_user_event_source,  Next: al_emit_user_event,  Prev: al_init_user_event_source,  Up: Event system and events

4.24 al_destroy_user_event_source
=================================

void al_destroy_user_event_source(ALLEGRO_EVENT_SOURCE *src)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/evtsrc.c#L206)

Destroy an event source initialised with *note
al_init_user_event_source: #al_init_user_event_source.

This does not free the memory, as that was user allocated to begin with.

See also: *note ALLEGRO_EVENT_SOURCE: #allegro_event_source.


File: refman.info,  Node: al_emit_user_event,  Next: al_unref_user_event,  Prev: al_destroy_user_event_source,  Up: Event system and events

4.25 al_emit_user_event
=======================

bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src,
   ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/evtsrc.c#L217)

Emit an event from a user event source.  The event source must have been
initialised with *note al_init_user_event_source:
#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 ‘dtor’ is not NULL. Whenever a
copy of the event is made, the reference count increases.  You need to
call *note al_unref_user_event: #al_unref_user_event. to decrease the
reference count once you are done with a user event that you have
received from *note al_get_next_event: #al_get_next_event, *note
al_peek_next_event: #al_peek_next_event, *note al_wait_for_event:
#al_wait_for_event, etc.

Once the reference count drops to zero ‘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 ‘dtor’ is NULL then reference counting will not be performed.  It is
safe, but unnecessary, to call *note al_unref_user_event:
#al_unref_user_event. on non-reference counted user events.

You can use 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 *note ALLEGRO_EVENT_KEY_DOWN: #allegro_event_key_down,
but it will not update the *note ALLEGRO_KEYBOARD_STATE:
#allegro_keyboard_state. returned by *note al_get_keyboard_state:
#al_get_keyboard_state.

See also: *note ALLEGRO_USER_EVENT: #allegro_user_event, *note
al_unref_user_event: #al_unref_user_event.


File: refman.info,  Node: al_unref_user_event,  Next: al_get_event_source_data,  Prev: al_emit_user_event,  Up: Event system and events

4.26 al_unref_user_event
========================

void al_unref_user_event(ALLEGRO_USER_EVENT *event)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/events.c#L711)

Decrease the reference count of a user-defined event.  This must be
called on any user event that you get from *note al_get_next_event:
#al_get_next_event, *note al_peek_next_event: #al_peek_next_event, *note
al_wait_for_event: #al_wait_for_event, etc.  which is reference counted.
This function does nothing if the event is not reference counted.

See also: *note al_emit_user_event: #al_emit_user_event, *note
ALLEGRO_USER_EVENT: #allegro_user_event.


File: refman.info,  Node: al_get_event_source_data,  Next: al_set_event_source_data,  Prev: al_unref_user_event,  Up: Event system and events

4.27 al_get_event_source_data
=============================

intptr_t al_get_event_source_data(const ALLEGRO_EVENT_SOURCE *source)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/evtsrc.c#L274)

Returns the abstract user data associated with the event source.  If no
data was previously set, returns NULL.

See also: *note al_set_event_source_data: #al_set_event_source_data.


File: refman.info,  Node: al_set_event_source_data,  Prev: al_get_event_source_data,  Up: Event system and events

4.28 al_set_event_source_data
=============================

void al_set_event_source_data(ALLEGRO_EVENT_SOURCE *source, intptr_t data)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/evtsrc.c#L264)

Assign 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.

See also: *note al_get_event_source_data: #al_get_event_source_data.


File: refman.info,  Node: File I/O,  Next: Fixed point math routines,  Prev: Event system and events,  Up: Top

5 File I/O
**********

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_FILE::
* ALLEGRO_FILE_INTERFACE::
* ALLEGRO_SEEK::
* al_fopen::
* al_fopen_interface::
* al_fopen_slice::
* al_fclose::
* al_fread::
* al_fwrite::
* al_fflush::
* al_ftell::
* al_fseek::
* al_feof::
* al_ferror::
* al_ferrmsg::
* al_fclearerr::
* al_fungetc::
* al_fsize::
* al_fgetc::
* al_fputc::
* al_fprintf::
* al_vfprintf::
* al_fread16le::
* al_fread16be::
* al_fwrite16le::
* al_fwrite16be::
* al_fread32le::
* al_fread32be::
* al_fwrite32le::
* al_fwrite32be::
* al_fgets::
* al_fget_ustr::
* al_fputs::
* Standard I/O specific routines::
* Alternative file streams::


File: refman.info,  Node: ALLEGRO_FILE,  Next: ALLEGRO_FILE_INTERFACE,  Up: File I/O

5.1 ALLEGRO_FILE
================

typedef struct ALLEGRO_FILE ALLEGRO_FILE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/file.h#L15)

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


File: refman.info,  Node: ALLEGRO_FILE_INTERFACE,  Next: ALLEGRO_SEEK,  Prev: ALLEGRO_FILE,  Up: File I/O

5.2 ALLEGRO_FILE_INTERFACE
==========================

typedef struct ALLEGRO_FILE_INTERFACE

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/file.h#L20)

A structure containing function pointers to handle a type of “file”,
real or virtual.  See the full discussion in *note
al_set_new_file_interface: #al_set_new_file_interface.

The fields are:

void*         (*fi_fopen)(const char *path, const char *mode);
bool          (*fi_fclose)(ALLEGRO_FILE *f);
size_t        (*fi_fread)(ALLEGRO_FILE *f, void *ptr, size_t size);
size_t        (*fi_fwrite)(ALLEGRO_FILE *f, const void *ptr, size_t size);
bool          (*fi_fflush)(ALLEGRO_FILE *f);
int64_t       (*fi_ftell)(ALLEGRO_FILE *f);
bool          (*fi_fseek)(ALLEGRO_FILE *f, int64_t offset, int whence);
bool          (*fi_feof)(ALLEGRO_FILE *f);
int           (*fi_ferror)(ALLEGRO_FILE *f);
const char *  (*fi_ferrmsg)(ALLEGRO_FILE *f);
void          (*fi_fclearerr)(ALLEGRO_FILE *f);
int           (*fi_fungetc)(ALLEGRO_FILE *f, int c);
off_t         (*fi_fsize)(ALLEGRO_FILE *f);

The 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 *note al_get_file_userdata: #al_get_file_userdata.
on the file handle.  If fi_open returns NULL then *note al_fopen:
#al_fopen. will also return NULL.

The fi_fclose function must clean up and free the userdata, but Allegro
will free the *note ALLEGRO_FILE: #allegro_file. handle.

If fi_fungetc is NULL, then Allegro’s default implementation of a 16
char long buffer will be used.


File: refman.info,  Node: ALLEGRO_SEEK,  Next: al_fopen,  Prev: ALLEGRO_FILE_INTERFACE,  Up: File I/O

5.3 ALLEGRO_SEEK
================

typedef enum ALLEGRO_SEEK

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/file.h#L40)

   • ALLEGRO_SEEK_SET - seek relative to beginning of file
   • ALLEGRO_SEEK_CUR - seek relative to current file position
   • ALLEGRO_SEEK_END - seek relative to end of file

See also: *note al_fseek: #al_fseek.


File: refman.info,  Node: al_fopen,  Next: al_fopen_interface,  Prev: ALLEGRO_SEEK,  Up: File I/O

5.4 al_fopen
============

ALLEGRO_FILE *al_fopen(const char *path, const char *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L24)

Creates and opens a file (real or virtual) given the path and mode.  The
current file interface is used to open the file.

Parameters:

   • path - path to the file to open
   • mode - access mode to open the file in (“r”, “w”, etc.)

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 CR+LF sequences,
a call to *note al_fgetc: #al_fgetc. may return just one character
(‘\n’) where there were two bytes (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 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. “rb”, “wb”.

Returns a file handle on success, or NULL on error.

See also: *note al_set_new_file_interface: #al_set_new_file_interface,
*note al_fclose: #al_fclose.


File: refman.info,  Node: al_fopen_interface,  Next: al_fopen_slice,  Prev: al_fopen,  Up: File I/O

5.5 al_fopen_interface
======================

ALLEGRO_FILE *al_fopen_interface(const ALLEGRO_FILE_INTERFACE *drv,
   const char *path, const char *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L32)

Opens a file using the specified interface, instead of the interface set
with *note al_set_new_file_interface: #al_set_new_file_interface.

See also: *note al_fopen: #al_fopen.


File: refman.info,  Node: al_fopen_slice,  Next: al_fclose,  Prev: al_fopen_interface,  Up: File I/O

5.6 al_fopen_slice
==================

ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file_slice.c#L209)

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 ‘initial_size’ bytes.  The ‘initial_size’ may be any
non-negative integer that will not exceed the bounds of the parent file.

Seeking with ‘ALLEGRO_SEEK_SET’ will be relative to this starting
location.  ‘ALLEGRO_SEEK_END’ will be relative to the starting location
plus the size of the slice.

The mode can be any combination of:

   • r: read access
   • w: write access
   • e: expandable
   • s: seek to the end of the slice upon [al_close] (this is the
     default behavior)
   • n: disable the seeking behavior of “s”.

For example, a mode of “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 *note al_fclose: #al_fclose.  The parent
file will then be positioned immediately after the end of the slice.
This behavior can be disabled by setting the “n” mode.

Since: 5.0.6, 5.1.0

See also: *note al_fopen: #al_fopen.


File: refman.info,  Node: al_fclose,  Next: al_fread,  Prev: al_fopen_slice,  Up: File I/O

5.7 al_fclose
=============

bool al_fclose(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L86)

Close the given file, writing any buffered output data (if any).

Returns true on success, false on failure.  errno is set to indicate the
error.


File: refman.info,  Node: al_fread,  Next: al_fwrite,  Prev: al_fclose,  Up: File I/O

5.8 al_fread
============

size_t al_fread(ALLEGRO_FILE *f, void *ptr, size_t size)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L101)

Read ‘size’ bytes into the buffer pointed to by ‘ptr’, from the given
file.

Returns 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).

al_fread() does not distinguish between EOF and other errors.  Use *note
al_feof: #al_feof. and *note al_ferror: #al_ferror. to determine which
occurred.

See also: *note al_fgetc: #al_fgetc, *note al_fread16be: #al_fread16be,
*note al_fread16le: #al_fread16le, *note al_fread32be: #al_fread32be,
*note al_fread32le: #al_fread32le.


File: refman.info,  Node: al_fwrite,  Next: al_fflush,  Prev: al_fread,  Up: File I/O

5.9 al_fwrite
=============

size_t al_fwrite(ALLEGRO_FILE *f, const void *ptr, size_t size)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L126)

Write ‘size’ bytes from the buffer pointed to by ‘ptr’ into the given
file.

Returns the number of bytes actually written.  If an error occurs, the
return value is a short byte count (or zero).

See also: *note al_fputc: #al_fputc, *note al_fputs: #al_fputs, *note
al_fwrite16be: #al_fwrite16be, *note al_fwrite16le: #al_fwrite16le,
*note al_fwrite32be: #al_fwrite32be, *note al_fwrite32le:
#al_fwrite32le.


File: refman.info,  Node: al_fflush,  Next: al_ftell,  Prev: al_fwrite,  Up: File I/O

5.10 al_fflush
==============

bool al_fflush(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L138)

Flush any pending writes to the given file.

Returns true on success, false otherwise.  errno is set to indicate the
error.

See also: *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_ftell,  Next: al_fseek,  Prev: al_fflush,  Up: File I/O

5.11 al_ftell
=============

int64_t al_ftell(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L148)

Returns the current position in the given file, or -1 on error.  errno
is set to indicate the error.

On some platforms this function may not support large files.

See also: *note al_fseek: #al_fseek, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_fseek,  Next: al_feof,  Prev: al_ftell,  Up: File I/O

5.12 al_fseek
=============

bool al_fseek(ALLEGRO_FILE *f, int64_t offset, int whence)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L158)

Set the current position of the given file to a position relative to
that specified by ‘whence’, plus ‘offset’ number of bytes.

‘whence’ can be:

   • ALLEGRO_SEEK_SET - seek relative to beginning of file
   • ALLEGRO_SEEK_CUR - seek relative to current file position
   • ALLEGRO_SEEK_END - seek relative to end of file

Returns true on success, false on failure.  errno is set to indicate the
error.

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.

See also: *note al_ftell: #al_ftell, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_feof,  Next: al_ferror,  Prev: al_fseek,  Up: File I/O

5.13 al_feof
============

bool al_feof(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L181)

Returns true if the end-of-file indicator has been set on the file,
i.e. we have attempted to read _past_ the end of the file.

This does _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:

int b1 = al_fgetc(f);
int b2 = al_fgetc(f);
if (al_feof(f)) {
   /* At least one byte was unsuccessfully read. */
   report_error();
}

See also: *note al_ferror: #al_ferror, *note al_fclearerr:
#al_fclearerr.


File: refman.info,  Node: al_ferror,  Next: al_ferrmsg,  Prev: al_feof,  Up: File I/O

5.14 al_ferror
==============

int al_ferror(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L191)

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.

See also: *note al_feof: #al_feof, *note al_fclearerr: #al_fclearerr,
*note al_ferrmsg: #al_ferrmsg.


File: refman.info,  Node: al_ferrmsg,  Next: al_fclearerr,  Prev: al_ferror,  Up: File I/O

5.15 al_ferrmsg
===============

const char *al_ferrmsg(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L201)

Return 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.

See also: *note al_fclearerr: #al_fclearerr, *note al_ferror:
#al_ferror.


File: refman.info,  Node: al_fclearerr,  Next: al_fungetc,  Prev: al_ferrmsg,  Up: File I/O

5.16 al_fclearerr
=================

void al_fclearerr(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L214)

Clear 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.

See also: *note al_ferror: #al_ferror, *note al_feof: #al_feof.


File: refman.info,  Node: al_fungetc,  Next: al_fsize,  Prev: al_fclearerr,  Up: File I/O

5.17 al_fungetc
===============

int al_fungetc(ALLEGRO_FILE *f, int c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L497)

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 *note al_fseek:
#al_fseek. and *note al_ftell: #al_ftell. are relative to the number of
pushbacks.  If a pushback causes the position to become negative, the
behavior of *note al_fseek: #al_fseek. and *note al_ftell: #al_ftell.
are undefined.

See also: *note al_fgetc: #al_fgetc, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_fsize,  Next: al_fgetc,  Prev: al_fungetc,  Up: File I/O

5.18 al_fsize
=============

int64_t al_fsize(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L523)

Return the size of the file, if it can be determined, or -1 otherwise.


File: refman.info,  Node: al_fgetc,  Next: al_fputc,  Prev: al_fsize,  Up: File I/O

5.19 al_fgetc
=============

int al_fgetc(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L224)

Read and return next byte in the given file.  Returns EOF on end of file
or if an error occurred.

See also: *note al_fungetc: #al_fungetc.


File: refman.info,  Node: al_fputc,  Next: al_fprintf,  Prev: al_fgetc,  Up: File I/O

5.20 al_fputc
=============

int al_fputc(ALLEGRO_FILE *f, int c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L239)

Write a single byte to the given file.  The byte written is the value of
c cast to an unsigned char.

Parameters:

   • c - byte value to write
   • f - file to write to

Returns the written byte (cast back to an int) on success, or EOF on
error.


File: refman.info,  Node: al_fprintf,  Next: al_vfprintf,  Prev: al_fputc,  Up: File I/O

5.21 al_fprintf
===============

int al_fprintf(ALLEGRO_FILE *pfile, const char *format, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L576)

Writes to a file with stdio “printf”-like formatting.  Returns the
number of bytes written, or a negative number on error.

See also: *note al_vfprintf: #al_vfprintf.


File: refman.info,  Node: al_vfprintf,  Next: al_fread16le,  Prev: al_fprintf,  Up: File I/O

5.22 al_vfprintf
================

int al_vfprintf(ALLEGRO_FILE *pfile, const char *format, va_list args)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L543)

Like al_fprintf but takes a va_list.  Useful for creating your own
variations of formatted printing.  Returns the number of bytes written,
or a negative number on error.

See also: *note al_fprintf: #al_fprintf.


File: refman.info,  Node: al_fread16le,  Next: al_fread16be,  Prev: al_vfprintf,  Up: File I/O

5.23 al_fread16le
=================

int16_t al_fread16le(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L254)

Reads a 16-bit word in little-endian format (LSB first).

On success, returns the 16-bit word.  On failure, returns EOF (-1).
Since -1 is also a valid return value, use *note al_feof: #al_feof. to
check if the end of the file was reached prematurely, or *note
al_ferror: #al_ferror. to check if an error occurred.

See also: *note al_fread16be: #al_fread16be.


File: refman.info,  Node: al_fread16be,  Next: al_fwrite16le,  Prev: al_fread16le,  Up: File I/O

5.24 al_fread16be
=================

int16_t al_fread16be(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L333)

Reads a 16-bit word in big-endian format (MSB first).

On success, returns the 16-bit word.  On failure, returns EOF (-1).
Since -1 is also a valid return value, use *note al_feof: #al_feof. to
check if the end of the file was reached prematurely, or *note
al_ferror: #al_ferror. to check if an error occurred.

See also: *note al_fread16le: #al_fread16le.


File: refman.info,  Node: al_fwrite16le,  Next: al_fwrite16be,  Prev: al_fread16be,  Up: File I/O

5.25 al_fwrite16le
==================

size_t al_fwrite16le(ALLEGRO_FILE *f, int16_t w)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L285)

Writes a 16-bit word in little-endian format (LSB first).

Returns the number of bytes written: 2 on success, less than 2 on an
error.

See also: *note al_fwrite16be: #al_fwrite16be.


File: refman.info,  Node: al_fwrite16be,  Next: al_fread32le,  Prev: al_fwrite16le,  Up: File I/O

5.26 al_fwrite16be
==================

size_t al_fwrite16be(ALLEGRO_FILE *f, int16_t w)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L364)

Writes a 16-bit word in big-endian format (MSB first).

Returns the number of bytes written: 2 on success, less than 2 on an
error.

See also: *note al_fwrite16le: #al_fwrite16le.


File: refman.info,  Node: al_fread32le,  Next: al_fread32be,  Prev: al_fwrite16be,  Up: File I/O

5.27 al_fread32le
=================

int32_t al_fread32le(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L269)

Reads a 32-bit word in little-endian format (LSB first).

On success, returns the 32-bit word.  On failure, returns EOF (-1).
Since -1 is also a valid return value, use *note al_feof: #al_feof. to
check if the end of the file was reached prematurely, or *note
al_ferror: #al_ferror. to check if an error occurred.

See also: *note al_fread32be: #al_fread32be.


File: refman.info,  Node: al_fread32be,  Next: al_fwrite32le,  Prev: al_fread32le,  Up: File I/O

5.28 al_fread32be
=================

int32_t al_fread32be(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L348)

Read a 32-bit word in big-endian format (MSB first).

On success, returns the 32-bit word.  On failure, returns EOF (-1).
Since -1 is also a valid return value, use *note al_feof: #al_feof. to
check if the end of the file was reached prematurely, or *note
al_ferror: #al_ferror. to check if an error occurred.

See also: *note al_fread32le: #al_fread32le.


File: refman.info,  Node: al_fwrite32le,  Next: al_fwrite32be,  Prev: al_fread32be,  Up: File I/O

5.29 al_fwrite32le
==================

size_t al_fwrite32le(ALLEGRO_FILE *f, int32_t l)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L305)

Writes a 32-bit word in little-endian format (LSB first).

Returns the number of bytes written: 4 on success, less than 4 on an
error.

See also: *note al_fwrite32be: #al_fwrite32be.


File: refman.info,  Node: al_fwrite32be,  Next: al_fgets,  Prev: al_fwrite32le,  Up: File I/O

5.30 al_fwrite32be
==================

size_t al_fwrite32be(ALLEGRO_FILE *f, int32_t l)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L384)

Writes a 32-bit word in big-endian format (MSB first).

Returns the number of bytes written: 4 on success, less than 4 on an
error.

See also: *note al_fwrite32le: #al_fwrite32le.


File: refman.info,  Node: al_fgets,  Next: al_fget_ustr,  Prev: al_fwrite32be,  Up: File I/O

5.31 al_fgets
=============

char *al_fgets(ALLEGRO_FILE *f, char * const buf, size_t max)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L412)

Read 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 max-1 bytes are read, with one byte being
reserved for a NUL terminator.

Parameters:

   • f - file to read from
   • buf - buffer to fill
   • max - maximum size of buffer

Returns the pointer to buf on success.  Returns NULL if an error
occurred or if the end of file was reached without reading any bytes.

See *note al_fopen: #al_fopen. about translations of end-of-line
characters.

See also: *note al_fget_ustr: #al_fget_ustr.


File: refman.info,  Node: al_fget_ustr,  Next: al_fputs,  Prev: al_fgets,  Up: File I/O

5.32 al_fget_ustr
=================

ALLEGRO_USTR *al_fget_ustr(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L457)

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.

On success returns a pointer to a new ALLEGRO_USTR structure.  This must
be freed eventually with *note al_ustr_free: #al_ustr_free.  Returns
NULL if an error occurred or if the end of file was reached without
reading any bytes.

See *note al_fopen: #al_fopen. about translations of end-of-line
characters.

See also: *note al_fgetc: #al_fgetc, *note al_fgets: #al_fgets.


File: refman.info,  Node: al_fputs,  Next: Standard I/O specific routines,  Prev: al_fget_ustr,  Up: File I/O

5.33 al_fputs
=============

int al_fputs(ALLEGRO_FILE *f, char const *p)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L480)

Writes a string to file.  Apart from the return value, this is
equivalent to:

al_fwrite(f, p, strlen(p));

Parameters:

   • f - file handle to write to
   • p - string to write

Returns a non-negative integer on success, EOF on error.

Note: depending on the stream type and the mode passed to *note
al_fopen: #al_fopen, newline characters in the string may or may not be
automatically translated to native end-of-line sequences, e.g. CR/LF
instead of LF.

See also: *note al_fwrite: #al_fwrite.


File: refman.info,  Node: Standard I/O specific routines,  Next: Alternative file streams,  Prev: al_fputs,  Up: File I/O

5.34 Standard I/O specific routines
===================================

* Menu:

* al_fopen_fd::
* al_make_temp_file::


File: refman.info,  Node: al_fopen_fd,  Next: al_make_temp_file,  Up: Standard I/O specific routines

5.34.1 al_fopen_fd
------------------

ALLEGRO_FILE *al_fopen_fd(int fd, const char *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file_stdio.c#L71)

Create an *note ALLEGRO_FILE: #allegro_file. object that operates on an
open file descriptor using stdio routines.  See the documentation of
fdopen() for a description of the ‘mode’ argument.

Returns an ALLEGRO_FILE object on success or NULL on an error.  On an
error, the Allegro errno will be set and the file descriptor will not be
closed.

The file descriptor will be closed by *note al_fclose: #al_fclose. so
you should not call close() on it.

See also: *note al_fopen: #al_fopen.


File: refman.info,  Node: al_make_temp_file,  Prev: al_fopen_fd,  Up: Standard I/O specific routines

5.34.2 al_make_temp_file
------------------------

ALLEGRO_FILE *al_make_temp_file(const char *template, ALLEGRO_PATH **ret_path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file_stdio.c#L463)

Make a temporary randomly named file given a filename ‘template’.

‘template’ is a string giving the format of the generated filename and
should include one or more capital Xs.  The Xs are replaced with random
alphanumeric characters, produced using a simple pseudo-random number
generator only.  There should be no path separators.

If ‘ret_path’ is not NULL, the address it points to will be set to point
to a new path structure with the name of the temporary file.

Returns the opened *note ALLEGRO_FILE: #allegro_file. on success, NULL
on failure.


File: refman.info,  Node: Alternative file streams,  Prev: Standard I/O specific routines,  Up: File I/O

5.35 Alternative file streams
=============================

By default, the Allegro file I/O routines use the C library I/O
routines, hence work with files on the local filesystem, but can be
overridden so that you can read and write to other streams.  For
example, you can work with blocks of memory or sub-files inside .zip
files.

There are two ways to get an *note ALLEGRO_FILE: #allegro_file. that
doesn’t use stdio.  An addon library may provide a function that returns
a new ALLEGRO_FILE directly, after which, all al_f* calls on that object
will use overridden functions for that type of stream.  Alternatively,
*note al_set_new_file_interface: #al_set_new_file_interface. changes
which function will handle the following *note al_fopen: #al_fopen.
calls for the current thread.

* Menu:

* al_set_new_file_interface::
* al_set_standard_file_interface::
* al_get_new_file_interface::
* al_create_file_handle::
* al_get_file_userdata::


File: refman.info,  Node: al_set_new_file_interface,  Next: al_set_standard_file_interface,  Up: Alternative file streams

5.35.1 al_set_new_file_interface
--------------------------------

void al_set_new_file_interface(const ALLEGRO_FILE_INTERFACE *file_interface)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L869)

Set the *note ALLEGRO_FILE_INTERFACE: #allegro_file_interface. table for
the calling thread.  This will change the handler for later calls to
*note al_fopen: #al_fopen.

See also: *note al_set_standard_file_interface:
#al_set_standard_file_interface, *note al_store_state: #al_store_state,
*note al_restore_state: #al_restore_state.


File: refman.info,  Node: al_set_standard_file_interface,  Next: al_get_new_file_interface,  Prev: al_set_new_file_interface,  Up: Alternative file streams

5.35.2 al_set_standard_file_interface
-------------------------------------

void al_set_standard_file_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file_stdio.c#L385)

Set the *note ALLEGRO_FILE_INTERFACE: #allegro_file_interface. table to
the default, for the calling thread.  This will change the handler for
later calls to *note al_fopen: #al_fopen.

See also: *note al_set_new_file_interface: #al_set_new_file_interface.


File: refman.info,  Node: al_get_new_file_interface,  Next: al_create_file_handle,  Prev: al_set_standard_file_interface,  Up: Alternative file streams

5.35.3 al_get_new_file_interface
--------------------------------

const ALLEGRO_FILE_INTERFACE *al_get_new_file_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L848)

Return a pointer to the *note ALLEGRO_FILE_INTERFACE:
#allegro_file_interface. table in effect for the calling thread.

See also: *note al_store_state: #al_store_state, *note al_restore_state:
#al_restore_state.


File: refman.info,  Node: al_create_file_handle,  Next: al_get_file_userdata,  Prev: al_get_new_file_interface,  Up: Alternative file streams

5.35.4 al_create_file_handle
----------------------------

ALLEGRO_FILE *al_create_file_handle(const ALLEGRO_FILE_INTERFACE *drv,
   void *userdata)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L63)

Creates an empty, opened file handle with some abstract user data.  This
allows custom interfaces to extend the *note ALLEGRO_FILE:
#allegro_file. struct with their own data.  You should close the handle
with the standard *note al_fclose: #al_fclose. function when you are
finished with it.

See also: *note al_fopen: #al_fopen, *note al_fclose: #al_fclose, *note
al_set_new_file_interface: #al_set_new_file_interface.


File: refman.info,  Node: al_get_file_userdata,  Prev: al_create_file_handle,  Up: Alternative file streams

5.35.5 al_get_file_userdata
---------------------------

void *al_get_file_userdata(ALLEGRO_FILE *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/file.c#L533)

Returns a pointer to the custom userdata that is attached to the file
handle.  This is intended to be used by functions that extend *note
ALLEGRO_FILE_INTERFACE: #allegro_file_interface.


File: refman.info,  Node: Fixed point math routines,  Next: File system routines,  Prev: File I/O,  Up: Top

6 Fixed point math routines
***************************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* al_fixed::
* al_itofix::
* al_fixtoi::
* al_fixfloor::
* al_fixceil::
* al_ftofix::
* al_fixtof::
* al_fixmul::
* al_fixdiv::
* al_fixadd::
* al_fixsub::
* Fixed point trig::


File: refman.info,  Node: al_fixed,  Next: al_itofix,  Up: Fixed point math routines

6.1 al_fixed
============

typedef int32_t al_fixed;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/fixed.h#L30)

A fixed point number.

Allegro provides some routines for working with fixed point numbers, and
defines the type ‘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 ‘fixed_point_1 +
fixed_point_2’ is OK, but ‘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.  However, many
embedded processors have no FPUs so fixed point maths can still be
useful there.

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.


File: refman.info,  Node: al_itofix,  Next: al_fixtoi,  Prev: al_fixed,  Up: Fixed point math routines

6.2 al_itofix
=============

al_fixed al_itofix(int x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L332)

Converts an integer to fixed point.  This is the same thing as x<<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:

al_fixed number;

/* This conversion is OK. */
number = al_itofix(100);
assert(al_fixtoi(number) == 100);

number = al_itofix(64000);

/* This check will fail in debug builds. */
assert(al_fixtoi(number) == 64000);

Return value: Returns the value of the integer converted to fixed point
ignoring overflows.

See also: *note al_fixtoi: #al_fixtoi, *note al_ftofix: #al_ftofix,
*note al_fixtof: #al_fixtof.


File: refman.info,  Node: al_fixtoi,  Next: al_fixfloor,  Prev: al_itofix,  Up: Fixed point math routines

6.3 al_fixtoi
=============

int al_fixtoi(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L336)

Converts fixed point to integer, rounding as required to the nearest
integer.

Example:

int result;

/* This will put 33 into `result'. */
result = al_fixtoi(al_itofix(100) / 3);

/* But this will round up to 17. */
result = al_fixtoi(al_itofix(100) / 6);

See also: *note al_itofix: #al_itofix, *note al_ftofix: #al_ftofix,
*note al_fixtof: #al_fixtof, *note al_fixfloor: #al_fixfloor, *note
al_fixceil: #al_fixceil.


File: refman.info,  Node: al_fixfloor,  Next: al_fixceil,  Prev: al_fixtoi,  Up: Fixed point math routines

6.4 al_fixfloor
===============

int al_fixfloor(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L340)

Returns the greatest integer not greater than x.  That is, it rounds
towards negative infinity.

Example:

int result;

/* This will put 33 into `result'. */
result = al_fixfloor(al_itofix(100) / 3);

/* And this will round down to 16. */
result = al_fixfloor(al_itofix(100) / 6);

See also: *note al_fixtoi: #al_fixtoi, *note al_fixceil: #al_fixceil.


File: refman.info,  Node: al_fixceil,  Next: al_ftofix,  Prev: al_fixfloor,  Up: Fixed point math routines

6.5 al_fixceil
==============

int al_fixceil(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L344)

Returns the smallest integer not less than x.  That is, it rounds
towards positive infinity.

Example:

int result;

/* This will put 34 into `result'. */
result = al_fixceil(al_itofix(100) / 3);

/* This will round up to 17. */
result = al_fixceil(al_itofix(100) / 6);

See also: *note al_fixtoi: #al_fixtoi, *note al_fixfloor: #al_fixfloor.


File: refman.info,  Node: al_ftofix,  Next: al_fixtof,  Prev: al_fixceil,  Up: Fixed point math routines

6.6 al_ftofix
=============

al_fixed al_ftofix(double x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L348)

Converts a floating point value to fixed point.  Unlike *note al_itofix:
#al_itofix, this function clamps values which could overflow the type
conversion, setting Allegro’s errno to ERANGE in the process if this
happens.

Example:

al_fixed number;

number = al_itofix(-40000);
assert(al_fixfloor(number) == -32768);

number = al_itofix(64000);
assert(al_fixfloor(number) == 32767);
assert(!al_get_errno()); /* This will fail. */

Return value: Returns the value of the floating point value converted to
fixed point clamping overflows (and setting Allegro’s errno).

See also: *note al_fixtof: #al_fixtof, *note al_itofix: #al_itofix,
*note al_fixtoi: #al_fixtoi, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_fixtof,  Next: al_fixmul,  Prev: al_ftofix,  Up: Fixed point math routines

6.7 al_fixtof
=============

double al_fixtof(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L352)

Converts fixed point to floating point.

Example:

float result;

/* This will put 33.33333 into `result'. */
result = al_fixtof(al_itofix(100) / 3);

/* This will put 16.66666 into `result'. */
result = al_fixtof(al_itofix(100) / 6);

See also: *note al_ftofix: #al_ftofix, *note al_itofix: #al_itofix,
*note al_fixtoi: #al_fixtoi.


File: refman.info,  Node: al_fixmul,  Next: al_fixdiv,  Prev: al_fixtof,  Up: Fixed point math routines

6.8 al_fixmul
=============

al_fixed al_fixmul(al_fixed x, al_fixed y);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L364)

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.

If an overflow 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
overflow you should call ‘al_set_errno(0)’ before calling *note
al_fixmul: #al_fixmul.

Example:

al_fixed result;

/* This will put 30000 into `result'. */
result = al_fixmul(al_itofix(10), al_itofix(3000));

/* But this overflows, and sets errno. */
result = al_fixmul(al_itofix(100), al_itofix(3000));
assert(!al_get_errno());

Return value: Returns the clamped result of multiplying ‘x’ by ‘y’,
setting Allegro’s errno to ERANGE if there was an overflow.

See also: *note al_fixadd: #al_fixadd, *note al_fixsub: #al_fixsub,
*note al_fixdiv: #al_fixdiv, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_fixdiv,  Next: al_fixadd,  Prev: al_fixmul,  Up: Fixed point math routines

6.9 al_fixdiv
=============

al_fixed al_fixdiv(al_fixed x, al_fixed y);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L368)

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 ‘al_set_errno(0)’ before calling
*note al_fixdiv: #al_fixdiv.

Example:

al_fixed result;

/* This will put 0.06060 `result'. */
result = al_fixdiv(al_itofix(2), al_itofix(33));

/* This will put 0 into `result'. */
result = al_fixdiv(0, al_itofix(-30));

/* Sets errno and puts -32768 into `result'. */
result = al_fixdiv(al_itofix(-100), al_itofix(0));
assert(!al_get_errno()); /* This will fail. */

Return value: Returns the result of dividing ‘x’ by ‘y’.  If ‘y’ is
zero, returns the maximum possible fixed point value and sets Allegro’s
errno to ERANGE.

See also: *note al_fixadd: #al_fixadd, *note al_fixsub: #al_fixsub,
*note al_fixmul: #al_fixmul, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_fixadd,  Next: al_fixsub,  Prev: al_fixdiv,  Up: Fixed point math routines

6.10 al_fixadd
==============

al_fixed al_fixadd(al_fixed x, al_fixed y);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L356)

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 Allegro’s errno and clamp the result, rather than just letting it
wrap.

Example:

al_fixed result;

/* This will put 5035 into `result'. */
result = al_fixadd(al_itofix(5000), al_itofix(35));

/* Sets errno and puts -32768 into `result'. */
result = al_fixadd(al_itofix(-31000), al_itofix(-3000));
assert(!al_get_errno()); /* This will fail. */

Return value: Returns the clamped result of adding ‘x’ to ‘y’, setting
Allegro’s errno to ERANGE if there was an overflow.

See also: *note al_fixsub: #al_fixsub, *note al_fixmul: #al_fixmul,
*note al_fixdiv: #al_fixdiv.


File: refman.info,  Node: al_fixsub,  Next: Fixed point trig,  Prev: al_fixadd,  Up: Fixed point math routines

6.11 al_fixsub
==============

al_fixed al_fixsub(al_fixed x, al_fixed y);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L360)

Although fixed point numbers can be subtracted 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 Allegro’s errno and clamp the result, rather than just letting it
wrap.

Example:

al_fixed result;

/* This will put 4965 into `result'. */
result = al_fixsub(al_itofix(5000), al_itofix(35));

/* Sets errno and puts -32768 into `result'. */
result = al_fixsub(al_itofix(-31000), al_itofix(3000));
assert(!al_get_errno()); /* This will fail. */

Return value: Returns the clamped result of subtracting ‘y’ from ‘x’,
setting Allegro’s errno to ERANGE if there was an overflow.

See also: *note al_fixadd: #al_fixadd, *note al_fixmul: #al_fixmul,
*note al_fixdiv: #al_fixdiv, *note al_get_errno: #al_get_errno.


File: refman.info,  Node: Fixed point trig,  Prev: al_fixsub,  Up: Fixed point math routines

6.12 Fixed point trig
=====================

The fixed point square root, sin, cos, tan, inverse sin, and inverse cos
functions are implemented using lookup tables, which are very fast but
not particularly accurate.  At the moment the inverse tan uses an
iterative search on the tan table, so it is a lot slower than the
others.  On machines with good floating point processors using these
functions could be slower Always profile your code.

Angles are represented in a binary format with 256 equal to a full
circle, 64 being a right angle and so on.  This has the advantage that a
simple bitwise ‘and’ can be used to keep the angle within the range zero
to a full circle.

* Menu:

* al_fixtorad_r::
* al_radtofix_r::
* al_fixsin::
* al_fixcos::
* al_fixtan::
* al_fixasin::
* al_fixacos::
* al_fixatan::
* al_fixatan2::
* al_fixsqrt::
* al_fixhypot::


File: refman.info,  Node: al_fixtorad_r,  Next: al_radtofix_r,  Up: Fixed point trig

6.12.1 al_fixtorad_r
--------------------

const al_fixed al_fixtorad_r = (al_fixed)1608;

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L290)

This constant gives a ratio which can be used to convert a fixed point
number in binary angle format to a fixed point number in radians.

Example:

al_fixed rad_angle, binary_angle;

/* Set the binary angle to 90 degrees. */
binary_angle = 64;

/* Now convert to radians (about 1.57). */
rad_angle = al_fixmul(binary_angle, al_fixtorad_r);

See also: *note al_fixmul: #al_fixmul, *note al_radtofix_r:
#al_radtofix_r.


File: refman.info,  Node: al_radtofix_r,  Next: al_fixsin,  Prev: al_fixtorad_r,  Up: Fixed point trig

6.12.2 al_radtofix_r
--------------------

const al_fixed al_radtofix_r = (al_fixed)2670177;

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L298)

This constant gives a ratio which can be used to convert a fixed point
number in radians to a fixed point number in binary angle format.

Example:

    al_fixed rad_angle, binary_angle;
    ...
    binary_angle = al_fixmul(rad_angle, radtofix_r);

See also: *note al_fixmul: #al_fixmul, *note al_fixtorad_r:
#al_fixtorad_r.


File: refman.info,  Node: al_fixsin,  Next: al_fixcos,  Prev: al_radtofix_r,  Up: Fixed point trig

6.12.3 al_fixsin
----------------

al_fixed al_fixsin(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L376)

This function finds the sine of a value using a lookup table.  The input
value must be a fixed point binary angle.

Example:

al_fixed angle;
int result;

/* Set the binary angle to 90 degrees. */
angle = al_itofix(64);

/* The sine of 90 degrees is one. */
result = al_fixtoi(al_fixsin(angle));
assert(result == 1);

Return value: Returns the sine of a fixed point binary format angle as a
fixed point value.


File: refman.info,  Node: al_fixcos,  Next: al_fixtan,  Prev: al_fixsin,  Up: Fixed point trig

6.12.4 al_fixcos
----------------

al_fixed al_fixcos(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L372)

This function finds the cosine of a value using a lookup table.  The
input value must be a fixed point binary angle.

Example:

al_fixed angle;
float result;

/* Set the binary angle to 45 degrees. */
angle = al_itofix(32);

/* The cosine of 45 degrees is about 0.7071. */
result = al_fixtof(al_fixcos(angle));
assert(result > 0.7 && result < 0.71);

Return value: Returns the cosine of a fixed point binary format angle as
a fixed point value.


File: refman.info,  Node: al_fixtan,  Next: al_fixasin,  Prev: al_fixcos,  Up: Fixed point trig

6.12.5 al_fixtan
----------------

al_fixed al_fixtan(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L380)

This function finds the tangent of a value using a lookup table.  The
input value must be a fixed point binary angle.

Example:

al_fixed angle, res_a, res_b;
float dif;

angle = al_itofix(37);
/* Prove that tan(angle) == sin(angle) / cos(angle). */
res_a = al_fixdiv(al_fixsin(angle), al_fixcos(angle));
res_b = al_fixtan(angle);
dif = al_fixtof(al_fixsub(res_a, res_b));
printf("Precision error: %f\n", dif);

Return value: Returns the tangent of a fixed point binary format angle
as a fixed point value.


File: refman.info,  Node: al_fixasin,  Next: al_fixacos,  Prev: al_fixtan,  Up: Fixed point trig

6.12.6 al_fixasin
-----------------

al_fixed al_fixasin(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L388)

This function finds the inverse sine of a value using a lookup table.
The input value must be a fixed point value.  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 EDOM and return zero.

Example:

float angle;
al_fixed val;

/* Sets `val' to a right binary angle (64). */
val = 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 assert. */
val = al_fixasin(al_ftofix(-1.09));
assert(!al_get_errno());

Return value: Returns the inverse sine of a fixed point value, measured
as fixed point binary format angle, or zero if the input was out of the
range.  All return values of this function will be in the range -64 to
64.


File: refman.info,  Node: al_fixacos,  Next: al_fixatan,  Prev: al_fixasin,  Up: Fixed point trig

6.12.7 al_fixacos
-----------------

al_fixed al_fixacos(al_fixed x);

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L384)

This function finds the inverse cosine of a value using a lookup table.
The input must be a fixed point value.  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 EDOM and return zero.

Example:

al_fixed result;

/* Sets result to binary angle 128. */
result = al_fixacos(al_itofix(-1));

Return value: Returns 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.


File: refman.info,  Node: al_fixatan,  Next: al_fixatan2,  Prev: al_fixacos,  Up: Fixed point trig

6.12.8 al_fixatan
-----------------

al_fixed al_fixatan(al_fixed x)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L215)

This function finds the inverse tangent of a value using a lookup table.
The input must be a fixed point value.  The inverse tangent is the value
whose tangent is ‘x’.

Example:

al_fixed result;

/* Sets result to binary angle 13. */
result = al_fixatan(al_ftofix(0.326));

Return value: Returns the inverse tangent of a fixed point value,
measured as a fixed point binary format angle.


File: refman.info,  Node: al_fixatan2,  Next: al_fixsqrt,  Prev: al_fixatan,  Up: Fixed point trig

6.12.9 al_fixatan2
------------------

al_fixed al_fixatan2(al_fixed y, al_fixed x)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L252)

This is a fixed point version of the libc atan2() routine.  It computes
the arc tangent of ‘y / x’, but the signs of both arguments are used to
determine the quadrant of the result, and ‘x’ is permitted to be zero.
This function is useful to convert Cartesian coordinates to polar
coordinates.

Example:

al_fixed result;

/* Sets `result' to binary angle 64. */
result = al_fixatan2(al_itofix(1), 0);

/* Sets `result' to binary angle -109. */
result = al_fixatan2(al_itofix(-1), al_itofix(-2));

/* Fails the assert. */
result = al_fixatan2(0, 0);
assert(!al_get_errno());

Return value: Returns 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 EDOM.


File: refman.info,  Node: al_fixsqrt,  Next: al_fixhypot,  Prev: al_fixatan2,  Up: Fixed point trig

6.12.10 al_fixsqrt
------------------

al_fixed al_fixsqrt(al_fixed x)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L305)

This finds out the non negative square root of ‘x’.  If ‘x’ is negative,
Allegro’s errno is set to EDOM and the function returns zero.


File: refman.info,  Node: al_fixhypot,  Prev: al_fixsqrt,  Up: Fixed point trig

6.12.11 al_fixhypot
-------------------

al_fixed al_fixhypot(al_fixed x, al_fixed y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/math.c#L321)

Fixed point hypotenuse (returns the square root of ‘x*x + y*y’).  This
should be better than calculating the formula yourself manually, since
the error is much smaller.


File: refman.info,  Node: File system routines,  Next: Fullscreen modes,  Prev: Fixed point math routines,  Up: Top

7 File system routines
**********************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

These functions allow access to the filesystem.  This can either be the
real filesystem like your harddrive, or a virtual filesystem like a .zip
archive (or whatever else you or an addon makes it do).

* Menu:

* ALLEGRO_FS_ENTRY::
* ALLEGRO_FILE_MODE::
* al_create_fs_entry::
* al_destroy_fs_entry::
* al_get_fs_entry_name::
* al_update_fs_entry::
* al_get_fs_entry_mode::
* al_get_fs_entry_atime::
* al_get_fs_entry_ctime::
* al_get_fs_entry_mtime::
* al_get_fs_entry_size::
* al_fs_entry_exists::
* al_remove_fs_entry::
* al_filename_exists::
* al_remove_filename::
* Directory functions::
* Alternative filesystem functions::


File: refman.info,  Node: ALLEGRO_FS_ENTRY,  Next: ALLEGRO_FILE_MODE,  Up: File system routines

7.1 ALLEGRO_FS_ENTRY
====================

typedef struct ALLEGRO_FS_ENTRY ALLEGRO_FS_ENTRY;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/fshook.h#L37)

Opaque filesystem entry object.  Represents a file or a directory (check
with *note al_get_fs_entry_mode: #al_get_fs_entry_mode.).  There are no
user accessible member variables.


File: refman.info,  Node: ALLEGRO_FILE_MODE,  Next: al_create_fs_entry,  Prev: ALLEGRO_FS_ENTRY,  Up: File system routines

7.2 ALLEGRO_FILE_MODE
=====================

typedef enum ALLEGRO_FILE_MODE

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/fshook.h#L46)

Filesystem modes/types

   • ALLEGRO_FILEMODE_READ - Readable
   • ALLEGRO_FILEMODE_WRITE - Writable
   • ALLEGRO_FILEMODE_EXECUTE - Executable
   • ALLEGRO_FILEMODE_HIDDEN - Hidden
   • ALLEGRO_FILEMODE_ISFILE - Regular file
   • ALLEGRO_FILEMODE_ISDIR - Directory


File: refman.info,  Node: al_create_fs_entry,  Next: al_destroy_fs_entry,  Prev: ALLEGRO_FILE_MODE,  Up: File system routines

7.3 al_create_fs_entry
======================

ALLEGRO_FS_ENTRY *al_create_fs_entry(const char *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L28)

Creates an *note ALLEGRO_FS_ENTRY: #allegro_fs_entry. object pointing to
path on the filesystem.  ‘path’ can be a file or a directory and must
not be NULL.


File: refman.info,  Node: al_destroy_fs_entry,  Next: al_get_fs_entry_name,  Prev: al_create_fs_entry,  Up: File system routines

7.4 al_destroy_fs_entry
=======================

void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L38)

Destroys a fs entry handle.  The file or directory represented by it is
not destroyed.  If the entry was opened, it is closed before being
destroyed.

Does nothing if passed NULL.


File: refman.info,  Node: al_get_fs_entry_name,  Next: al_update_fs_entry,  Prev: al_destroy_fs_entry,  Up: File system routines

7.5 al_get_fs_entry_name
========================

const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L48)

Returns the entry’s filename path.  Note that the filesystem encoding
may not be known and the conversion to UTF-8 could in very rare cases
cause this to return an invalid path.  Therefore it’s always safest to
access the file over its *note ALLEGRO_FS_ENTRY: #allegro_fs_entry. and
not the path.

On success returns a read only string which you must not modify or
destroy.  Returns NULL on failure.

     Note: prior to 5.1.5 it was written: “... the path will not be an
     absolute path if the entry wasn’t created from an absolute path”.
     This is no longer true.


File: refman.info,  Node: al_update_fs_entry,  Next: al_get_fs_entry_mode,  Prev: al_get_fs_entry_name,  Up: File system routines

7.6 al_update_fs_entry
======================

bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L58)

Updates file status information for a filesystem entry.  File status
information is automatically updated when the entry is created, however
you may update it again with this function, e.g. in case it changed.

Returns true on success, false on failure.  Fills in errno to indicate
the error.

See also: *note al_get_errno: #al_get_errno, *note
al_get_fs_entry_atime: #al_get_fs_entry_atime, *note
al_get_fs_entry_ctime: #al_get_fs_entry_ctime, *note
al_get_fs_entry_mode: #al_get_fs_entry_mode.


File: refman.info,  Node: al_get_fs_entry_mode,  Next: al_get_fs_entry_atime,  Prev: al_update_fs_entry,  Up: File system routines

7.7 al_get_fs_entry_mode
========================

uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L68)

Returns the entry’s mode flags, i.e. permissions and whether the entry
refers to a file or directory.

See also: *note al_get_errno: #al_get_errno, *note ALLEGRO_FILE_MODE:
#allegro_file_mode.


File: refman.info,  Node: al_get_fs_entry_atime,  Next: al_get_fs_entry_ctime,  Prev: al_get_fs_entry_mode,  Up: File system routines

7.8 al_get_fs_entry_atime
=========================

time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L78)

Returns the time in seconds since the epoch since the entry was last
accessed.

Warning: some filesystems either don’t support this flag, or people turn
it off to increase performance.  It may not be valid in all
circumstances.

See also: *note al_get_fs_entry_ctime: #al_get_fs_entry_ctime, *note
al_get_fs_entry_mtime: #al_get_fs_entry_mtime, *note al_update_fs_entry:
#al_update_fs_entry.


File: refman.info,  Node: al_get_fs_entry_ctime,  Next: al_get_fs_entry_mtime,  Prev: al_get_fs_entry_atime,  Up: File system routines

7.9 al_get_fs_entry_ctime
=========================

time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L98)

Returns the time in seconds since the epoch this entry was created on
the filesystem.

See also: *note al_get_fs_entry_atime: #al_get_fs_entry_atime, *note
al_get_fs_entry_mtime: #al_get_fs_entry_mtime, *note al_update_fs_entry:
#al_update_fs_entry.


File: refman.info,  Node: al_get_fs_entry_mtime,  Next: al_get_fs_entry_size,  Prev: al_get_fs_entry_ctime,  Up: File system routines

7.10 al_get_fs_entry_mtime
==========================

time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L88)

Returns the time in seconds since the epoch since the entry was last
modified.

See also: *note al_get_fs_entry_atime: #al_get_fs_entry_atime, *note
al_get_fs_entry_ctime: #al_get_fs_entry_ctime, *note al_update_fs_entry:
#al_update_fs_entry.


File: refman.info,  Node: al_get_fs_entry_size,  Next: al_fs_entry_exists,  Prev: al_get_fs_entry_mtime,  Up: File system routines

7.11 al_get_fs_entry_size
=========================

off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L108)

Returns the size, in bytes, of the given entry.  May not return anything
sensible for a directory entry.

See also: *note al_update_fs_entry: #al_update_fs_entry.


File: refman.info,  Node: al_fs_entry_exists,  Next: al_remove_fs_entry,  Prev: al_get_fs_entry_size,  Up: File system routines

7.12 al_fs_entry_exists
=======================

bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L128)

Check if the given entry exists on in the filesystem.  Returns true if
it does exist or false if it doesn’t exist, or an error occurred.  Error
is indicated in Allegro’s errno.

See also: *note al_filename_exists: #al_filename_exists.


File: refman.info,  Node: al_remove_fs_entry,  Next: al_filename_exists,  Prev: al_fs_entry_exists,  Up: File system routines

7.13 al_remove_fs_entry
=======================

bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L118)

Delete this filesystem entry from the filesystem.  Only files and empty
directories may be deleted.

Returns true on success, and false on failure, error is indicated in
Allegro’s errno.

See also: *note al_filename_exists: #al_filename_exists.


File: refman.info,  Node: al_filename_exists,  Next: al_remove_filename,  Prev: al_remove_fs_entry,  Up: File system routines

7.14 al_filename_exists
=======================

bool al_filename_exists(const char *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L202)

Check if the path exists on the filesystem, without creating an *note
ALLEGRO_FS_ENTRY: #allegro_fs_entry. object explicitly.

See also: *note al_fs_entry_exists: #al_fs_entry_exists.


File: refman.info,  Node: al_remove_filename,  Next: Directory functions,  Prev: al_filename_exists,  Up: File system routines

7.15 al_remove_filename
=======================

bool al_remove_filename(const char *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L214)

Delete the given path from the filesystem, which may be a file or an
empty directory.  This is the same as *note al_remove_fs_entry:
#al_remove_fs_entry, except it expects the path as a string.

Returns true on success, and false on failure.  Allegro’s errno is
filled in to indicate the error.

See also: *note al_remove_fs_entry: #al_remove_fs_entry.


File: refman.info,  Node: Directory functions,  Next: Alternative filesystem functions,  Prev: al_remove_filename,  Up: File system routines

7.16 Directory functions
========================

* Menu:

* al_open_directory::
* al_read_directory::
* al_close_directory::
* al_get_current_directory::
* al_change_directory::
* al_make_directory::
* al_open_fs_entry::
* ALLEGRO_FOR_EACH_FS_ENTRY_RESULT::
* al_for_each_fs_entry::


File: refman.info,  Node: al_open_directory,  Next: al_read_directory,  Up: Directory functions

7.16.1 al_open_directory
------------------------

bool al_open_directory(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L138)

Opens a directory entry object.  You must call this before using *note
al_read_directory: #al_read_directory. on an entry and you must call
*note al_close_directory: #al_close_directory. when you no longer need
it.

Returns true on success.

See also: *note al_read_directory: #al_read_directory, *note
al_close_directory: #al_close_directory.


File: refman.info,  Node: al_read_directory,  Next: al_close_directory,  Prev: al_open_directory,  Up: Directory functions

7.16.2 al_read_directory
------------------------

ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L158)

Reads the next directory item and returns a filesystem entry for it.

Returns NULL if there are no more entries or if an error occurs.  Call
*note al_destroy_fs_entry: #al_destroy_fs_entry. on the returned entry
when you are done with it.

This function will ignore any files or directories named ‘.’ or ‘..’
which may exist on certain platforms and may signify the current and the
parent directory.

See also: *note al_open_directory: #al_open_directory, *note
al_close_directory: #al_close_directory.


File: refman.info,  Node: al_close_directory,  Next: al_get_current_directory,  Prev: al_read_directory,  Up: Directory functions

7.16.3 al_close_directory
-------------------------

bool al_close_directory(ALLEGRO_FS_ENTRY *e)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L148)

Closes a previously opened directory entry object.

Returns true on success, false on failure and fills in Allegro’s errno
to indicate the error.

See also: *note al_open_directory: #al_open_directory, *note
al_read_directory: #al_read_directory.


File: refman.info,  Node: al_get_current_directory,  Next: al_change_directory,  Prev: al_close_directory,  Up: Directory functions

7.16.4 al_get_current_directory
-------------------------------

char *al_get_current_directory(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L168)

Returns the path to the current working directory, or NULL on failure.
The returned path is dynamically allocated and must be destroyed with
*note al_free: #al_free.

Allegro’s errno is filled in to indicate the error if there is a
failure.  This function may not be implemented on some (virtual)
filesystems.

See also: *note al_get_errno: #al_get_errno, *note al_free: #al_free.


File: refman.info,  Node: al_change_directory,  Next: al_make_directory,  Prev: al_get_current_directory,  Up: Directory functions

7.16.5 al_change_directory
--------------------------

bool al_change_directory(const char *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L178)

Changes the current working directory to ‘path’.

Returns true on success, false on error.


File: refman.info,  Node: al_make_directory,  Next: al_open_fs_entry,  Prev: al_change_directory,  Up: Directory functions

7.16.6 al_make_directory
------------------------

bool al_make_directory(const char *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L190)

Creates a new directory on the filesystem.  This function also creates
any parent directories as needed.

Returns true on success (including if the directory already exists),
otherwise returns false on error.  Fills in Allegro’s errno to indicate
the error.

See also: *note al_get_errno: #al_get_errno.


File: refman.info,  Node: al_open_fs_entry,  Next: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT,  Prev: al_make_directory,  Up: Directory functions

7.16.7 al_open_fs_entry
-----------------------

ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L226)

Open an *note ALLEGRO_FILE: #allegro_file. handle to a filesystem entry,
for the given access mode.  This is like calling *note al_fopen:
#al_fopen. with the name of the filesystem entry, but uses the
appropriate file interface, not whatever was set with the latest call to
*note al_set_new_file_interface: #al_set_new_file_interface.

Returns the handle on success, NULL on error.

See also: *note al_fopen: #al_fopen.


File: refman.info,  Node: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT,  Next: al_for_each_fs_entry,  Prev: al_open_fs_entry,  Up: Directory functions

7.16.8 ALLEGRO_FOR_EACH_FS_ENTRY_RESULT
---------------------------------------

typedef enum ALLEGRO_FOR_EACH_FS_ENTRY_RESULT {

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/fshook.h#L124)

Return values for the callbacks of *note al_for_each_fs_entry:
#al_for_each_fs_entry. and for that function itself.

   • ALLEGRO_FOR_EACH_FS_ENTRY_ERROR - An error ocurred.
   • ALLEGRO_FOR_EACH_FS_ENTRY_OK - Continue normally and recurse into
     directories.
   • ALLEGRO_FOR_EACH_FS_ENTRY_SKIP - Continue but do NOT recusively
     descend.
   • ALLEGRO_FOR_EACH_FS_ENTRY_STOP - Stop iterating and return.

See also: *note al_for_each_fs_entry: #al_for_each_fs_entry.

Since: 5.1.9


File: refman.info,  Node: al_for_each_fs_entry,  Prev: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT,  Up: Directory functions

7.16.9 al_for_each_fs_entry
---------------------------

int al_for_each_fs_entry(ALLEGRO_FS_ENTRY *dir,
                         int (*callback)(ALLEGRO_FS_ENTRY *dir, void *extra),
                         void *extra)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fshook.c#L242)

This function takes the *note ALLEGRO_FS_ENTRY: #allegro_fs_entry.
‘dir’, which should represent a directory, and looks for any other file
system entries that are in it.  This function will then call the
callback function ‘callback’ once for every filesystem entry in the
directory ‘dir’.

The callback ‘callback’ must be of type ‘int callback(ALLEGRO_FS_ENTRY *
entry, void * extra)’.  The ‘callback’ will be called with a pointer to
an *note ALLEGRO_FS_ENTRY: #allegro_fs_entry. that matches one file or
directory in ‘dir’, and the pointer passed in the ‘extra’ parameter to
*note al_for_each_fs_entry: #al_for_each_fs_entry.

When ‘callback’ returns ‘ALLEGRO_FOR_EACH_FS_ENTRY_STOP’ or
‘ALLEGRO_FOR_EACH_FS_ENTRY_ERROR’, iteration will stop immediately and
*note al_for_each_fs_entry: #al_for_each_fs_entry. will return the value
the ‘callback’ returned.

When ‘callback’ returns ‘ALLEGRO_FOR_EACH_FS_ENTRY_OK’ iteration will
continue normally, and if the *note ALLEGRO_FS_ENTRY: #allegro_fs_entry.
parameter of ‘callback’ is a directory, *note al_for_each_fs_entry:
#al_for_each_fs_entry. will call itself on that directory.  Therefore
the function will recusively descend into that directory.

However, when ‘callback’ returns ‘ALLEGRO_FOR_EACH_FS_ENTRY_SKIP’
iteration will continue, but *note al_for_each_fs_entry:
#al_for_each_fs_entry. will NOT recurse into the *note ALLEGRO_FS_ENTRY:
#allegro_fs_entry. parameter of ‘callback’ even if it is a directory.

This function will skip any files or directories named ‘.’ or ‘..’ which
may exist on certain platforms and may signify the current and the
parent directory.  The ‘callback’ will not be called for files or
directories with such a name.

Returns ALLEGRO_FOR_EACH_FS_ENTRY_OK if successful, or
ALLEGRO_FOR_EACH_FS_ENTRY_ERROR if something went wrong in processing
the directory.  In that case it will use *note al_set_errno:
#al_set_errno. to indicate the type of error which occurred.  This
function returns ALLEGRO_FOR_EACH_FS_ENTRY_STOP in case iteration was
stopped by making ‘callback’ return that value.  In this case, *note
al_set_errno: #al_set_errno. will not be used.

See also: *note ALLEGRO_FOR_EACH_FS_ENTRY_RESULT:
#allegro_for_each_fs_entry_result.

Since: 5.1.9


File: refman.info,  Node: Alternative filesystem functions,  Prev: Directory functions,  Up: File system routines

7.17 Alternative filesystem functions
=====================================

By default, Allegro uses platform specific filesystem functions for
things like directory access.  However if for example the files of your
game are not in the local filesystem but inside some file archive, you
can provide your own set of functions (or use an addon which does this
for you, for example our physfs addon allows access to the most common
archive formats).

* Menu:

* ALLEGRO_FS_INTERFACE::
* al_set_fs_interface::
* al_set_standard_fs_interface::
* al_get_fs_interface::


File: refman.info,  Node: ALLEGRO_FS_INTERFACE,  Next: al_set_fs_interface,  Up: Alternative filesystem functions

7.17.1 ALLEGRO_FS_INTERFACE
---------------------------

typedef struct ALLEGRO_FS_INTERFACE ALLEGRO_FS_INTERFACE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/fshook.h#L64)

The available functions you can provide for a filesystem.  They are:

   ALLEGRO_FS_ENTRY *  fs_create_entry   (const char *path);
   void                fs_destroy_entry  (ALLEGRO_FS_ENTRY *e);
   const char *        fs_entry_name     (ALLEGRO_FS_ENTRY *e);
   bool                fs_update_entry   (ALLEGRO_FS_ENTRY *e);
   uint32_t            fs_entry_mode     (ALLEGRO_FS_ENTRY *e);
   time_t              fs_entry_atime    (ALLEGRO_FS_ENTRY *e);
   time_t              fs_entry_mtime    (ALLEGRO_FS_ENTRY *e);
   time_t              fs_entry_ctime    (ALLEGRO_FS_ENTRY *e);
   off_t               fs_entry_size     (ALLEGRO_FS_ENTRY *e);
   bool                fs_entry_exists   (ALLEGRO_FS_ENTRY *e);
   bool                fs_remove_entry   (ALLEGRO_FS_ENTRY *e);

   bool                fs_open_directory (ALLEGRO_FS_ENTRY *e);
   ALLEGRO_FS_ENTRY *  fs_read_directory (ALLEGRO_FS_ENTRY *e);
   bool                fs_close_directory(ALLEGRO_FS_ENTRY *e);

   bool                fs_filename_exists(const char *path);
   bool                fs_remove_filename(const char *path);
   char *              fs_get_current_directory(void);
   bool                fs_change_directory(const char *path);
   bool                fs_make_directory(const char *path);

   ALLEGRO_FILE *      fs_open_file(ALLEGRO_FS_ENTRY *e);


File: refman.info,  Node: al_set_fs_interface,  Next: al_set_standard_fs_interface,  Prev: ALLEGRO_FS_INTERFACE,  Up: Alternative filesystem functions

7.17.2 al_set_fs_interface
--------------------------

void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L899)

Set the *note ALLEGRO_FS_INTERFACE: #allegro_fs_interface. table for the
calling thread.

See also: *note al_set_standard_fs_interface:
#al_set_standard_fs_interface, *note al_store_state: #al_store_state,
*note al_restore_state: #al_restore_state.


File: refman.info,  Node: al_set_standard_fs_interface,  Next: al_get_fs_interface,  Prev: al_set_fs_interface,  Up: Alternative filesystem functions

7.17.3 al_set_standard_fs_interface
-----------------------------------

void al_set_standard_fs_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L912)

Return the *note ALLEGRO_FS_INTERFACE: #allegro_fs_interface. table to
the default, for the calling thread.

See also: *note al_set_fs_interface: #al_set_fs_interface.


File: refman.info,  Node: al_get_fs_interface,  Prev: al_set_standard_fs_interface,  Up: Alternative filesystem functions

7.17.4 al_get_fs_interface
--------------------------

const ALLEGRO_FS_INTERFACE *al_get_fs_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L882)

Return a pointer to the *note ALLEGRO_FS_INTERFACE:
#allegro_fs_interface. table in effect for the calling thread.

See also: *note al_store_state: #al_store_state, *note al_restore_state:
#al_restore_state.


File: refman.info,  Node: Fullscreen modes,  Next: Graphics routines,  Prev: File system routines,  Up: Top

8 Fullscreen modes
******************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_DISPLAY_MODE::
* al_get_display_mode::
* al_get_num_display_modes::


File: refman.info,  Node: ALLEGRO_DISPLAY_MODE,  Next: al_get_display_mode,  Up: Fullscreen modes

8.1 ALLEGRO_DISPLAY_MODE
========================

typedef struct ALLEGRO_DISPLAY_MODE

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/fullscreen_mode.h#L13)

Used for fullscreen mode queries.  Contains information about a
supported fullscreen modes.

typedef struct ALLEGRO_DISPLAY_MODE {
   int width;          // Screen width
   int height;         // Screen height
   int format;         // The pixel format of the mode
   int refresh_rate;   // The refresh rate of the mode
} ALLEGRO_DISPLAY_MODE;

The ‘refresh_rate’ may be zero if unknown.

For an explanation of what ‘format’ means, see *note
ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format.

See also: *note al_get_display_mode: #al_get_display_mode.


File: refman.info,  Node: al_get_display_mode,  Next: al_get_num_display_modes,  Prev: ALLEGRO_DISPLAY_MODE,  Up: Fullscreen modes

8.2 al_get_display_mode
=======================

ALLEGRO_DISPLAY_MODE *al_get_display_mode(int index, ALLEGRO_DISPLAY_MODE *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fullscreen_mode.c#L32)

Retrieves a fullscreen mode.  Display parameters should not be changed
between a call of *note al_get_num_display_modes:
#al_get_num_display_modes. and *note al_get_display_mode:
#al_get_display_mode.  index must be between 0 and the number returned
from al_get_num_display_modes-1.  mode must be an allocated
ALLEGRO_DISPLAY_MODE structure.  This function will return NULL on
failure, and the mode parameter that was passed in on success.

See also: *note ALLEGRO_DISPLAY_MODE: #allegro_display_mode, *note
al_get_num_display_modes: #al_get_num_display_modes.


File: refman.info,  Node: al_get_num_display_modes,  Prev: al_get_display_mode,  Up: Fullscreen modes

8.3 al_get_num_display_modes
============================

int al_get_num_display_modes(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/fullscreen_mode.c#L23)

Get the number of available fullscreen display modes for the current set
of display parameters.  This will use the values set with *note
al_set_new_display_refresh_rate: #al_set_new_display_refresh_rate, and
*note al_set_new_display_flags: #al_set_new_display_flags. to find the
number of modes that match.  Settings the new display parameters to zero
will give a list of all modes for the default driver.

See also: *note al_get_display_mode: #al_get_display_mode.


File: refman.info,  Node: Graphics routines,  Next: Haptic routines,  Prev: Fullscreen modes,  Up: Top

9 Graphics routines
*******************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* Colors::
* Locking and pixel formats::
* Bitmap creation::
* Bitmap properties::
* Drawing operations::
* Target bitmap::
* Blending modes::
* Clipping::
* Graphics utility functions::
* Deferred drawing::
* Image I/O::
* Render State::


File: refman.info,  Node: Colors,  Next: Locking and pixel formats,  Up: Graphics routines

9.1 Colors
==========

* Menu:

* ALLEGRO_COLOR::
* al_map_rgb::
* al_map_rgb_f::
* al_map_rgba::
* al_premul_rgba::
* al_map_rgba_f::
* al_premul_rgba_f::
* al_unmap_rgb::
* al_unmap_rgb_f::
* al_unmap_rgba::
* al_unmap_rgba_f::


File: refman.info,  Node: ALLEGRO_COLOR,  Next: al_map_rgb,  Up: Colors

9.1.1 ALLEGRO_COLOR
-------------------

typedef struct ALLEGRO_COLOR ALLEGRO_COLOR;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/color.h#L13)

An ALLEGRO_COLOR structure describes a color in a device independent
way.  Use *note al_map_rgb: #al_map_rgb. et al. and *note al_unmap_rgb:
#al_unmap_rgb. et al. to translate from and to various color
representations.


File: refman.info,  Node: al_map_rgb,  Next: al_map_rgb_f,  Prev: ALLEGRO_COLOR,  Up: Colors

9.1.2 al_map_rgb
----------------

ALLEGRO_COLOR al_map_rgb(
   unsigned char r, unsigned char g, unsigned char b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L575)

Convert r, g, b (ranging from 0-255) into an *note ALLEGRO_COLOR:
#allegro_color, using 255 for alpha.

This function can be called before Allegro is initialized.

See also: *note al_map_rgba: #al_map_rgba, *note al_map_rgba_f:
#al_map_rgba_f, *note al_map_rgb_f: #al_map_rgb_f.


File: refman.info,  Node: al_map_rgb_f,  Next: al_map_rgba,  Prev: al_map_rgb,  Up: Colors

9.1.3 al_map_rgb_f
------------------

ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L610)

Convert r, g, b, (ranging from 0.0f-1.0f) into an *note ALLEGRO_COLOR:
#allegro_color, using 1.0f for alpha.

This function can be called before Allegro is initialized.

See also: *note al_map_rgba: #al_map_rgba, *note al_map_rgb:
#al_map_rgb, *note al_map_rgba_f: #al_map_rgba_f.


File: refman.info,  Node: al_map_rgba,  Next: al_premul_rgba,  Prev: al_map_rgb_f,  Up: Colors

9.1.4 al_map_rgba
-----------------

ALLEGRO_COLOR al_map_rgba(
   unsigned char r, unsigned char g, unsigned char b, unsigned char a)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L553)

Convert r, g, b, a (ranging from 0-255) into an *note ALLEGRO_COLOR:
#allegro_color.

This function can be called before Allegro is initialized.

See also: *note al_map_rgb: #al_map_rgb, *note al_premul_rgba:
#al_premul_rgba, *note al_map_rgb_f: #al_map_rgb_f.


File: refman.info,  Node: al_premul_rgba,  Next: al_map_rgba_f,  Prev: al_map_rgba,  Up: Colors

9.1.5 al_premul_rgba
--------------------

ALLEGRO_COLOR al_premul_rgba(
   unsigned char r, unsigned char g, unsigned char b, unsigned char a)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L564)

This is a shortcut for *note al_map_rgba: #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 *note al_load_bitmap_flags:
#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:

int r = 255;
int g = 0;
int b = 0;
int a = 127;
ALLEGRO_COLOR c = al_premul_rgba(r, g, b, a);
/* Draw the bitmap tinted red and half-transparent. */
al_draw_tinted_bitmap(bmp, c, 0, 0, 0);

This function can be called before Allegro is initialized.

Since: 5.1.12

See also: *note al_map_rgba: #al_map_rgba, *note al_premul_rgba_f:
#al_premul_rgba_f.


File: refman.info,  Node: al_map_rgba_f,  Next: al_premul_rgba_f,  Prev: al_premul_rgba,  Up: Colors

9.1.6 al_map_rgba_f
-------------------

ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L584)

Convert r, g, b, a (ranging from 0.0f-1.0f) into an *note ALLEGRO_COLOR:
#allegro_color.

This function can be called before Allegro is initialized.

See also: *note al_map_rgba: #al_map_rgba, *note al_premul_rgba_f:
#al_premul_rgba_f, *note al_map_rgb_f: #al_map_rgb_f.


File: refman.info,  Node: al_premul_rgba_f,  Next: al_unmap_rgb,  Prev: al_map_rgba_f,  Up: Colors

9.1.7 al_premul_rgba_f
----------------------

ALLEGRO_COLOR al_premul_rgba_f(float r, float g, float b, float a)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L597)

This is a shortcut for *note al_map_rgba_f: #al_map_rgba_f.(r * a, g *
a, b * a, a).

By default Allegro uses pre-multiplied alpha for transparent blending of
bitmaps and primitives (see *note al_load_bitmap_flags:
#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:

float r = 1;
float g = 0;
float b = 0;
float a = 0.5;
ALLEGRO_COLOR c = al_premul_rgba_f(r, g, b, a);
/* Draw the bitmap tinted red and half-transparent. */
al_draw_tinted_bitmap(bmp, c, 0, 0, 0);

This function can be called before Allegro is initialized.

Since: 5.1.12

See also: *note al_map_rgba_f: #al_map_rgba_f, *note al_premul_rgba:
#al_premul_rgba.


File: refman.info,  Node: al_unmap_rgb,  Next: al_unmap_rgb_f,  Prev: al_premul_rgba_f,  Up: Colors

9.1.8 al_unmap_rgb
------------------

void al_unmap_rgb(ALLEGRO_COLOR color,
   unsigned char *r, unsigned char *g, unsigned char *b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L633)

Retrieves components of an ALLEGRO_COLOR, ignoring alpha.  Components
will range from 0-255.

This function can be called before Allegro is initialized.

See also: *note al_unmap_rgba: #al_unmap_rgba, *note al_unmap_rgba_f:
#al_unmap_rgba_f, *note al_unmap_rgb_f: #al_unmap_rgb_f.


File: refman.info,  Node: al_unmap_rgb_f,  Next: al_unmap_rgba,  Prev: al_unmap_rgb,  Up: Colors

9.1.9 al_unmap_rgb_f
--------------------

void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L656)

Retrieves components of an *note ALLEGRO_COLOR: #allegro_color, ignoring
alpha.  Components will range from 0.0f-1.0f.

This function can be called before Allegro is initialized.

See also: *note al_unmap_rgba: #al_unmap_rgba, *note al_unmap_rgb:
#al_unmap_rgb, *note al_unmap_rgba_f: #al_unmap_rgba_f.


File: refman.info,  Node: al_unmap_rgba,  Next: al_unmap_rgba_f,  Prev: al_unmap_rgb_f,  Up: Colors

9.1.10 al_unmap_rgba
--------------------

void al_unmap_rgba(ALLEGRO_COLOR color,
   unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L621)

Retrieves components of an *note ALLEGRO_COLOR: #allegro_color.
Components will range from 0-255.

This function can be called before Allegro is initialized.

See also: *note al_unmap_rgb: #al_unmap_rgb, *note al_unmap_rgba_f:
#al_unmap_rgba_f, *note al_unmap_rgb_f: #al_unmap_rgb_f.


File: refman.info,  Node: al_unmap_rgba_f,  Prev: al_unmap_rgba,  Up: Colors

9.1.11 al_unmap_rgba_f
----------------------

void al_unmap_rgba_f(ALLEGRO_COLOR color,
   float *r, float *g, float *b, float *a)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L644)

Retrieves components of an *note ALLEGRO_COLOR: #allegro_color.
Components will range from 0.0f-1.0f.

This function can be called before Allegro is initialized.

See also: *note al_unmap_rgba: #al_unmap_rgba, *note al_unmap_rgb:
#al_unmap_rgb, *note al_unmap_rgb_f: #al_unmap_rgb_f.


File: refman.info,  Node: Locking and pixel formats,  Next: Bitmap creation,  Prev: Colors,  Up: Graphics routines

9.2 Locking and pixel formats
=============================

* Menu:

* ALLEGRO_LOCKED_REGION::
* ALLEGRO_PIXEL_FORMAT::
* al_get_pixel_size::
* al_get_pixel_format_bits::
* al_get_pixel_block_size::
* al_get_pixel_block_width::
* al_get_pixel_block_height::
* al_lock_bitmap::
* al_lock_bitmap_region::
* al_unlock_bitmap::
* al_lock_bitmap_blocked::
* al_lock_bitmap_region_blocked::


File: refman.info,  Node: ALLEGRO_LOCKED_REGION,  Next: ALLEGRO_PIXEL_FORMAT,  Up: Locking and pixel formats

9.2.1 ALLEGRO_LOCKED_REGION
---------------------------

typedef struct ALLEGRO_LOCKED_REGION ALLEGRO_LOCKED_REGION;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/bitmap_lock.h#L23)

Users who wish to manually edit or read from a bitmap are required to
lock it first.  The ALLEGRO_LOCKED_REGION structure represents the
locked region of the bitmap.  This call will work with any bitmap,
including memory bitmaps.

typedef struct ALLEGRO_LOCKED_REGION {
   void *data;
   int format;
   int pitch;
   int pixel_size;
} ALLEGRO_LOCKED_REGION;

   • _data_ points to the leftmost pixel of the first row (row 0) of the
     locked region.  For blocked formats, this points to the leftmost
     block of the first row of blocks.

   • _format_ indicates the pixel format of the data.

   • _pitch_ gives the size in bytes of a single row (also known as the
     stride).  The pitch may be greater than ‘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
     formats, ‘row’ refers to the row of blocks, not of pixels.

   • _pixel_size_ 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.

See also: *note al_lock_bitmap: #al_lock_bitmap, *note
al_lock_bitmap_region: #al_lock_bitmap_region, *note al_unlock_bitmap:
#al_unlock_bitmap, *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format.


File: refman.info,  Node: ALLEGRO_PIXEL_FORMAT,  Next: al_get_pixel_size,  Prev: ALLEGRO_LOCKED_REGION,  Up: Locking and pixel formats

9.2.2 ALLEGRO_PIXEL_FORMAT
--------------------------

typedef enum ALLEGRO_PIXEL_FORMAT

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/color.h#L23)

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 ARGB_8888 format is
0xFFFF0000.

     _Note:_

     The pixel format is independent of endianness.  That is, in the
     above example you can always get the red component with

     (pixel & 0x00ff0000) >> 16

     But you can _not_ rely on this 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 GL_RGBA8 merely defines the component order and the
exact layout including endianness treatment is specified separately.
Usually GL_RGBA8 will correspond to 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 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
‘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.

   • ALLEGRO_PIXEL_FORMAT_ANY - Let the driver choose a format.  This is
     the default format at program start.
   • ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA - Let the driver choose a format
     without alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA - Let the driver choose a
     format with alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA - Let the driver choose a 15
     bit format without alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA - Let the driver choose a 16
     bit format without alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA - Let the driver choose a 16
     bit format with alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA - Let the driver choose a 24
     bit format without alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA - Let the driver choose a 32
     bit format without alpha.
   • ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA - Let the driver choose a 32
     bit format with alpha.
   • ALLEGRO_PIXEL_FORMAT_ARGB_8888 - 32 bit
   • ALLEGRO_PIXEL_FORMAT_RGBA_8888 - 32 bit
   • ALLEGRO_PIXEL_FORMAT_ARGB_4444 - 16 bit
   • ALLEGRO_PIXEL_FORMAT_RGB_888 - 24 bit
   • ALLEGRO_PIXEL_FORMAT_RGB_565 - 16 bit
   • ALLEGRO_PIXEL_FORMAT_RGB_555 - 15 bit
   • ALLEGRO_PIXEL_FORMAT_RGBA_5551 - 16 bit
   • ALLEGRO_PIXEL_FORMAT_ARGB_1555 - 16 bit
   • ALLEGRO_PIXEL_FORMAT_ABGR_8888 - 32 bit
   • ALLEGRO_PIXEL_FORMAT_XBGR_8888 - 32 bit
   • ALLEGRO_PIXEL_FORMAT_BGR_888 - 24 bit
   • ALLEGRO_PIXEL_FORMAT_BGR_565 - 16 bit
   • ALLEGRO_PIXEL_FORMAT_BGR_555 - 15 bit
   • ALLEGRO_PIXEL_FORMAT_RGBX_8888 - 32 bit
   • ALLEGRO_PIXEL_FORMAT_XRGB_8888 - 32 bit
   • ALLEGRO_PIXEL_FORMAT_ABGR_F32 - 128 bit
   • 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.
   • ALLEGRO_PIXEL_FORMAT_RGBA_4444 - 16bit
   • 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.  Since 5.1.2.
   • 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.  Since 5.1.9.
   • 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.  Since 5.1.9.
   • 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.  Since 5.1.9.

See also: *note al_set_new_bitmap_format: #al_set_new_bitmap_format,
*note al_get_bitmap_format: #al_get_bitmap_format.


File: refman.info,  Node: al_get_pixel_size,  Next: al_get_pixel_format_bits,  Prev: ALLEGRO_PIXEL_FORMAT,  Up: Locking and pixel formats

9.2.3 al_get_pixel_size
-----------------------

int al_get_pixel_size(int format)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L398)

Return the number of bytes that a pixel of the given format occupies.
For blocked pixel formats (e.g. compressed formats), this returns 0.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_get_pixel_format_bits: #al_get_pixel_format_bits.


File: refman.info,  Node: al_get_pixel_format_bits,  Next: al_get_pixel_block_size,  Prev: al_get_pixel_size,  Up: Locking and pixel formats

9.2.4 al_get_pixel_format_bits
------------------------------

int al_get_pixel_format_bits(int format)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L406)

Return the number of bits that a pixel of the given format occupies.
For blocked pixel formats (e.g. compressed formats), this returns 0.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_get_pixel_size: #al_get_pixel_size.


File: refman.info,  Node: al_get_pixel_block_size,  Next: al_get_pixel_block_width,  Prev: al_get_pixel_format_bits,  Up: Locking and pixel formats

9.2.5 al_get_pixel_block_size
-----------------------------

int al_get_pixel_block_size(int format)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L374)

Return the number of bytes that a block of pixels with this format
occupies.

Since: 5.1.9.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_get_pixel_block_width: #al_get_pixel_block_width, *note
al_get_pixel_block_height: #al_get_pixel_block_height.


File: refman.info,  Node: al_get_pixel_block_width,  Next: al_get_pixel_block_height,  Prev: al_get_pixel_block_size,  Up: Locking and pixel formats

9.2.6 al_get_pixel_block_width
------------------------------

int al_get_pixel_block_width(int format)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L382)

Return the width of the the pixel block for this format.

Since: 5.1.9.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_get_pixel_block_size: #al_get_pixel_block_size, *note
al_get_pixel_block_height: #al_get_pixel_block_height.


File: refman.info,  Node: al_get_pixel_block_height,  Next: al_lock_bitmap,  Prev: al_get_pixel_block_width,  Up: Locking and pixel formats

9.2.7 al_get_pixel_block_height
-------------------------------

int al_get_pixel_block_height(int format)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L390)

Return the height of the the pixel block for this format.

Since: 5.1.9.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_get_pixel_block_size: #al_get_pixel_block_size, *note
al_get_pixel_block_width: #al_get_pixel_block_width.


File: refman.info,  Node: al_lock_bitmap,  Next: al_lock_bitmap_region,  Prev: al_get_pixel_block_height,  Up: Locking and pixel formats

9.2.8 al_lock_bitmap
--------------------

ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap,
   int format, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_lock.c#L126)

Lock 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).  Returns NULL if the bitmap cannot
be locked, e.g. the bitmap was locked previously and not unlocked.  This
function also returns NULL if the ‘format’ is a compressed format.

Flags are:

   • 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.

   • 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.

   • 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.

‘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 ‘al_get_bitmap_format(bitmap)’ as the format or use
ALLEGRO_PIXEL_FORMAT_ANY. Locking in the native format will usually be
faster.  If the bitmap format is compressed, using
ALLEGRO_PIXEL_FORMAT_ANY will choose an implementation defined
non-compressed format.

On some platforms, Allegro automatically backs up the contents of video
bitmaps because they may be occasionally lost (see discussion in *note
al_create_bitmap: #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
ALLEGRO_NO_PRESERVE_TEXTURE flag.

     _Note:_ While a bitmap is locked, you can not use any drawing
     operations on it (with the sole exception of *note al_put_pixel:
     #al_put_pixel. and *note al_put_blended_pixel:
     #al_put_blended_pixel.).
See also: *note ALLEGRO_LOCKED_REGION: #allegro_locked_region, *note
ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note al_unlock_bitmap:
#al_unlock_bitmap, *note al_lock_bitmap_region: #al_lock_bitmap_region,
*note al_lock_bitmap_blocked: #al_lock_bitmap_blocked, *note
al_lock_bitmap_region_blocked: #al_lock_bitmap_region_blocked.


File: refman.info,  Node: al_lock_bitmap_region,  Next: al_unlock_bitmap,  Prev: al_lock_bitmap,  Up: Locking and pixel formats

9.2.9 al_lock_bitmap_region
---------------------------

ALLEGRO_LOCKED_REGION *al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap,
   int x, int y, int width, int height, int format, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_lock.c#L25)

Like *note al_lock_bitmap: #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.

     _Note:_ Using the ALLEGRO_LOCK_WRITEONLY with a blocked pixel
     format (i.e. formats for which *note al_get_pixel_block_width:
     #al_get_pixel_block_width. or *note al_get_pixel_block_height:
     #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 ALLEGRO_LOCK_READWRITE instead in order to pad this region with
     valid data.
See also: *note ALLEGRO_LOCKED_REGION: #allegro_locked_region, *note
ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note al_unlock_bitmap:
#al_unlock_bitmap.


File: refman.info,  Node: al_unlock_bitmap,  Next: al_lock_bitmap_blocked,  Prev: al_lock_bitmap_region,  Up: Locking and pixel formats

9.2.10 al_unlock_bitmap
-----------------------

void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_lock.c#L135)

Unlock 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).

See also: *note al_lock_bitmap: #al_lock_bitmap, *note
al_lock_bitmap_region: #al_lock_bitmap_region, *note
al_lock_bitmap_blocked: #al_lock_bitmap_blocked, *note
al_lock_bitmap_region_blocked: #al_lock_bitmap_region_blocked.


File: refman.info,  Node: al_lock_bitmap_blocked,  Next: al_lock_bitmap_region_blocked,  Prev: al_unlock_bitmap,  Up: Locking and pixel formats

9.2.11 al_lock_bitmap_blocked
-----------------------------

ALLEGRO_LOCKED_REGION *al_lock_bitmap_blocked(ALLEGRO_BITMAP *bitmap,
   int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_lock.c#L174)

Like *note al_lock_bitmap: #al_lock_bitmap, but allows locking bitmaps
with a blocked pixel format (i.e. a format for which *note
al_get_pixel_block_width: #al_get_pixel_block_width. or *note
al_get_pixel_block_height: #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 ‘al_lock_bitmap(bmp, al_get_bitmap_format(bmp),
flags)’.

     _Note:_ Currently there are no drawing functions that work when the
     bitmap is locked with a compressed format.  *note al_get_pixel:
     #al_get_pixel. will also not work.
Since: 5.1.9

See also: *note al_lock_bitmap: #al_lock_bitmap, *note
al_lock_bitmap_region_blocked: #al_lock_bitmap_region_blocked.


File: refman.info,  Node: al_lock_bitmap_region_blocked,  Prev: al_lock_bitmap_blocked,  Up: Locking and pixel formats

9.2.12 al_lock_bitmap_region_blocked
------------------------------------

ALLEGRO_LOCKED_REGION *al_lock_bitmap_region_blocked(ALLEGRO_BITMAP *bitmap,
   int x_block, int y_block, int width_block, int height_block, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_lock.c#L189)

Like *note al_lock_bitmap_blocked: #al_lock_bitmap_blocked, but allows
locking a sub-region, for performance.  Unlike *note
al_lock_bitmap_region: #al_lock_bitmap_region. the region specified in
terms of blocks and not pixels.

Since: 5.1.9

See also: *note al_lock_bitmap_region: #al_lock_bitmap_region, *note
al_lock_bitmap_blocked: #al_lock_bitmap_blocked.


File: refman.info,  Node: Bitmap creation,  Next: Bitmap properties,  Prev: Locking and pixel formats,  Up: Graphics routines

9.3 Bitmap creation
===================

* Menu:

* ALLEGRO_BITMAP::
* al_create_bitmap::
* al_create_sub_bitmap::
* al_clone_bitmap::
* al_convert_bitmap::
* al_convert_memory_bitmaps::
* al_destroy_bitmap::
* al_get_new_bitmap_flags::
* al_get_new_bitmap_format::
* al_set_new_bitmap_flags::
* al_add_new_bitmap_flag::
* al_set_new_bitmap_format::
* al_set_new_bitmap_depth::
* al_get_new_bitmap_depth::
* al_set_new_bitmap_samples::
* al_get_new_bitmap_samples::
* al_set_new_bitmap_wrap::
* al_get_new_bitmap_wrap::
* ALLEGRO_BITMAP_WRAP::


File: refman.info,  Node: ALLEGRO_BITMAP,  Next: al_create_bitmap,  Up: Bitmap creation

9.3.1 ALLEGRO_BITMAP
--------------------

typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/bitmap.h#L12)

Abstract type representing a bitmap (2D image).


File: refman.info,  Node: al_create_bitmap,  Next: al_create_sub_bitmap,  Prev: ALLEGRO_BITMAP,  Up: Bitmap creation

9.3.2 al_create_bitmap
----------------------

ALLEGRO_BITMAP *al_create_bitmap(int w, int h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L188)

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 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
minimum size that will work on all platforms is 32 by 32.  There is an
experimental switch to turns this padding off by editing the system
configuration (see ‘min_bitmap_size’ key in *note al_get_system_config:
#al_get_system_config.).

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 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 *note al_convert_memory_bitmaps:
#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 ALLEGRO_NO_PRESERVE_TEXTURE flag.  The
bitmap contents are lost when you get the ALLEGRO_EVENT_DISPLAY_LOST and
ALLEGRO_EVENT_DISPLAY_HALT_DRAWING and a should be restored when you get
the ALLEGRO_EVENT_DISPLAY_FOUND and when you call *note
al_acknowledge_drawing_resume: #al_acknowledge_drawing_resume. (after
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).

_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 *note
al_destroy_bitmap: #al_destroy_bitmap. on it to free any resources
allocated for it.

See also: *note al_set_new_bitmap_format: #al_set_new_bitmap_format,
*note al_set_new_bitmap_flags: #al_set_new_bitmap_flags, *note
al_clone_bitmap: #al_clone_bitmap, *note al_create_sub_bitmap:
#al_create_sub_bitmap, *note al_convert_memory_bitmaps:
#al_convert_memory_bitmaps, *note al_destroy_bitmap: #al_destroy_bitmap.


File: refman.info,  Node: al_create_sub_bitmap,  Next: al_clone_bitmap,  Prev: al_create_bitmap,  Up: Bitmap creation

9.3.3 al_create_sub_bitmap
--------------------------

ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent,
   int x, int y, int w, int h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L559)

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 *note al_get_backbuffer: #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 NULL is returned.

When you are done with using the sub-bitmap you must call *note
al_destroy_bitmap: #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 *note
al_destroy_bitmap: #al_destroy_bitmap. however.  It does not matter
whether you destroy a sub-bitmap before or after its parent otherwise.

See also: *note al_create_bitmap: #al_create_bitmap.


File: refman.info,  Node: al_clone_bitmap,  Next: al_convert_bitmap,  Prev: al_create_sub_bitmap,  Up: Bitmap creation

9.3.4 al_clone_bitmap
---------------------

ALLEGRO_BITMAP *al_clone_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L793)

Create a new bitmap with *note al_create_bitmap: #al_create_bitmap, and
copy 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.

See also: *note al_create_bitmap: #al_create_bitmap, *note
al_set_new_bitmap_format: #al_set_new_bitmap_format, *note
al_set_new_bitmap_flags: #al_set_new_bitmap_flags, *note
al_convert_bitmap: #al_convert_bitmap.


File: refman.info,  Node: al_convert_bitmap,  Next: al_convert_memory_bitmaps,  Prev: al_clone_bitmap,  Up: Bitmap creation

9.3.5 al_convert_bitmap
-----------------------

void al_convert_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_type.c#L154)

Converts the bitmap to the current bitmap flags and format.  The bitmap
will be as if it was created anew with *note al_create_bitmap:
#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.

Since: 5.1.0

See also: *note al_create_bitmap: #al_create_bitmap, *note
al_set_new_bitmap_format: #al_set_new_bitmap_format, *note
al_set_new_bitmap_flags: #al_set_new_bitmap_flags, *note
al_clone_bitmap: #al_clone_bitmap.


File: refman.info,  Node: al_convert_memory_bitmaps,  Next: al_destroy_bitmap,  Prev: al_convert_bitmap,  Up: Bitmap creation

9.3.6 al_convert_memory_bitmaps
-------------------------------

void al_convert_memory_bitmaps(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_type.c#L231)

If you create a bitmap when there is no current display (for example
because you have not called *note al_create_display: #al_create_display.
in the current thread) and are using the 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
ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP.

Since: 5.2.0

See also: *note al_convert_bitmap: #al_convert_bitmap, *note
al_create_bitmap: #al_create_bitmap.


File: refman.info,  Node: al_destroy_bitmap,  Next: al_get_new_bitmap_flags,  Prev: al_convert_memory_bitmaps,  Up: Bitmap creation

9.3.7 al_destroy_bitmap
-----------------------

void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L206)

Destroys the given bitmap, freeing all resources used by it.  This
function does nothing if the bitmap argument is NULL.

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.  (since: 5.0.10, 5.1.6)

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

See also: *note al_create_bitmap: #al_create_bitmap.


File: refman.info,  Node: al_get_new_bitmap_flags,  Next: al_get_new_bitmap_format,  Prev: al_destroy_bitmap,  Up: Bitmap creation

9.3.8 al_get_new_bitmap_flags
-----------------------------

int al_get_new_bitmap_flags(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L687)

Returns the flags used for newly created bitmaps.

See also: *note al_set_new_bitmap_flags: #al_set_new_bitmap_flags.


File: refman.info,  Node: al_get_new_bitmap_format,  Next: al_set_new_bitmap_flags,  Prev: al_get_new_bitmap_flags,  Up: Bitmap creation

9.3.9 al_get_new_bitmap_format
------------------------------

int al_get_new_bitmap_format(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L674)

Returns the format used for newly created bitmaps.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_set_new_bitmap_format: #al_set_new_bitmap_format.


File: refman.info,  Node: al_set_new_bitmap_flags,  Next: al_add_new_bitmap_flag,  Prev: al_get_new_bitmap_format,  Up: Bitmap creation

9.3.10 al_set_new_bitmap_flags
------------------------------

void al_set_new_bitmap_flags(int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L647)

Sets the flags to use for newly created bitmaps.  Valid flags are:

ALLEGRO_MEMORY_BITMAP

     Create 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.

     _Note_: Allegro’s software rendering routines are currently
     somewhat unoptimised.

     _Note:_ Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP
     flags is invalid.

ALLEGRO_VIDEO_BITMAP

     Creates a bitmap that resides in the video card memory.  These
     types of bitmaps receive the greatest benefit from hardware
     acceleration.

     _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.

     _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 ALLEGRO_CONVERT_BITMAP flag instead.

     _Note:_ Combining ALLEGRO_VIDEO_BITMAP and ALLEGRO_MEMORY_BITMAP
     flags is invalid.

ALLEGRO_CONVERT_BITMAP

     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.  Since 5.1.0.

     _Note:_ You can combine this flag with ALLEGRO_MEMORY_BITMAP or
     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 ALLEGRO_AUTO_CONVERT_BITMAPS to
     control which displays will try to auto-convert bitmaps.

ALLEGRO_FORCE_LOCKING

     Does nothing since 5.1.8.  Kept for backwards compatibility only.
ALLEGRO_NO_PRESERVE_TEXTURE

     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.
ALLEGRO_ALPHA_TEST

     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).
ALLEGRO_MIN_LINEAR

     When drawing a scaled down version of the bitmap, use linear
     filtering.  This usually looks better.  You can also combine it
     with the MIPMAP flag for even better quality.
ALLEGRO_MAG_LINEAR

     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.

ALLEGRO_MIPMAP

     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.

See also: *note al_get_new_bitmap_flags: #al_get_new_bitmap_flags, *note
al_get_bitmap_flags: #al_get_bitmap_flags.


File: refman.info,  Node: al_add_new_bitmap_flag,  Next: al_set_new_bitmap_format,  Prev: al_set_new_bitmap_flags,  Up: Bitmap creation

9.3.11 al_add_new_bitmap_flag
-----------------------------

void al_add_new_bitmap_flag(int flag)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L661)

A convenience function which does the same as

al_set_new_bitmap_flags(al_get_new_bitmap_flags() | flag);

See also: *note al_set_new_bitmap_flags: #al_set_new_bitmap_flags, *note
al_get_new_bitmap_flags: #al_get_new_bitmap_flags, *note
al_get_bitmap_flags: #al_get_bitmap_flags.


File: refman.info,  Node: al_set_new_bitmap_format,  Next: al_set_new_bitmap_depth,  Prev: al_add_new_bitmap_flag,  Up: Bitmap creation

9.3.12 al_set_new_bitmap_format
-------------------------------

void al_set_new_bitmap_format(int format)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L634)

Sets the pixel format (*note ALLEGRO_PIXEL_FORMAT:
#allegro_pixel_format.) for newly created bitmaps.  The default format
is 0 and means the display driver will choose the best format.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_get_new_bitmap_format: #al_get_new_bitmap_format, *note
al_get_bitmap_format: #al_get_bitmap_format.


File: refman.info,  Node: al_set_new_bitmap_depth,  Next: al_get_new_bitmap_depth,  Prev: al_set_new_bitmap_format,  Up: Bitmap creation

9.3.13 al_set_new_bitmap_depth
------------------------------

void al_set_new_bitmap_depth(int depth)
SETTER(new_bitmap_depth, depth)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L951)

Sets the depthbuffer depth used by newly created bitmaps (on the current
thread) if they are used with *note al_set_target_bitmap:
#al_set_target_bitmap.  0 means no depth-buffer will be created when
drawing into the bitmap, which is the default.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works for the OpenGL backend.


File: refman.info,  Node: al_get_new_bitmap_depth,  Next: al_set_new_bitmap_samples,  Prev: al_set_new_bitmap_depth,  Up: Bitmap creation

9.3.14 al_get_new_bitmap_depth
------------------------------

int al_get_new_bitmap_depth(void)
GETTER(new_bitmap_depth, 0)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L946)

Returns the value currently set with *note al_set_new_bitmap_depth:
#al_set_new_bitmap_depth. on the current thread or 0 if none was set.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works for the OpenGL backend.


File: refman.info,  Node: al_set_new_bitmap_samples,  Next: al_get_new_bitmap_samples,  Prev: al_get_new_bitmap_depth,  Up: Bitmap creation

9.3.15 al_set_new_bitmap_samples
--------------------------------

void al_set_new_bitmap_samples(int samples)
SETTER(new_bitmap_samples, samples)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L961)

Sets the multi-sampling samples used by newly created bitmaps (on the
current thread) if they are used with *note al_set_target_bitmap:
#al_set_target_bitmap.  0 means multi-sampling will not be used when
drawing into the bitmap, which is the default.  1 means multi-sampling
will be used but only using a single sample per pixel (so usually there
will be no visual difference to not using multi-sampling at all).

     _Note:_ Some platforms have restrictions on when the multi-sampling
     buffer for a bitmap is realized, i.e. down-scaled back to the
     actual bitmap dimensions.  This may only happen after a call to
     *note al_set_target_bitmap: #al_set_target_bitmap.  So for example:

al_set_target_bitmap(multisample);
al_clear_to_color(blue);
al_draw_line(0, 0, 100, 100, red, 1);
al_lock_bitmap(multisample, ...)
// ERROR: the contents of the bitmap will be undefined

al_set_target_bitmap(backbuffer);
al_lock_bitmap(multisample, ...)
// CORRECT: at this point, the bitmap contents are updated and
// there will be an anti-aliased line in it.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works for the OpenGL backend.


File: refman.info,  Node: al_get_new_bitmap_samples,  Next: al_set_new_bitmap_wrap,  Prev: al_set_new_bitmap_samples,  Up: Bitmap creation

9.3.16 al_get_new_bitmap_samples
--------------------------------

int al_get_new_bitmap_samples(void)
GETTER(new_bitmap_samples, 0)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L956)

Returns the value currently set with *note al_set_new_bitmap_samples:
#al_set_new_bitmap_samples. on the current thread or 0 if none was set.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works for the OpenGL backend.


File: refman.info,  Node: al_set_new_bitmap_wrap,  Next: al_get_new_bitmap_wrap,  Prev: al_get_new_bitmap_samples,  Up: Bitmap creation

9.3.17 al_set_new_bitmap_wrap
-----------------------------

void al_set_new_bitmap_wrap(ALLEGRO_BITMAP_WRAP u, ALLEGRO_BITMAP_WRAP v)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L981)

Sets the texture wrapping settings for newly created bitmaps (on the
current thread).  Typically you take advantage of this feature either
via the primitives addon (see *note al_draw_prim: #al_draw_prim. and
others) or via custom shaders (see *note ALLEGRO_SHADER:
#allegro_shader.).

     _Note:_ In the context of custom shaders, Direct3D and OpenGL have
     different granularities for controlling this setting.  Direct3D
     sets wrapping setting for each sampler separately, while OpenGL
     sets it per-texture.  This interacts particularly poorly with the
     primitives addon which (for backwards compatibility) alters the
     wrapping setting.  To minimize this issue, use a wrapping setting
     that’s not ALLEGRO_BITMAP_WRAP_DEFAULT.
Since: 5.2.8

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature.
See also: *note ALLEGRO_BITMAP_WRAP: #allegro_bitmap_wrap.


File: refman.info,  Node: al_get_new_bitmap_wrap,  Next: ALLEGRO_BITMAP_WRAP,  Prev: al_set_new_bitmap_wrap,  Up: Bitmap creation

9.3.18 al_get_new_bitmap_wrap
-----------------------------

Source Code

Returns the value currently set with *note al_set_new_bitmap_wrap:
#al_set_new_bitmap_wrap. on the current thread.

Since: 5.2.8

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature.
See also: *note ALLEGRO_BITMAP_WRAP: #allegro_bitmap_wrap.


File: refman.info,  Node: ALLEGRO_BITMAP_WRAP,  Prev: al_get_new_bitmap_wrap,  Up: Bitmap creation

9.3.19 ALLEGRO_BITMAP_WRAP
--------------------------

typedef enum ALLEGRO_BITMAP_WRAP {

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/bitmap.h#L17)

Controls the how the pixel color is determined from a texture querying
the texture coordinates are outside the usual bounds.

   • ALLEGRO_BITMAP_WRAP_DEFAULT - The default behavior.  This
     corresponds to ALLEGRO_BITMAP_WRAP_REPEAT when using the primitives
     addon and ALLEGRO_BITMAP_WRAP_CLAMP otherwise.

   • ALLEGRO_BITMAP_WRAP_REPEAT - The texture coordinates get shifted to
     the opposite edge that they go past.

   • ALLEGRO_BITMAP_WRAP_CLAMP - The texture coordinates get clamped to
     the edges that they go past.

   • ALLEGRO_BITMAP_WRAP_MIRROR - The texture coordinates get mirrored
     across the edges that they go past.


File: refman.info,  Node: Bitmap properties,  Next: Drawing operations,  Prev: Bitmap creation,  Up: Graphics routines

9.4 Bitmap properties
=====================

* Menu:

* al_get_bitmap_flags::
* al_get_bitmap_format::
* al_get_bitmap_height::
* al_get_bitmap_width::
* al_get_bitmap_depth::
* al_get_bitmap_samples::
* al_get_pixel::
* al_is_bitmap_locked::
* al_is_compatible_bitmap::
* al_is_sub_bitmap::
* al_get_parent_bitmap::
* al_get_bitmap_x::
* al_get_bitmap_y::
* al_reparent_bitmap::
* al_get_bitmap_blender::
* al_get_separate_bitmap_blender::
* al_get_bitmap_blend_color::
* al_set_bitmap_blender::
* al_set_separate_bitmap_blender::
* al_set_bitmap_blend_color::
* al_reset_bitmap_blender::


File: refman.info,  Node: al_get_bitmap_flags,  Next: al_get_bitmap_format,  Up: Bitmap properties

9.4.1 al_get_bitmap_flags
-------------------------

int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L330)

Return the flags used to create the bitmap.

See also: *note al_set_new_bitmap_flags: #al_set_new_bitmap_flags.


File: refman.info,  Node: al_get_bitmap_format,  Next: al_get_bitmap_height,  Prev: al_get_bitmap_flags,  Up: Bitmap properties

9.4.2 al_get_bitmap_format
--------------------------

int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L309)

Returns the pixel format of a bitmap.

See also: *note ALLEGRO_PIXEL_FORMAT: #allegro_pixel_format, *note
al_set_new_bitmap_flags: #al_set_new_bitmap_flags.


File: refman.info,  Node: al_get_bitmap_height,  Next: al_get_bitmap_width,  Prev: al_get_bitmap_format,  Up: Bitmap properties

9.4.3 al_get_bitmap_height
--------------------------

int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L300)

Returns the height of a bitmap in pixels.


File: refman.info,  Node: al_get_bitmap_width,  Next: al_get_bitmap_depth,  Prev: al_get_bitmap_height,  Up: Bitmap properties

9.4.4 al_get_bitmap_width
-------------------------

int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L291)

Returns the width of a bitmap in pixels.


File: refman.info,  Node: al_get_bitmap_depth,  Next: al_get_bitmap_samples,  Prev: al_get_bitmap_width,  Up: Bitmap properties

9.4.5 al_get_bitmap_depth
-------------------------

int al_get_bitmap_depth(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L350)

Return the depthbuffer depth used by this bitmap if it is used with
*note al_set_target_bitmap: #al_set_target_bitmap.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works for the OpenGL backend.


File: refman.info,  Node: al_get_bitmap_samples,  Next: al_get_pixel,  Prev: al_get_bitmap_depth,  Up: Bitmap properties

9.4.6 al_get_bitmap_samples
---------------------------

int al_get_bitmap_samples(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L361)

Return the multi-sampling samples used by this bitmap if it is used with
*note al_set_target_bitmap: #al_set_target_bitmap.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works for the OpenGL backend.


File: refman.info,  Node: al_get_pixel,  Next: al_is_bitmap_locked,  Prev: al_get_bitmap_samples,  Up: Bitmap properties

9.4.7 al_get_pixel
------------------

ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_pixel.c#L27)

Get 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.

See also: *note ALLEGRO_COLOR: #allegro_color, *note al_put_pixel:
#al_put_pixel, *note al_lock_bitmap: #al_lock_bitmap.


File: refman.info,  Node: al_is_bitmap_locked,  Next: al_is_compatible_bitmap,  Prev: al_get_pixel,  Up: Bitmap properties

9.4.8 al_is_bitmap_locked
-------------------------

bool al_is_bitmap_locked(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_lock.c#L167)

Returns whether or not a bitmap is already locked.

See also: *note al_lock_bitmap: #al_lock_bitmap, *note
al_lock_bitmap_region: #al_lock_bitmap_region, *note al_unlock_bitmap:
#al_unlock_bitmap.


File: refman.info,  Node: al_is_compatible_bitmap,  Next: al_is_sub_bitmap,  Prev: al_is_bitmap_locked,  Up: Bitmap properties

9.4.9 al_is_compatible_bitmap
-----------------------------

bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L252)

D3D and OpenGL allow sharing a texture in a way so it can be used for
multiple windows.  Each *note ALLEGRO_BITMAP: #allegro_bitmap. created
with *note al_create_bitmap: #al_create_bitmap. however is usually tied
to a single ALLEGRO_DISPLAY. 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.


File: refman.info,  Node: al_is_sub_bitmap,  Next: al_get_parent_bitmap,  Prev: al_is_compatible_bitmap,  Up: Bitmap properties

9.4.10 al_is_sub_bitmap
-----------------------

bool al_is_sub_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L633)

Returns true if the specified bitmap is a sub-bitmap, false otherwise.

See also: *note al_create_sub_bitmap: #al_create_sub_bitmap, *note
al_get_parent_bitmap: #al_get_parent_bitmap.


File: refman.info,  Node: al_get_parent_bitmap,  Next: al_get_bitmap_x,  Prev: al_is_sub_bitmap,  Up: Bitmap properties

9.4.11 al_get_parent_bitmap
---------------------------

ALLEGRO_BITMAP *al_get_parent_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L641)

Returns the bitmap this bitmap is a sub-bitmap of.  Returns NULL 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
*note al_create_sub_bitmap: #al_create_sub_bitmap.  Consider this code,
for instance:

ALLEGRO_BITMAP* a = al_create_bitmap(512, 512);
ALLEGRO_BITMAP* b = al_create_sub_bitmap(a, 128, 128, 256, 256);
ALLEGRO_BITMAP* c = al_create_sub_bitmap(b, 64, 64, 128, 128);
ASSERT(al_get_parent_bitmap(b) == a && al_get_parent_bitmap(c) == a);

The assertion will pass because only ‘a’ is a real bitmap, and both ‘b’
and ‘c’ are its sub-bitmaps.

Since: 5.0.6, 5.1.2

See also: *note al_create_sub_bitmap: #al_create_sub_bitmap, *note
al_is_sub_bitmap: #al_is_sub_bitmap.


File: refman.info,  Node: al_get_bitmap_x,  Next: al_get_bitmap_y,  Prev: al_get_parent_bitmap,  Up: Bitmap properties

9.4.12 al_get_bitmap_x
----------------------

int al_get_bitmap_x(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L650)

For a sub-bitmap, return it’s x position within the parent.

See also: *note al_create_sub_bitmap: #al_create_sub_bitmap, *note
al_get_parent_bitmap: #al_get_parent_bitmap, *note al_get_bitmap_y:
#al_get_bitmap_y.

Since: 5.1.12


File: refman.info,  Node: al_get_bitmap_y,  Next: al_reparent_bitmap,  Prev: al_get_bitmap_x,  Up: Bitmap properties

9.4.13 al_get_bitmap_y
----------------------

int al_get_bitmap_y(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L659)

For a sub-bitmap, return it’s y position within the parent.

See also: *note al_create_sub_bitmap: #al_create_sub_bitmap, *note
al_get_parent_bitmap: #al_get_parent_bitmap, *note al_get_bitmap_x:
#al_get_bitmap_x.

Since: 5.1.12


File: refman.info,  Node: al_reparent_bitmap,  Next: al_get_bitmap_blender,  Prev: al_get_bitmap_y,  Up: Bitmap properties

9.4.14 al_reparent_bitmap
-------------------------

void al_reparent_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP *parent,
   int x, int y, int w, int h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L608)

For a sub-bitmap, changes the parent, position and size.  This is the
same as destroying the bitmap and re-creating it with *note
al_create_sub_bitmap: #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.

See also: *note al_create_sub_bitmap: #al_create_sub_bitmap, *note
al_get_parent_bitmap: #al_get_parent_bitmap.

Since: 5.1.12


File: refman.info,  Node: al_get_bitmap_blender,  Next: al_get_separate_bitmap_blender,  Prev: al_reparent_bitmap,  Up: Bitmap properties

9.4.15 al_get_bitmap_blender
----------------------------

void al_get_bitmap_blender(int *op, int *src, int *dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L389)

Returns the current blender being used by the target bitmap.  You can
pass NULL for values you are not interested in.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.
See also: *note al_set_bitmap_blender: #al_set_bitmap_blender, *note
al_get_separate_bitmap_blender: #al_get_separate_bitmap_blender.


File: refman.info,  Node: al_get_separate_bitmap_blender,  Next: al_get_bitmap_blend_color,  Prev: al_get_bitmap_blender,  Up: Bitmap properties

9.4.16 al_get_separate_bitmap_blender
-------------------------------------

void al_get_separate_bitmap_blender(int *op, int *src, int *dst, int *alpha_op, int *alpha_src, int *alpha_dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L396)

Returns the current blender being used by the target bitmap.  You can
pass NULL for values you are not interested in.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.
See also: *note al_set_separate_bitmap_blender:
#al_set_separate_bitmap_blender, *note al_get_bitmap_blender:
#al_get_bitmap_blender.


File: refman.info,  Node: al_get_bitmap_blend_color,  Next: al_set_bitmap_blender,  Prev: al_get_separate_bitmap_blender,  Up: Bitmap properties

9.4.17 al_get_bitmap_blend_color
--------------------------------

ALLEGRO_COLOR al_get_bitmap_blend_color(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L371)

Returns the color currently used for constant color blending on the
target bitmap.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.
See also: *note al_set_bitmap_blend_color: #al_set_bitmap_blend_color.


File: refman.info,  Node: al_set_bitmap_blender,  Next: al_set_separate_bitmap_blender,  Prev: al_get_bitmap_blend_color,  Up: Bitmap properties

9.4.18 al_set_bitmap_blender
----------------------------

void al_set_bitmap_blender(int op, int src, int dest)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L445)

Sets the function to use for blending when rendering to the target
bitmap.  If no blender is set for a given bitmap at draw time, the
values set for *note al_set_blender: #al_set_blender./*note
al_set_separate_blender: #al_set_separate_blender. are used instead.

To use separate functions for chroma (RGB) and alpha channels, use *note
al_set_separate_bitmap_blender: #al_set_separate_bitmap_blender.

See *note al_set_blender: #al_set_blender. for more information about
how blending works.

See also: *note al_set_separate_bitmap_blender:
#al_set_separate_bitmap_blender, *note al_reset_bitmap_blender:
#al_reset_bitmap_blender.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: al_set_separate_bitmap_blender,  Next: al_set_bitmap_blend_color,  Prev: al_set_bitmap_blender,  Up: Bitmap properties

9.4.19 al_set_separate_bitmap_blender
-------------------------------------

void al_set_separate_bitmap_blender(int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L456)

Like *note al_set_bitmap_blender: #al_set_bitmap_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.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.
See also: *note al_set_bitmap_blender: #al_set_bitmap_blender, *note
al_reset_bitmap_blender: #al_reset_bitmap_blender.


File: refman.info,  Node: al_set_bitmap_blend_color,  Next: al_reset_bitmap_blender,  Prev: al_set_separate_bitmap_blender,  Up: Bitmap properties

9.4.20 al_set_bitmap_blend_color
--------------------------------

void al_set_bitmap_blend_color(ALLEGRO_COLOR col)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L432)

Sets the color to use for ‘ALLEGRO_CONST_COLOR’ or
‘ALLEGRO_INVERSE_CONST_COLOR’ blend operations.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.
See also: *note al_set_bitmap_blender: #al_set_bitmap_blender, *note
al_reset_bitmap_blender: #al_reset_bitmap_blender.


File: refman.info,  Node: al_reset_bitmap_blender,  Prev: al_set_bitmap_blend_color,  Up: Bitmap properties

9.4.21 al_reset_bitmap_blender
------------------------------

void al_reset_bitmap_blender(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L475)

Resets the blender for this bitmap to the default.  After resetting the
bitmap blender, the values set for *note al_set_bitmap_blender:
#al_set_bitmap_blender./*note al_set_separate_bitmap_blender:
#al_set_separate_bitmap_blender. will be used instead.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API.
See also: *note al_set_bitmap_blender: #al_set_bitmap_blender.


File: refman.info,  Node: Drawing operations,  Next: Target bitmap,  Prev: Bitmap properties,  Up: Graphics routines

9.5 Drawing operations
======================

All drawing operations draw to the current “target bitmap” of the
current thread.  Initially, the target bitmap will be the backbuffer of
the last display created in a thread.

* Menu:

* al_clear_to_color::
* al_clear_depth_buffer::
* al_draw_bitmap::
* al_draw_tinted_bitmap::
* al_draw_bitmap_region::
* al_draw_tinted_bitmap_region::
* al_draw_pixel::
* al_draw_rotated_bitmap::
* al_draw_tinted_rotated_bitmap::
* al_draw_scaled_rotated_bitmap::
* al_draw_tinted_scaled_rotated_bitmap::
* al_draw_tinted_scaled_rotated_bitmap_region::
* al_draw_scaled_bitmap::
* al_draw_tinted_scaled_bitmap::
* al_get_target_bitmap::
* al_put_pixel::
* al_put_blended_pixel::


File: refman.info,  Node: al_clear_to_color,  Next: al_clear_depth_buffer,  Up: Drawing operations

9.5.1 al_clear_to_color
-----------------------

void al_clear_to_color(ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/drawing.c#L26)

Clear the complete target bitmap, but confined by the clipping
rectangle.

See also: *note ALLEGRO_COLOR: #allegro_color, *note
al_set_clipping_rectangle: #al_set_clipping_rectangle, *note
al_clear_depth_buffer: #al_clear_depth_buffer.


File: refman.info,  Node: al_clear_depth_buffer,  Next: al_draw_bitmap,  Prev: al_clear_to_color,  Up: Drawing operations

9.5.2 al_clear_depth_buffer
---------------------------

void al_clear_depth_buffer(float z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/drawing.c#L46)

Clear the depth buffer (confined by the clipping rectangle) to the given
value.  A depth buffer is only available if it was requested with *note
al_set_new_display_option: #al_set_new_display_option. and the
requirement could be met by the *note al_create_display:
#al_create_display. call creating the current display.  Operations
involving the depth buffer are also affected by *note
al_set_render_state: #al_set_render_state.

For example, if ‘ALLEGRO_DEPTH_FUNCTION’ is set to ‘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.

Since: 5.1.2

See also: *note al_clear_to_color: #al_clear_to_color, *note
al_set_clipping_rectangle: #al_set_clipping_rectangle, *note
al_set_render_state: #al_set_render_state, *note
al_set_new_display_option: #al_set_new_display_option.


File: refman.info,  Node: al_draw_bitmap,  Next: al_draw_tinted_bitmap,  Prev: al_clear_depth_buffer,  Up: Drawing operations

9.5.3 al_draw_bitmap
--------------------

void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, float dx, float dy, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L148)

Draws an unscaled, unrotated bitmap at the given position to the current
target bitmap (see *note al_set_target_bitmap: #al_set_target_bitmap.).

‘flags’ can be a combination of:

   • ALLEGRO_FLIP_HORIZONTAL - flip the bitmap about the y-axis
   • ALLEGRO_FLIP_VERTICAL - flip the bitmap about the x-axis

     _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.
     _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.
See also: *note al_draw_bitmap_region: #al_draw_bitmap_region, *note
al_draw_scaled_bitmap: #al_draw_scaled_bitmap, *note
al_draw_rotated_bitmap: #al_draw_rotated_bitmap, *note
al_draw_scaled_rotated_bitmap: #al_draw_scaled_rotated_bitmap.


File: refman.info,  Node: al_draw_tinted_bitmap,  Next: al_draw_bitmap_region,  Prev: al_draw_bitmap,  Up: Drawing operations

9.5.4 al_draw_tinted_bitmap
---------------------------

void al_draw_tinted_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint,
   float dx, float dy, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L137)

Like *note al_draw_bitmap: #al_draw_bitmap. but multiplies all colors in
the bitmap with the given color.  For example:

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).

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 *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_bitmap: #al_draw_bitmap.


File: refman.info,  Node: al_draw_bitmap_region,  Next: al_draw_tinted_bitmap_region,  Prev: al_draw_tinted_bitmap,  Up: Drawing operations

9.5.5 al_draw_bitmap_region
---------------------------

void al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap,
   float sx, float sy, float sw, float sh, float dx, float dy, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L156)

Draws a region of the given bitmap to the target bitmap.

   • sx - source x
   • sy - source y
   • sw - source width (width of region to blit)
   • sh - source height (height of region to blit)
   • dx - destination x
   • dy - destination y
   • flags - same as for *note al_draw_bitmap: #al_draw_bitmap.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_bitmap: #al_draw_bitmap, *note
al_draw_scaled_bitmap: #al_draw_scaled_bitmap, *note
al_draw_rotated_bitmap: #al_draw_rotated_bitmap, *note
al_draw_scaled_rotated_bitmap: #al_draw_scaled_rotated_bitmap.


File: refman.info,  Node: al_draw_tinted_bitmap_region,  Next: al_draw_pixel,  Prev: al_draw_bitmap_region,  Up: Drawing operations

9.5.6 al_draw_tinted_bitmap_region
----------------------------------

void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_COLOR tint,
   float sx, float sy, float sw, float sh, float dx, float dy,
   int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L125)

Like *note al_draw_bitmap_region: #al_draw_bitmap_region. but multiplies
all colors in the bitmap with the given color.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_tinted_bitmap: #al_draw_tinted_bitmap.


File: refman.info,  Node: al_draw_pixel,  Next: al_draw_rotated_bitmap,  Prev: al_draw_tinted_bitmap_region,  Up: Drawing operations

9.5.7 al_draw_pixel
-------------------

void al_draw_pixel(float x, float y, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/drawing.c#L64)

Draws a single pixel at x, y.  This function, unlike *note al_put_pixel:
#al_put_pixel, does blending and, unlike *note al_put_blended_pixel:
#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 *note al_draw_prim: #al_draw_prim.
with ALLEGRO_PRIM_POINT_LIST from the primitives addon.

   • x - destination x
   • y - destination y
   • color - color of the pixel

     _Note:_ This function may not draw exactly where you expect it to.
     See the pixel-precise output section on the primitives addon
     documentation for details on how to control exactly where the pixel
     is drawn.
See also: *note ALLEGRO_COLOR: #allegro_color, *note al_put_pixel:
#al_put_pixel.


File: refman.info,  Node: al_draw_rotated_bitmap,  Next: al_draw_tinted_rotated_bitmap,  Prev: al_draw_pixel,  Up: Drawing operations

9.5.8 al_draw_rotated_bitmap
----------------------------

void al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
   float cx, float cy, float dx, float dy, float angle, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L205)

Draws a rotated version of the given bitmap to the target bitmap.  The
bitmap is rotated by ‘angle’ radians clockwise.

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

   • cx - center x (relative to the bitmap)
   • cy - center y (relative to the bitmap)
   • dx - destination x
   • dy - destination y
   • angle - angle by which to rotate (radians)
   • flags - same as for *note al_draw_bitmap: #al_draw_bitmap.

Example

float w = al_get_bitmap_width(bitmap);
float h = al_get_bitmap_height(bitmap);
al_draw_rotated_bitmap(bitmap, w / 2, h / 2, x, y, ALLEGRO_PI / 2, 0);

The above code draws the bitmap centered on x/y and rotates it 90°
clockwise.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_bitmap: #al_draw_bitmap, *note
al_draw_bitmap_region: #al_draw_bitmap_region, *note
al_draw_scaled_bitmap: #al_draw_scaled_bitmap, *note
al_draw_scaled_rotated_bitmap: #al_draw_scaled_rotated_bitmap.


File: refman.info,  Node: al_draw_tinted_rotated_bitmap,  Next: al_draw_scaled_rotated_bitmap,  Prev: al_draw_rotated_bitmap,  Up: Drawing operations

9.5.9 al_draw_tinted_rotated_bitmap
-----------------------------------

void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_COLOR tint,
   float cx, float cy, float dx, float dy, float angle, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L194)

Like *note al_draw_rotated_bitmap: #al_draw_rotated_bitmap. but
multiplies all colors in the bitmap with the given color.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_tinted_bitmap: #al_draw_tinted_bitmap.


File: refman.info,  Node: al_draw_scaled_rotated_bitmap,  Next: al_draw_tinted_scaled_rotated_bitmap,  Prev: al_draw_tinted_rotated_bitmap,  Up: Drawing operations

9.5.10 al_draw_scaled_rotated_bitmap
------------------------------------

void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
   float cx, float cy, float dx, float dy, float xscale, float yscale,
   float angle, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L244)

Like *note al_draw_rotated_bitmap: #al_draw_rotated_bitmap, but can also
scale the bitmap.

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

   • cx - center x
   • cy - center y
   • dx - destination x
   • dy - destination y
   • xscale - how much to scale on the x-axis (e.g. 2 for twice the
     size)
   • yscale - how much to scale on the y-axis
   • angle - angle by which to rotate (radians)
   • flags - same as for *note al_draw_bitmap: #al_draw_bitmap.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_bitmap: #al_draw_bitmap, *note
al_draw_bitmap_region: #al_draw_bitmap_region, *note
al_draw_scaled_bitmap: #al_draw_scaled_bitmap, *note
al_draw_rotated_bitmap: #al_draw_rotated_bitmap.


File: refman.info,  Node: al_draw_tinted_scaled_rotated_bitmap,  Next: al_draw_tinted_scaled_rotated_bitmap_region,  Prev: al_draw_scaled_rotated_bitmap,  Up: Drawing operations

9.5.11 al_draw_tinted_scaled_rotated_bitmap
-------------------------------------------

void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_COLOR tint,
   float cx, float cy, float dx, float dy, float xscale, float yscale,
   float angle, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L215)

Like *note al_draw_scaled_rotated_bitmap:
#al_draw_scaled_rotated_bitmap. but multiplies all colors in the bitmap
with the given color.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_tinted_bitmap: #al_draw_tinted_bitmap.


File: refman.info,  Node: al_draw_tinted_scaled_rotated_bitmap_region,  Next: al_draw_scaled_bitmap,  Prev: al_draw_tinted_scaled_rotated_bitmap,  Up: Drawing operations

9.5.12 al_draw_tinted_scaled_rotated_bitmap_region
--------------------------------------------------

void al_draw_tinted_scaled_rotated_bitmap_region(ALLEGRO_BITMAP *bitmap,
   float sx, float sy, float sw, float sh,
   ALLEGRO_COLOR tint,
   float cx, float cy, float dx, float dy, float xscale, float yscale,
   float angle, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L229)

Like *note al_draw_tinted_scaled_rotated_bitmap:
#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:

al_draw_tinted_scaled_rotated_bitmap(bitmap, sx, sy, sw, sh, tint,
    cx, cy, dx, dy, xscale, yscale, angle, flags);

/* This 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 *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

Since: 5.0.6, 5.1.0

See also: *note al_draw_tinted_bitmap: #al_draw_tinted_bitmap.


File: refman.info,  Node: al_draw_scaled_bitmap,  Next: al_draw_tinted_scaled_bitmap,  Prev: al_draw_tinted_scaled_rotated_bitmap_region,  Up: Drawing operations

9.5.13 al_draw_scaled_bitmap
----------------------------

void al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
   float sx, float sy, float sw, float sh,
   float dx, float dy, float dw, float dh, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L180)

Draws a scaled version of the given bitmap to the target bitmap.

   • sx - source x
   • sy - source y
   • sw - source width
   • sh - source height
   • dx - destination x
   • dy - destination y
   • dw - destination width
   • dh - destination height
   • flags - same as for *note al_draw_bitmap: #al_draw_bitmap.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_bitmap: #al_draw_bitmap, *note
al_draw_bitmap_region: #al_draw_bitmap_region, *note
al_draw_rotated_bitmap: #al_draw_rotated_bitmap, *note
al_draw_scaled_rotated_bitmap: #al_draw_scaled_rotated_bitmap,


File: refman.info,  Node: al_draw_tinted_scaled_bitmap,  Next: al_get_target_bitmap,  Prev: al_draw_scaled_bitmap,  Up: Drawing operations

9.5.14 al_draw_tinted_scaled_bitmap
-----------------------------------

void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_COLOR tint,
   float sx, float sy, float sw, float sh,
   float dx, float dy, float dw, float dh, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_draw.c#L166)

Like *note al_draw_scaled_bitmap: #al_draw_scaled_bitmap. but multiplies
all colors in the bitmap with the given color.

See *note al_draw_bitmap: #al_draw_bitmap. for a note on restrictions on
which bitmaps can be drawn where.

See also: *note al_draw_tinted_bitmap: #al_draw_tinted_bitmap.


File: refman.info,  Node: al_get_target_bitmap,  Next: al_put_pixel,  Prev: al_draw_tinted_scaled_bitmap,  Up: Drawing operations

9.5.15 al_get_target_bitmap
---------------------------

ALLEGRO_BITMAP *al_get_target_bitmap(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L513)

Return the target bitmap of the calling thread.

See also: *note al_set_target_bitmap: #al_set_target_bitmap.


File: refman.info,  Node: al_put_pixel,  Next: al_put_blended_pixel,  Prev: al_get_target_bitmap,  Up: Drawing operations

9.5.16 al_put_pixel
-------------------

void al_put_pixel(int x, int y, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_pixel.c#L131)

Draw 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.

See also: *note ALLEGRO_COLOR: #allegro_color, *note al_get_pixel:
#al_get_pixel, *note al_put_blended_pixel: #al_put_blended_pixel, *note
al_lock_bitmap: #al_lock_bitmap.


File: refman.info,  Node: al_put_blended_pixel,  Prev: al_put_pixel,  Up: Drawing operations

9.5.17 al_put_blended_pixel
---------------------------

void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_pixel.c#L139)

Like *note al_put_pixel: #al_put_pixel, but the pixel color is blended
using the current blenders before being drawn.

See also: *note ALLEGRO_COLOR: #allegro_color, *note al_put_pixel:
#al_put_pixel.


File: refman.info,  Node: Target bitmap,  Next: Blending modes,  Prev: Drawing operations,  Up: Graphics routines

9.6 Target bitmap
=================

* Menu:

* al_set_target_bitmap::
* al_set_target_backbuffer::
* al_get_current_display::


File: refman.info,  Node: al_set_target_bitmap,  Next: al_set_target_backbuffer,  Up: Target bitmap

9.6.1 al_set_target_bitmap
--------------------------

void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L407)

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
*note al_get_backbuffer: #al_get_backbuffer.  As a convenience, you may
also use *note al_set_target_backbuffer: #al_set_target_backbuffer.

Each allegro bitmap maintains two transformation matrices associated
with it for drawing onto the bitmap.  There is a view matrix and a
projection matrix.  When you call al_set_target_bitmap, these will be
made current for the bitmap, affecting global OpenGL and DirectX states
depending on the driver in use.

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 ‘al_set_target_bitmap(NULL);’

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 *note
al_create_bitmap: #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
ALLEGRO_NO_PRESERVE_TEXTURE flag.

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:

   • The GL_EXT_framebuffer_object OpenGL extension is available.
   • The bitmap is not a memory bitmap.
   • 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 *note
al_remove_opengl_fbo: #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 *note
al_get_opengl_fbo: #al_get_opengl_fbo. to retrieve the FBO id.

In the following example, no FBO will be created:

lock = al_lock_bitmap(bitmap);
al_set_target_bitmap(bitmap);
al_put_pixel(x, y, color);
al_unlock_bitmap(bitmap);

The above allows using *note al_put_pixel: #al_put_pixel. on a locked
bitmap without creating an FBO.

In this example an FBO is created however:

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.

See also: *note al_get_target_bitmap: #al_get_target_bitmap, *note
al_set_target_backbuffer: #al_set_target_backbuffer.


File: refman.info,  Node: al_set_target_backbuffer,  Next: al_get_current_display,  Prev: al_set_target_bitmap,  Up: Target bitmap

9.6.2 al_set_target_backbuffer
------------------------------

void al_set_target_backbuffer(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L504)

Same as ‘al_set_target_bitmap(al_get_backbuffer(display));’

See also: *note al_set_target_bitmap: #al_set_target_bitmap, *note
al_get_backbuffer: #al_get_backbuffer.


File: refman.info,  Node: al_get_current_display,  Prev: al_set_target_backbuffer,  Up: Target bitmap

9.6.3 al_get_current_display
----------------------------

ALLEGRO_DISPLAY *al_get_current_display(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L394)

Return the display that is “current” for the calling thread, or NULL if
there is none.

See also: *note al_set_target_bitmap: #al_set_target_bitmap.


File: refman.info,  Node: Blending modes,  Next: Clipping,  Prev: Target bitmap,  Up: Graphics routines

9.7 Blending modes
==================

* Menu:

* al_get_blender::
* al_get_separate_blender::
* al_get_blend_color::
* al_set_blender::
* al_set_separate_blender::
* al_set_blend_color::


File: refman.info,  Node: al_get_blender,  Next: al_get_separate_blender,  Up: Blending modes

9.7.1 al_get_blender
--------------------

void al_get_blender(int *op, int *src, int *dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L578)

Returns the active blender for the current thread.  You can pass NULL
for values you are not interested in.

See also: *note al_set_blender: #al_set_blender, *note
al_get_separate_blender: #al_get_separate_blender.


File: refman.info,  Node: al_get_separate_blender,  Next: al_get_blend_color,  Prev: al_get_blender,  Up: Blending modes

9.7.2 al_get_separate_blender
-----------------------------

void al_get_separate_blender(int *op, int *src, int *dst,
   int *alpha_op, int *alpha_src, int *alpha_dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L600)

Returns the active blender for the current thread.  You can pass NULL
for values you are not interested in.

See also: *note al_set_separate_blender: #al_set_separate_blender, *note
al_get_blender: #al_get_blender.


File: refman.info,  Node: al_get_blend_color,  Next: al_set_blender,  Prev: al_get_separate_blender,  Up: Blending modes

9.7.3 al_get_blend_color
------------------------

ALLEGRO_COLOR al_get_blend_color(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L587)

Returns the color currently used for constant color blending (white by
default).

See also: *note al_set_blend_color: #al_set_blend_color, *note
al_set_blender: #al_set_blender.

Since: 5.1.12


File: refman.info,  Node: al_set_blender,  Next: al_set_separate_blender,  Prev: al_get_blend_color,  Up: Blending modes

9.7.4 al_set_blender
--------------------

void al_set_blender(int op, int src, int dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L526)

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): _s = s.r, s.g, s.b, s.a_.  And
this color is drawn to a destination, which already has a color: _d =
d.r, d.g, d.b, d.a_.

The conceptional formula used by Allegro to draw any pixel then depends
on the ‘op’ parameter:

   • ALLEGRO_ADD

        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

   • ALLEGRO_DEST_MINUS_SRC

        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

   • ALLEGRO_SRC_MINUS_DEST

        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 ‘sf’ and ‘df’ passed to this function are
as follows, where ‘s’ is the source color, ‘d’ the destination color and
‘cc’ the color set with *note al_set_blend_color: #al_set_blend_color.
(white by default)

   • ALLEGRO_ZERO

        f = 0, 0, 0, 0

   • ALLEGRO_ONE

        f = 1, 1, 1, 1

   • ALLEGRO_ALPHA

        f = s.a, s.a, s.a, s.a

   • ALLEGRO_INVERSE_ALPHA

        f = 1 - s.a, 1 - s.a, 1 - s.a, 1 - s.a

   • ALLEGRO_SRC_COLOR (since: 5.0.10, 5.1.0)

        f = s.r, s.g, s.b, s.a

   • ALLEGRO_DEST_COLOR (since: 5.0.10, 5.1.8)

        f = d.r, d.g, d.b, d.a

   • ALLEGRO_INVERSE_SRC_COLOR (since: 5.0.10, 5.1.0)

        f = 1 - s.r, 1 - s.g, 1 - s.b, 1 - s.a

   • ALLEGRO_INVERSE_DEST_COLOR (since: 5.0.10, 5.1.8)

        f = 1 - d.r, 1 - d.g, 1 - d.b, 1 - d.a

   • ALLEGRO_CONST_COLOR (since: 5.1.12, not supported on OpenGLES 1.0)

        f = cc.r, cc.g, cc.b, cc.a

   • ALLEGRO_INVERSE_CONST_COLOR (since: 5.1.12, not supported on
     OpenGLES 1.0)

        f = 1 - cc.r, 1 - cc.g, 1 - cc.b, 1 - cc.a

Blending examples:

So for example, to restore the default of using premultiplied alpha
blending, you would use:

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);

As formula:

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

al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

Additive blending would be achieved with

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);

Copying the source to the destination (including alpha) unmodified

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);

Multiplying source and destination components

al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_ZERO)

Tinting the source (like *note al_draw_tinted_bitmap:
#al_draw_tinted_bitmap.)

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

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:

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

See also: *note al_set_separate_blender: #al_set_separate_blender, *note
al_set_blend_color: #al_set_blend_color, *note al_get_blender:
#al_get_blender.


File: refman.info,  Node: al_set_separate_blender,  Next: al_set_blend_color,  Prev: al_set_blender,  Up: Blending modes

9.7.5 al_set_separate_blender
-----------------------------

void al_set_separate_blender(int op, int src, int dst,
   int alpha_op, int alpha_src, int alpha_dst)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L548)

Like *note al_set_blender: #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.

See also: *note al_set_blender: #al_set_blender, *note al_get_blender:
#al_get_blender, *note al_get_separate_blender:
#al_get_separate_blender.


File: refman.info,  Node: al_set_blend_color,  Prev: al_set_separate_blender,  Up: Blending modes

9.7.6 al_set_blend_color
------------------------

void al_set_blend_color(ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L535)

Sets the color to use for blending when using the ALLEGRO_CONST_COLOR or
ALLEGRO_INVERSE_CONST_COLOR blend functions.  See *note al_set_blender:
#al_set_blender. for more information.

See also: *note al_set_blender: #al_set_blender, *note
al_get_blend_color: #al_get_blend_color.

Since: 5.1.12


File: refman.info,  Node: Clipping,  Next: Graphics utility functions,  Prev: Blending modes,  Up: Graphics routines

9.8 Clipping
============

* Menu:

* al_get_clipping_rectangle::
* al_set_clipping_rectangle::
* al_reset_clipping_rectangle::


File: refman.info,  Node: al_get_clipping_rectangle,  Next: al_set_clipping_rectangle,  Up: Clipping

9.8.1 al_get_clipping_rectangle
-------------------------------

void al_get_clipping_rectangle(int *x, int *y, int *w, int *h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L543)

Gets the clipping rectangle of the target bitmap.

See also: *note al_set_clipping_rectangle: #al_set_clipping_rectangle.


File: refman.info,  Node: al_set_clipping_rectangle,  Next: al_reset_clipping_rectangle,  Prev: al_get_clipping_rectangle,  Up: Clipping

9.8.2 al_set_clipping_rectangle
-------------------------------

void al_set_clipping_rectangle(int x, int y, int width, int height)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L487)

Set the region of the target bitmap or display that pixels get clipped
to.  The default is to clip pixels to the entire bitmap.

See also: *note al_get_clipping_rectangle: #al_get_clipping_rectangle,
*note al_reset_clipping_rectangle: #al_reset_clipping_rectangle.


File: refman.info,  Node: al_reset_clipping_rectangle,  Prev: al_set_clipping_rectangle,  Up: Clipping

9.8.3 al_reset_clipping_rectangle
---------------------------------

void al_reset_clipping_rectangle(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L528)

Equivalent to calling ‘al_set_clipping_rectangle(0, 0, w, h)’ where _w_
and _h_ are the width and height of the target bitmap respectively.

Does nothing if there is no target bitmap.

See also: *note al_set_clipping_rectangle: #al_set_clipping_rectangle.

Since: 5.0.6, 5.1.0


File: refman.info,  Node: Graphics utility functions,  Next: Deferred drawing,  Prev: Clipping,  Up: Graphics routines

9.9 Graphics utility functions
==============================

* Menu:

* al_convert_mask_to_alpha::


File: refman.info,  Node: al_convert_mask_to_alpha,  Up: Graphics utility functions

9.9.1 al_convert_mask_to_alpha
------------------------------

void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR mask_color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L255)

Convert 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.

See also: *note ALLEGRO_COLOR: #allegro_color.


File: refman.info,  Node: Deferred drawing,  Next: Image I/O,  Prev: Graphics utility functions,  Up: Graphics routines

9.10 Deferred drawing
=====================

* Menu:

* al_hold_bitmap_drawing::
* al_is_bitmap_drawing_held::


File: refman.info,  Node: al_hold_bitmap_drawing,  Next: al_is_bitmap_drawing_held,  Up: Deferred drawing

9.10.1 al_hold_bitmap_drawing
-----------------------------

void al_hold_bitmap_drawing(bool hold)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L497)

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.

See also: *note al_is_bitmap_drawing_held: #al_is_bitmap_drawing_held.


File: refman.info,  Node: al_is_bitmap_drawing_held,  Prev: al_hold_bitmap_drawing,  Up: Deferred drawing

9.10.2 al_is_bitmap_drawing_held
--------------------------------

bool al_is_bitmap_drawing_held(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L533)

Returns whether the deferred bitmap drawing mode is turned on or off.

See also: *note al_hold_bitmap_drawing: #al_hold_bitmap_drawing.


File: refman.info,  Node: Image I/O,  Next: Render State,  Prev: Deferred drawing,  Up: Graphics routines

9.11 Image I/O
==============

* Menu:

* al_register_bitmap_loader::
* al_register_bitmap_saver::
* al_register_bitmap_loader_f::
* al_register_bitmap_saver_f::
* al_load_bitmap::
* al_load_bitmap_flags::
* al_load_bitmap_f::
* al_load_bitmap_flags_f::
* al_save_bitmap::
* al_save_bitmap_f::
* al_register_bitmap_identifier::
* al_identify_bitmap::
* al_identify_bitmap_f::


File: refman.info,  Node: al_register_bitmap_loader,  Next: al_register_bitmap_saver,  Up: Image I/O

9.11.1 al_register_bitmap_loader
--------------------------------

bool al_register_bitmap_loader(const char *extension,
   ALLEGRO_BITMAP *(*loader)(const char *filename, int flags))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L128)

Register a handler for *note al_load_bitmap: #al_load_bitmap.  The given
function will be used to handle the loading of bitmaps files with the
given extension.

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

The ‘loader’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_bitmap_saver: #al_register_bitmap_saver,
*note al_register_bitmap_loader_f: #al_register_bitmap_loader_f.


File: refman.info,  Node: al_register_bitmap_saver,  Next: al_register_bitmap_loader_f,  Prev: al_register_bitmap_loader,  Up: Image I/O

9.11.2 al_register_bitmap_saver
-------------------------------

bool al_register_bitmap_saver(const char *extension,
   bool (*saver)(const char *filename, ALLEGRO_BITMAP *bmp))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L137)

Register a handler for *note al_save_bitmap: #al_save_bitmap.  The given
function will be used to handle the saving of bitmaps files with the
given extension.

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

The ‘saver’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_bitmap_loader: #al_register_bitmap_loader,
*note al_register_bitmap_saver_f: #al_register_bitmap_saver_f.


File: refman.info,  Node: al_register_bitmap_loader_f,  Next: al_register_bitmap_saver_f,  Prev: al_register_bitmap_saver,  Up: Image I/O

9.11.3 al_register_bitmap_loader_f
----------------------------------

bool al_register_bitmap_loader_f(const char *extension,
   ALLEGRO_BITMAP *(*fs_loader)(ALLEGRO_FILE *fp, int flags))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L146)

Register a handler for *note al_load_bitmap_f: #al_load_bitmap_f.  The
given function will be used to handle the loading of bitmaps files with
the given extension.

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

The ‘fs_loader’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_bitmap_loader: #al_register_bitmap_loader.


File: refman.info,  Node: al_register_bitmap_saver_f,  Next: al_load_bitmap,  Prev: al_register_bitmap_loader_f,  Up: Image I/O

9.11.4 al_register_bitmap_saver_f
---------------------------------

bool al_register_bitmap_saver_f(const char *extension,
   bool (*fs_saver)(ALLEGRO_FILE *fp, ALLEGRO_BITMAP *bmp))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L155)

Register a handler for *note al_save_bitmap_f: #al_save_bitmap_f.  The
given function will be used to handle the saving of bitmaps files with
the given extension.

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

The ‘saver_f’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_bitmap_saver: #al_register_bitmap_saver.


File: refman.info,  Node: al_load_bitmap,  Next: al_load_bitmap_flags,  Prev: al_register_bitmap_saver_f,  Up: Image I/O

9.11.5 al_load_bitmap
---------------------

ALLEGRO_BITMAP *al_load_bitmap(const char *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L173)

Loads an image file into a new *note ALLEGRO_BITMAP: #allegro_bitmap.
The file type is determined by *note al_identify_bitmap:
#al_identify_bitmap, using the extension as a fallback in case
identification is not possible.

Returns NULL on error.

This is the same as calling *note al_load_bitmap_flags:
#al_load_bitmap_flags. with a flags parameter of 0.

     _Note:_ the core Allegro library does not support any image file
     formats by default.  You must use the allegro_image addon, or
     register your own format handler.
See also: *note al_load_bitmap_flags: #al_load_bitmap_flags, *note
al_load_bitmap_f: #al_load_bitmap_f, *note al_register_bitmap_loader:
#al_register_bitmap_loader, *note al_set_new_bitmap_format:
#al_set_new_bitmap_format, *note al_set_new_bitmap_flags:
#al_set_new_bitmap_flags, *note al_init_image_addon:
#al_init_image_addon.


File: refman.info,  Node: al_load_bitmap_flags,  Next: al_load_bitmap_f,  Prev: al_load_bitmap,  Up: Image I/O

9.11.6 al_load_bitmap_flags
---------------------------

ALLEGRO_BITMAP *al_load_bitmap_flags(const char *filename, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L190)

Loads an image file into a new *note ALLEGRO_BITMAP: #allegro_bitmap.
The file type is determined by *note al_identify_bitmap:
#al_identify_bitmap, using the extension as a fallback in case
identification is not possible.

Returns NULL on error.

The flags parameter may be a combination of the following constants:

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:

     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
     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 al_set_blender(ALLEGRO_ADD,
     ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA).

     The 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:

     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
     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.

     // 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 (ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) for
     blending, the formula is:

     a = da * dst + sa * src

     Expands to:

     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.

ALLEGRO_KEEP_INDEX

     Load the palette indices of 8-bit .bmp and .pcx files instead of
     the rgb colors.  Since 5.1.0.
ALLEGRO_KEEP_BITMAP_FORMAT

     Force the resulting *note ALLEGRO_BITMAP: #allegro_bitmap. to use
     the same format as the file.

     _This is not yet honoured._

     _Note:_ the core Allegro library does not support any image file
     formats by default.  You must use the allegro_image addon, or
     register your own format handler.
Since: 5.1.0

See also: *note al_load_bitmap: #al_load_bitmap.


File: refman.info,  Node: al_load_bitmap_f,  Next: al_load_bitmap_flags_f,  Prev: al_load_bitmap_flags,  Up: Image I/O

9.11.7 al_load_bitmap_f
-----------------------

ALLEGRO_BITMAP *al_load_bitmap_f(ALLEGRO_FILE *fp, const char *ident)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L246)

Loads an image from an *note ALLEGRO_FILE: #allegro_file. stream into a
new *note ALLEGRO_BITMAP: #allegro_bitmap.  The file type is determined
by *note al_identify_bitmap_f: #al_identify_bitmap_f.  If identification
is not possible, the passed ‘ident’ parameter, which is a file name
extension including the leading dot, is used as a fallback, if it is not
NULL.

This is the same as calling *note al_load_bitmap_flags_f:
#al_load_bitmap_flags_f. with 0 for the flags parameter.

Returns NULL on error.  The file remains open afterwards.

     _Note:_ the core Allegro library does not support any image file
     formats by default.  You must use the allegro_image addon, or
     register your own format handler.
See also: *note al_load_bitmap_flags_f: #al_load_bitmap_flags_f, *note
al_load_bitmap: #al_load_bitmap, *note al_register_bitmap_loader_f:
#al_register_bitmap_loader_f, *note al_init_image_addon:
#al_init_image_addon.


File: refman.info,  Node: al_load_bitmap_flags_f,  Next: al_save_bitmap,  Prev: al_load_bitmap_f,  Up: Image I/O

9.11.8 al_load_bitmap_flags_f
-----------------------------

ALLEGRO_BITMAP *al_load_bitmap_flags_f(ALLEGRO_FILE *fp,
   const char *ident, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L263)

Loads an image from an *note ALLEGRO_FILE: #allegro_file. stream into a
new *note ALLEGRO_BITMAP: #allegro_bitmap.  The file type is determined
by *note al_identify_bitmap_f: #al_identify_bitmap_f.  If identification
is not possible, the passed ‘ident’ parameter, which is a file name
extension including the leading dot, is used as a fallback, if it is not
NULL.

The flags parameter is the same as for *note al_load_bitmap_flags:
#al_load_bitmap_flags.

Returns NULL on error.  The file remains open afterwards.

     _Note:_ the core Allegro library does not support any image file
     formats by default.  You must use the allegro_image addon, or
     register your own format handler.
Since: 5.1.0

See also: *note al_load_bitmap_f: #al_load_bitmap_f, *note
al_load_bitmap_flags: #al_load_bitmap_flags.


File: refman.info,  Node: al_save_bitmap,  Next: al_save_bitmap_f,  Prev: al_load_bitmap_flags_f,  Up: Image I/O

9.11.9 al_save_bitmap
---------------------

bool al_save_bitmap(const char *filename, ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L223)

Saves an *note ALLEGRO_BITMAP: #allegro_bitmap. to an image file.  The
file type is determined by the extension.

Returns true on success, false on error.

     _Note:_ the core Allegro library does not support any image file
     formats by default.  You must use the allegro_image addon, or
     register your own format handler.
See also: *note al_save_bitmap_f: #al_save_bitmap_f, *note
al_register_bitmap_saver: #al_register_bitmap_saver, *note
al_init_image_addon: #al_init_image_addon.


File: refman.info,  Node: al_save_bitmap_f,  Next: al_register_bitmap_identifier,  Prev: al_save_bitmap,  Up: Image I/O

9.11.10 al_save_bitmap_f
------------------------

bool al_save_bitmap_f(ALLEGRO_FILE *fp, const char *ident,
   ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L280)

Saves an *note ALLEGRO_BITMAP: #allegro_bitmap. to an *note
ALLEGRO_FILE: #allegro_file. stream.  The file type is determined by the
passed ‘ident’ parameter, which is a file name extension including the
leading dot.

Returns true on success, false on error.  The file remains open
afterwards.

     _Note:_ the core Allegro library does not support any image file
     formats by default.  You must use the allegro_image addon, or
     register your own format handler.
See also: *note al_save_bitmap: #al_save_bitmap, *note
al_register_bitmap_saver_f: #al_register_bitmap_saver_f, *note
al_init_image_addon: #al_init_image_addon.


File: refman.info,  Node: al_register_bitmap_identifier,  Next: al_identify_bitmap,  Prev: al_save_bitmap_f,  Up: Image I/O

9.11.11 al_register_bitmap_identifier
-------------------------------------

bool al_register_bitmap_identifier(const char *extension,
   bool (*identifier)(ALLEGRO_FILE *f))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L164)

Register an identify handler for *note al_identify_bitmap:
#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 *note ALLEGRO_FILE: #allegro_file. 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 NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

Since: 5.1.12

See also: *note al_identify_bitmap: #al_identify_bitmap.


File: refman.info,  Node: al_identify_bitmap,  Next: al_identify_bitmap_f,  Prev: al_register_bitmap_identifier,  Up: Image I/O

9.11.12 al_identify_bitmap
--------------------------

char const *al_identify_bitmap(char const *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L306)

This works exactly as *note al_identify_bitmap_f: #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.

Since: 5.1.12

See also: *note al_init_image_addon: #al_init_image_addon, *note
al_identify_bitmap_f: #al_identify_bitmap_f, *note
al_register_bitmap_identifier: #al_register_bitmap_identifier.


File: refman.info,  Node: al_identify_bitmap_f,  Prev: al_identify_bitmap,  Up: Image I/O

9.11.13 al_identify_bitmap_f
----------------------------

char const *al_identify_bitmap_f(ALLEGRO_FILE *fp)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap_io.c#L295)

Tries to guess the bitmap file type of the open ALLEGRO_FILE by reading
the first few bytes.  By default Allegro cannot recognize any file
types, but calling *note al_init_image_addon: #al_init_image_addon. will
add detection of (some of) the types it can read.  You can also use
*note al_register_bitmap_identifier: #al_register_bitmap_identifier. to
add identification for 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 NULL
if the bitmap type cannot be determined.

Since: 5.1.12

See also: *note al_init_image_addon: #al_init_image_addon, *note
al_identify_bitmap: #al_identify_bitmap, *note
al_register_bitmap_identifier: #al_register_bitmap_identifier.


File: refman.info,  Node: Render State,  Prev: Image I/O,  Up: Graphics routines

9.12 Render State
=================

* Menu:

* ALLEGRO_RENDER_STATE::
* ALLEGRO_RENDER_FUNCTION::
* ALLEGRO_WRITE_MASK_FLAGS::
* al_set_render_state::
* al_backup_dirty_bitmap::
* al_backup_dirty_bitmaps::


File: refman.info,  Node: ALLEGRO_RENDER_STATE,  Next: ALLEGRO_RENDER_FUNCTION,  Up: Render State

9.12.1 ALLEGRO_RENDER_STATE
---------------------------

typedef enum ALLEGRO_RENDER_STATE {

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/render_state.h#L12)

Possible render states which can be set with *note al_set_render_state:
#al_set_render_state.:

ALLEGRO_ALPHA_TEST

     If this is set to 1, the values of ALLEGRO_ALPHA_FUNCTION and
     ALLEGRO_ALPHA_TEST_VALUE define a comparison function which is
     performed on the alpha component of each pixel.  Only if it
     evaluates to true the pixel is written.  Otherwise no subsequent
     processing (like depth test or blending) is performed.  This can be
     very useful, for example if a depth buffer is used but you do not
     want fully transparent pixels to modify it.
ALLEGRO_ALPHA_FUNCTION

     One of *note ALLEGRO_RENDER_FUNCTION: #allegro_render_function,
     only used when ALLEGRO_ALPHA_TEST is 1.
ALLEGRO_ALPHA_TEST_VALUE

     Only used when ALLEGRO_ALPHA_TEST is 1.  Should be a value of 0 -
     255.
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 ALLEGRO_DEPTH_TEST is 1, in addition to the write
     mask flag being set.
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
     ALLEGRO_DEPTH_FUNCTION. Allegro primitives with no explicit z
     coordinate will write a value of 0 into the depth buffer.
ALLEGRO_DEPTH_FUNCTION

     One of *note ALLEGRO_RENDER_FUNCTION: #allegro_render_function,
     only used when ALLEGRO_DEPTH_TEST is 1.

Since: 5.1.2

See also: *note al_set_render_state: #al_set_render_state, *note
ALLEGRO_RENDER_FUNCTION: #allegro_render_function, *note
ALLEGRO_WRITE_MASK_FLAGS: #allegro_write_mask_flags.


File: refman.info,  Node: ALLEGRO_RENDER_FUNCTION,  Next: ALLEGRO_WRITE_MASK_FLAGS,  Prev: ALLEGRO_RENDER_STATE,  Up: Render State

9.12.2 ALLEGRO_RENDER_FUNCTION
------------------------------

typedef enum ALLEGRO_RENDER_FUNCTION {

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/render_state.h#L26)

Possible functions are:

   • ALLEGRO_RENDER_NEVER
   • ALLEGRO_RENDER_ALWAYS
   • ALLEGRO_RENDER_LESS
   • ALLEGRO_RENDER_EQUAL
   • ALLEGRO_RENDER_LESS_EQUAL
   • ALLEGRO_RENDER_GREATER
   • ALLEGRO_RENDER_NOT_EQUAL
   • ALLEGRO_RENDER_GREATER_EQUAL

Since: 5.1.2

See also: *note al_set_render_state: #al_set_render_state.


File: refman.info,  Node: ALLEGRO_WRITE_MASK_FLAGS,  Next: al_set_render_state,  Prev: ALLEGRO_RENDER_FUNCTION,  Up: Render State

9.12.3 ALLEGRO_WRITE_MASK_FLAGS
-------------------------------

typedef enum ALLEGRO_WRITE_MASK_FLAGS {

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/render_state.h#L39)

Each enabled bit means the corresponding value is written, a disabled
bit means it is not.

   • ALLEGRO_MASK_RED
   • ALLEGRO_MASK_GREEN
   • ALLEGRO_MASK_BLUE
   • ALLEGRO_MASK_ALPHA
   • ALLEGRO_MASK_DEPTH
   • ALLEGRO_MASK_RGB - Same as RED | GREEN | BLUE.
   • ALLEGRO_MASK_RGBA - Same as RGB | ALPHA.

Since: 5.1.2

See also: *note al_set_render_state: #al_set_render_state.


File: refman.info,  Node: al_set_render_state,  Next: al_backup_dirty_bitmap,  Prev: ALLEGRO_WRITE_MASK_FLAGS,  Up: Render State

9.12.4 al_set_render_state
--------------------------

void al_set_render_state(ALLEGRO_RENDER_STATE state, int value)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L595)

Set one of several render attributes; see *note ALLEGRO_RENDER_STATE:
#allegro_render_state. for details.

This function does nothing if the target bitmap is a memory bitmap.

Since: 5.1.2

See also: *note ALLEGRO_RENDER_STATE: #allegro_render_state, *note
ALLEGRO_RENDER_FUNCTION: #allegro_render_function, *note
ALLEGRO_WRITE_MASK_FLAGS: #allegro_write_mask_flags.


File: refman.info,  Node: al_backup_dirty_bitmap,  Next: al_backup_dirty_bitmaps,  Prev: al_set_render_state,  Up: Render State

9.12.5 al_backup_dirty_bitmap
-----------------------------

void al_backup_dirty_bitmap(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/bitmap.c#L811)

On some platforms, notably Windows Direct3D and Android, textures may be
lost at any time for events such as display resize or switching out of
the app.  On those platforms, bitmaps created without the
ALLEGRO_NO_PRESERVE_TEXTURE flag automatically get backed up to system
memory every time al_flip_display is called.

This function gives you more control over when your bitmaps get backed
up.  By calling this function after modifying a bitmap, you can make
sure the bitmap is backed up right away instead of during the next flip.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This API is new and subject
     to refinement.
See also: *note al_backup_dirty_bitmaps: #al_backup_dirty_bitmaps, *note
al_create_bitmap: #al_create_bitmap.


File: refman.info,  Node: al_backup_dirty_bitmaps,  Prev: al_backup_dirty_bitmap,  Up: Render State

9.12.6 al_backup_dirty_bitmaps
------------------------------

void al_backup_dirty_bitmaps(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/display.c#L633)

Backs up all of a display’s bitmaps to system memory.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This API is new and subject
     to refinement.
See also: *note al_backup_dirty_bitmap: #al_backup_dirty_bitmap.


File: refman.info,  Node: Haptic routines,  Next: Joystick routines,  Prev: Graphics routines,  Up: Top

10 Haptic routines
******************

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

 #include <allegro5/allegro.h>

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

* Menu:

* ALLEGRO_HAPTIC::
* ALLEGRO_HAPTIC_CONSTANTS::
* ALLEGRO_HAPTIC_EFFECT::
* ALLEGRO_HAPTIC_EFFECT_ID::
* al_install_haptic::
* al_uninstall_haptic::
* al_is_haptic_installed::
* al_is_mouse_haptic::
* al_is_keyboard_haptic::
* al_is_display_haptic::
* al_is_joystick_haptic::
* al_is_touch_input_haptic::
* al_get_haptic_from_mouse::
* al_get_haptic_from_keyboard::
* al_get_haptic_from_display::
* al_get_haptic_from_joystick::
* al_get_haptic_from_touch_input::
* al_release_haptic::
* al_is_haptic_active::
* al_get_haptic_capabilities::
* al_is_haptic_capable::
* al_set_haptic_gain::
* al_get_haptic_gain::
* al_set_haptic_autocenter::
* al_get_haptic_autocenter::
* al_get_max_haptic_effects::
* al_is_haptic_effect_ok::
* al_upload_haptic_effect::
* al_play_haptic_effect::
* al_upload_and_play_haptic_effect::
* al_stop_haptic_effect::
* al_is_haptic_effect_playing::
* al_get_haptic_effect_duration::
* al_release_haptic_effect::
* al_rumble_haptic::


File: refman.info,  Node: ALLEGRO_HAPTIC,  Next: ALLEGRO_HAPTIC_CONSTANTS,  Up: Haptic routines

10.1 ALLEGRO_HAPTIC
===================

typedef struct ALLEGRO_HAPTIC ALLEGRO_HAPTIC;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/haptic.h#L64)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.
See also: *note al_get_haptic_from_joystick:
#al_get_haptic_from_joystick.


File: refman.info,  Node: ALLEGRO_HAPTIC_CONSTANTS,  Next: ALLEGRO_HAPTIC_EFFECT,  Prev: ALLEGRO_HAPTIC,  Up: Haptic routines

10.2 ALLEGRO_HAPTIC_CONSTANTS
=============================

enum ALLEGRO_HAPTIC_CONSTANTS

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/haptic.h#L37)

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.
See also: *note al_get_haptic_capabilities: #al_get_haptic_capabilities,
*note ALLEGRO_HAPTIC_EFFECT: #allegro_haptic_effect.


File: refman.info,  Node: ALLEGRO_HAPTIC_EFFECT,  Next: ALLEGRO_HAPTIC_EFFECT_ID,  Prev: ALLEGRO_HAPTIC_CONSTANTS,  Up: Haptic routines

10.3 ALLEGRO_HAPTIC_EFFECT
==========================

struct ALLEGRO_HAPTIC_EFFECT

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/haptic.h#L169)

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

_Fields:_

type

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

        • If ‘type’ is set to ALLEGRO_HAPTIC_RUMBLE, then the effect is
          a simple “rumble” or vibration effect that shakes the device.
          In some cases, such as on a mobile platform, the whole device
          may shake.

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

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

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

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

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

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

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

direction

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

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

     If *note al_get_haptic_capabilities: #al_get_haptic_capabilities.
     has the flag ALLEGRO_HAPTIC_ANGLE set, then setting
     ‘direction.angle’ is supported.  Otherwise, it is unsupported, and
     you should set it to 0.

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

     If *note al_get_haptic_capabilities: #al_get_haptic_capabilities.
     has the flag ALLEGRO_HAPTIC_RADIUS set, then setting
     ‘direction.radius’ is supported.  Otherwise, it is unsupported, and
     you should set it to 0.

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

     If *note al_get_haptic_capabilities: #al_get_haptic_capabilities.
     has the flag ALLEGRO_HAPTIC_AZIMUTH set, then setting
     ‘direction.azimuth’ is supported.  Otherwise, it is unsupported,
     and you should set it to 0.

replay

     Determines how the effect should be played back.  ‘replay.length’
     is the duration in seconds of the effect, and ‘replay.delay’ is the
     time in seconds that the effect playback should be delayed when
     playback is started with *note al_play_haptic_effect:
     #al_play_haptic_effect.
data

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: ALLEGRO_HAPTIC_EFFECT_ID,  Next: al_install_haptic,  Prev: ALLEGRO_HAPTIC_EFFECT,  Up: Haptic routines

10.4 ALLEGRO_HAPTIC_EFFECT_ID
=============================

typedef struct ALLEGRO_HAPTIC_EFFECT_ID ALLEGRO_HAPTIC_EFFECT_ID;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/haptic.h#L183)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_install_haptic,  Next: al_uninstall_haptic,  Prev: ALLEGRO_HAPTIC_EFFECT_ID,  Up: Haptic routines

10.5 al_install_haptic
======================

bool al_install_haptic(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L34)

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

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_uninstall_haptic,  Next: al_is_haptic_installed,  Prev: al_install_haptic,  Up: Haptic routines

10.6 al_uninstall_haptic
========================

void al_uninstall_haptic(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L64)

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_haptic_installed,  Next: al_is_mouse_haptic,  Prev: al_uninstall_haptic,  Up: Haptic routines

10.7 al_is_haptic_installed
===========================

bool al_is_haptic_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L76)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_mouse_haptic,  Next: al_is_keyboard_haptic,  Prev: al_is_haptic_installed,  Up: Haptic routines

10.8 al_is_mouse_haptic
=======================

bool al_is_mouse_haptic(ALLEGRO_MOUSE *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L95)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_keyboard_haptic,  Next: al_is_display_haptic,  Prev: al_is_mouse_haptic,  Up: Haptic routines

10.9 al_is_keyboard_haptic
==========================

bool al_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L106)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_display_haptic,  Next: al_is_joystick_haptic,  Prev: al_is_keyboard_haptic,  Up: Haptic routines

10.10 al_is_display_haptic
==========================

bool al_is_display_haptic(ALLEGRO_DISPLAY *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L117)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_joystick_haptic,  Next: al_is_touch_input_haptic,  Prev: al_is_display_haptic,  Up: Haptic routines

10.11 al_is_joystick_haptic
===========================

bool al_is_joystick_haptic(ALLEGRO_JOYSTICK *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L84)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_touch_input_haptic,  Next: al_get_haptic_from_mouse,  Prev: al_is_joystick_haptic,  Up: Haptic routines

10.12 al_is_touch_input_haptic
==============================

bool al_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L127)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_from_mouse,  Next: al_get_haptic_from_keyboard,  Prev: al_is_touch_input_haptic,  Up: Haptic routines

10.13 al_get_haptic_from_mouse
==============================

ALLEGRO_HAPTIC *al_get_haptic_from_mouse(ALLEGRO_MOUSE *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L148)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_from_keyboard,  Next: al_get_haptic_from_display,  Prev: al_get_haptic_from_mouse,  Up: Haptic routines

10.14 al_get_haptic_from_keyboard
=================================

ALLEGRO_HAPTIC *al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L159)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_from_display,  Next: al_get_haptic_from_joystick,  Prev: al_get_haptic_from_keyboard,  Up: Haptic routines

10.15 al_get_haptic_from_display
================================

ALLEGRO_HAPTIC *al_get_haptic_from_display(ALLEGRO_DISPLAY *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L170)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_from_joystick,  Next: al_get_haptic_from_touch_input,  Prev: al_get_haptic_from_display,  Up: Haptic routines

10.16 al_get_haptic_from_joystick
=================================

ALLEGRO_HAPTIC *al_get_haptic_from_joystick(ALLEGRO_JOYSTICK *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L137)

If the joystick has haptic capabilities, returns the associated haptic
device handle.  Otherwise returns NULL. It’s necessary to call this
again every time the joystick configuration changes, such as through hot
plugging.  In that case, the old haptic device must be released using
*note al_release_haptic: #al_release_haptic.

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_from_touch_input,  Next: al_release_haptic,  Prev: al_get_haptic_from_joystick,  Up: Haptic routines

10.17 al_get_haptic_from_touch_input
====================================

ALLEGRO_HAPTIC *al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT *dev)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L181)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_release_haptic,  Next: al_is_haptic_active,  Prev: al_get_haptic_from_touch_input,  Up: Haptic routines

10.18 al_release_haptic
=======================

bool al_release_haptic(ALLEGRO_HAPTIC *haptic)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L385)

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_haptic_active,  Next: al_get_haptic_capabilities,  Prev: al_release_haptic,  Up: Haptic routines

10.19 al_is_haptic_active
=========================

bool al_is_haptic_active(ALLEGRO_HAPTIC *hap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L192)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_capabilities,  Next: al_is_haptic_capable,  Prev: al_is_haptic_active,  Up: Haptic routines

10.20 al_get_haptic_capabilities
================================

int al_get_haptic_capabilities(ALLEGRO_HAPTIC *hap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L203)

Returns an integer with or’ed values from *note
ALLEGRO_HAPTIC_CONSTANTS: #allegro_haptic_constants, which, if set,
indicate that the haptic device supports the given feature.

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_haptic_capable,  Next: al_set_haptic_gain,  Prev: al_get_haptic_capabilities,  Up: Haptic routines

10.21 al_is_haptic_capable
==========================

bool al_is_haptic_capable(ALLEGRO_HAPTIC * hap, int query) {

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L213)

Returns true if the haptic device supports the feature indicated by the
query parameter, false if the feature is not supported.  The query
parameter must be one of the values of *note ALLEGRO_HAPTIC_CONSTANTS:
#allegro_haptic_constants.

Since: 5.1.9

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.
See also: *note al_get_haptic_capabilities: #al_get_haptic_capabilities.


File: refman.info,  Node: al_set_haptic_gain,  Next: al_get_haptic_gain,  Prev: al_is_haptic_capable,  Up: Haptic routines

10.22 al_set_haptic_gain
========================

bool al_set_haptic_gain(ALLEGRO_HAPTIC *hap, double gain)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L231)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_gain,  Next: al_set_haptic_autocenter,  Prev: al_set_haptic_gain,  Up: Haptic routines

10.23 al_get_haptic_gain
========================

double al_get_haptic_gain(ALLEGRO_HAPTIC *hap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L220)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_set_haptic_autocenter,  Next: al_get_haptic_autocenter,  Prev: al_get_haptic_gain,  Up: Haptic routines

10.24 al_set_haptic_autocenter
==============================

bool al_set_haptic_autocenter(ALLEGRO_HAPTIC *hap, double intensity)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L252)

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

Since: 5.1.9

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_autocenter,  Next: al_get_max_haptic_effects,  Prev: al_set_haptic_autocenter,  Up: Haptic routines

10.25 al_get_haptic_autocenter
==============================

double al_get_haptic_autocenter(ALLEGRO_HAPTIC *hap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L241)

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

Since: 5.1.9

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_max_haptic_effects,  Next: al_is_haptic_effect_ok,  Prev: al_get_haptic_autocenter,  Up: Haptic routines

10.26 al_get_max_haptic_effects
===============================

int al_get_max_haptic_effects(ALLEGRO_HAPTIC *hap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L264)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_haptic_effect_ok,  Next: al_upload_haptic_effect,  Prev: al_get_max_haptic_effects,  Up: Haptic routines

10.27 al_is_haptic_effect_ok
============================

bool al_is_haptic_effect_ok(ALLEGRO_HAPTIC *hap, ALLEGRO_HAPTIC_EFFECT *effect)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L275)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_upload_haptic_effect,  Next: al_play_haptic_effect,  Prev: al_is_haptic_effect_ok,  Up: Haptic routines

10.28 al_upload_haptic_effect
=============================

bool al_upload_haptic_effect(ALLEGRO_HAPTIC *hap,
   ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L286)

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

The function *note al_get_max_haptic_effects:
#al_get_max_haptic_effects. returns how many effects can be uploaded to
the device at the same time.

The same haptic effect can be uploaded several times, as long as care is
taken to pass in a different *note ALLEGRO_HAPTIC_EFFECT_ID:
#allegro_haptic_effect_id.

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_play_haptic_effect,  Next: al_upload_and_play_haptic_effect,  Prev: al_upload_haptic_effect,  Up: Haptic routines

10.29 al_play_haptic_effect
===========================

bool al_play_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L298)

Plays back a previously uploaded haptic effect.  The play_id must be a
valid *note ALLEGRO_HAPTIC_EFFECT_ID: #allegro_haptic_effect_id.
obtained from *note al_upload_haptic_effect: #al_upload_haptic_effect,
*note al_upload_and_play_haptic_effect:
#al_upload_and_play_haptic_effect. or *note al_rumble_haptic:
#al_rumble_haptic.

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_upload_and_play_haptic_effect,  Next: al_stop_haptic_effect,  Prev: al_play_haptic_effect,  Up: Haptic routines

10.30 al_upload_and_play_haptic_effect
======================================

bool al_upload_and_play_haptic_effect(ALLEGRO_HAPTIC *hap,
   ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id, int loop)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L309)

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.
See also: *note al_upload_haptic_effect: #al_upload_haptic_effect, *note
al_play_haptic_effect: #al_play_haptic_effect.


File: refman.info,  Node: al_stop_haptic_effect,  Next: al_is_haptic_effect_playing,  Prev: al_upload_and_play_haptic_effect,  Up: Haptic routines

10.31 al_stop_haptic_effect
===========================

bool al_stop_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L330)

Stops playing a previously uploaded haptic effect.  The play_id must be
a valid *note ALLEGRO_HAPTIC_EFFECT_ID: #allegro_haptic_effect_id.
obtained from *note al_upload_haptic_effect: #al_upload_haptic_effect,
*note al_upload_and_play_haptic_effect:
#al_upload_and_play_haptic_effect. or *note al_rumble_haptic:
#al_rumble_haptic.

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_is_haptic_effect_playing,  Next: al_get_haptic_effect_duration,  Prev: al_stop_haptic_effect,  Up: Haptic routines

10.32 al_is_haptic_effect_playing
=================================

bool al_is_haptic_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L340)

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_get_haptic_effect_duration,  Next: al_release_haptic_effect,  Prev: al_is_haptic_effect_playing,  Up: Haptic routines

10.33 al_get_haptic_effect_duration
===================================

double al_get_haptic_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L349)

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

Since: 5.1.9

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_release_haptic_effect,  Next: al_rumble_haptic,  Prev: al_get_haptic_effect_duration,  Up: Haptic routines

10.34 al_release_haptic_effect
==============================

bool al_release_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L374)

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

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: al_rumble_haptic,  Prev: al_release_haptic_effect,  Up: Haptic routines

10.35 al_rumble_haptic
======================

bool al_rumble_haptic(ALLEGRO_HAPTIC *hap,
   double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/haptic.c#L356)

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

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

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

Since: 5.1.8

     _*note Unstable API: #unstable-api.:_ Perhaps could be simplified
     due to limited support for all the exposed features across all of
     the platforms.  Awaiting feedback from users.


File: refman.info,  Node: Joystick routines,  Next: Keyboard routines,  Prev: Haptic routines,  Up: Top

11 Joystick routines
********************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

On Windows there are two joystick drivers, a DirectInput one and an
Xinput one.  If support for XInput was compiled in, then it can be
enabled by calling al_set_config_value(al_get_system_config(),
“joystick”, “driver”, “xinput”) before calling al_install_joystick, or
by setting the same option in the allegro5.cfg configuration file.  The
Xinput and DirectInput drivers are mutually exclusive.  The haptics
subsystem will use the same driver as the joystick system does.

* Menu:

* ALLEGRO_JOYSTICK::
* ALLEGRO_JOYSTICK_STATE::
* ALLEGRO_JOYFLAGS::
* al_install_joystick::
* al_uninstall_joystick::
* al_is_joystick_installed::
* al_reconfigure_joysticks::
* al_get_num_joysticks::
* al_get_joystick::
* al_release_joystick::
* al_get_joystick_active::
* al_get_joystick_name::
* al_get_joystick_stick_name::
* al_get_joystick_axis_name::
* al_get_joystick_button_name::
* al_get_joystick_stick_flags::
* al_get_joystick_num_sticks::
* al_get_joystick_num_axes::
* al_get_joystick_num_buttons::
* al_get_joystick_state::
* al_get_joystick_event_source::


File: refman.info,  Node: ALLEGRO_JOYSTICK,  Next: ALLEGRO_JOYSTICK_STATE,  Up: Joystick routines

11.1 ALLEGRO_JOYSTICK
=====================

typedef struct ALLEGRO_JOYSTICK ALLEGRO_JOYSTICK;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/joystick.h#L35)

This is an abstract data type representing a physical joystick.

See also: *note al_get_joystick: #al_get_joystick.


File: refman.info,  Node: ALLEGRO_JOYSTICK_STATE,  Next: ALLEGRO_JOYFLAGS,  Prev: ALLEGRO_JOYSTICK,  Up: Joystick routines

11.2 ALLEGRO_JOYSTICK_STATE
===========================

typedef struct ALLEGRO_JOYSTICK_STATE ALLEGRO_JOYSTICK_STATE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/joystick.h#L41)

This is a structure that is used to hold a “snapshot” of a joystick’s
axes and buttons at a particular instant.  All fields public and
read-only.

struct {
   float axis[num_axes];             // -1.0 to 1.0
} stick[num_sticks];
int button[num_buttons];             // 0 to 32767

See also: *note al_get_joystick_state: #al_get_joystick_state.


File: refman.info,  Node: ALLEGRO_JOYFLAGS,  Next: al_install_joystick,  Prev: ALLEGRO_JOYSTICK_STATE,  Up: Joystick routines

11.3 ALLEGRO_JOYFLAGS
=====================

enum ALLEGRO_JOYFLAGS

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/joystick.h#L54)

   • ALLEGRO_JOYFLAG_DIGITAL - the stick provides digital input
   • ALLEGRO_JOYFLAG_ANALOGUE - the stick provides analogue input

(this enum is a holdover from the old API and may be removed)

See also: *note al_get_joystick_stick_flags:
#al_get_joystick_stick_flags.


File: refman.info,  Node: al_install_joystick,  Next: al_uninstall_joystick,  Prev: ALLEGRO_JOYFLAGS,  Up: Joystick routines

11.4 al_install_joystick
========================

bool al_install_joystick(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L40)

Install a joystick driver, returning true if successful.  If a joystick
driver was already installed, returns true immediately.

See also: *note al_uninstall_joystick: #al_uninstall_joystick.


File: refman.info,  Node: al_uninstall_joystick,  Next: al_is_joystick_installed,  Prev: al_install_joystick,  Up: Joystick routines

11.5 al_uninstall_joystick
==========================

void al_uninstall_joystick(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L73)

Uninstalls the active joystick driver.  All outstanding *note
ALLEGRO_JOYSTICK: #allegro_joystick. structures are invalidated.  If no
joystick driver was active, this function does nothing.

This function is automatically called when Allegro is shut down.

See also: *note al_install_joystick: #al_install_joystick.


File: refman.info,  Node: al_is_joystick_installed,  Next: al_reconfigure_joysticks,  Prev: al_uninstall_joystick,  Up: Joystick routines

11.6 al_is_joystick_installed
=============================

bool al_is_joystick_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L87)

Returns true if *note al_install_joystick: #al_install_joystick. was
called successfully.


File: refman.info,  Node: al_reconfigure_joysticks,  Next: al_get_num_joysticks,  Prev: al_is_joystick_installed,  Up: Joystick routines

11.7 al_reconfigure_joysticks
=============================

bool al_reconfigure_joysticks(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L96)

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 ‘ALLEGRO_EVENT_JOYSTICK_CONFIGURATION’
when a device is plugged in or unplugged.  In response, you should call
*note al_reconfigure_joysticks: #al_reconfigure_joysticks.

Afterwards, the number returned by *note al_get_num_joysticks:
#al_get_num_joysticks. may be different, and the handles returned by
*note al_get_joystick: #al_get_joystick. may be different or be ordered
differently.

All *note ALLEGRO_JOYSTICK: #allegro_joystick. handles remain valid, but
handles for disconnected devices become inactive: their states will no
longer update, and *note al_get_joystick: #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.

Returns true if the joystick configuration changed, otherwise returns
false.

It is possible that on some systems, Allegro won’t be able to generate
‘ALLEGRO_EVENT_JOYSTICK_CONFIGURATION’ events.  If your game has an
input configuration screen or similar, you may wish to call *note
al_reconfigure_joysticks: #al_reconfigure_joysticks. when entering that
screen.

See also: *note al_get_joystick_event_source:
#al_get_joystick_event_source, *note ALLEGRO_EVENT: #allegro_event.


File: refman.info,  Node: al_get_num_joysticks,  Next: al_get_joystick,  Prev: al_reconfigure_joysticks,  Up: Joystick routines

11.8 al_get_num_joysticks
=========================

int al_get_num_joysticks(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L138)

Return the number of joysticks currently on the system (or potentially
on the system).  This number can change after *note
al_reconfigure_joysticks: #al_reconfigure_joysticks. is called, in order
to support hotplugging.

Returns 0 if there is no joystick driver installed.

See also: *note al_get_joystick: #al_get_joystick, *note
al_get_joystick_active: #al_get_joystick_active.


File: refman.info,  Node: al_get_joystick,  Next: al_release_joystick,  Prev: al_get_num_joysticks,  Up: Joystick routines

11.9 al_get_joystick
====================

ALLEGRO_JOYSTICK * al_get_joystick(int num)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L150)

Get a handle for a joystick on the system.  The number may be from 0 to
*note al_get_num_joysticks: #al_get_num_joysticks.-1.  If successful a
pointer to a joystick object is returned, which represents a physical
device.  Otherwise NULL is returned.

The handle and the index are only incidentally linked.  After *note
al_reconfigure_joysticks: #al_reconfigure_joysticks. is called, *note
al_get_joystick: #al_get_joystick. may return handles in a different
order, and handles which represent disconnected devices will not be
returned.

See also: *note al_get_num_joysticks: #al_get_num_joysticks, *note
al_reconfigure_joysticks: #al_reconfigure_joysticks, *note
al_get_joystick_active: #al_get_joystick_active.


File: refman.info,  Node: al_release_joystick,  Next: al_get_joystick_active,  Prev: al_get_joystick,  Up: Joystick routines

11.10 al_release_joystick
=========================

void al_release_joystick(ALLEGRO_JOYSTICK *joy)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L162)

This function currently does nothing.

See also: *note al_get_joystick: #al_get_joystick.


File: refman.info,  Node: al_get_joystick_active,  Next: al_get_joystick_name,  Prev: al_release_joystick,  Up: Joystick routines

11.11 al_get_joystick_active
============================

bool al_get_joystick_active(ALLEGRO_JOYSTICK *joy)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L174)

Return if the joystick handle is “active”, i.e. in the current
configuration, the handle represents some physical device plugged into
the system.  *note al_get_joystick: #al_get_joystick. returns active
handles.  After reconfiguration, active handles may become inactive, and
vice versa.

See also: *note al_reconfigure_joysticks: #al_reconfigure_joysticks.


File: refman.info,  Node: al_get_joystick_name,  Next: al_get_joystick_stick_name,  Prev: al_get_joystick_active,  Up: Joystick routines

11.12 al_get_joystick_name
==========================

const char *al_get_joystick_name(ALLEGRO_JOYSTICK *joy)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L185)

Return the name of the given joystick.

See also: *note al_get_joystick_stick_name: #al_get_joystick_stick_name,
*note al_get_joystick_axis_name: #al_get_joystick_axis_name, *note
al_get_joystick_button_name: #al_get_joystick_button_name.


File: refman.info,  Node: al_get_joystick_stick_name,  Next: al_get_joystick_axis_name,  Prev: al_get_joystick_name,  Up: Joystick routines

11.13 al_get_joystick_stick_name
================================

const char *al_get_joystick_stick_name(ALLEGRO_JOYSTICK *joy, int stick)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L222)

Return the name of the given “stick”.  If the stick doesn’t exist, NULL
is returned.

See also: *note al_get_joystick_axis_name: #al_get_joystick_axis_name,
*note al_get_joystick_num_sticks: #al_get_joystick_num_sticks.


File: refman.info,  Node: al_get_joystick_axis_name,  Next: al_get_joystick_button_name,  Prev: al_get_joystick_stick_name,  Up: Joystick routines

11.14 al_get_joystick_axis_name
===============================

const char *al_get_joystick_axis_name(ALLEGRO_JOYSTICK *joy, int stick, int axis)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L251)

Return the name of the given axis.  If the axis doesn’t exist, NULL is
returned.  Indices begin from 0.

See also: *note al_get_joystick_stick_name: #al_get_joystick_stick_name,
*note al_get_joystick_num_axes: #al_get_joystick_num_axes.


File: refman.info,  Node: al_get_joystick_button_name,  Next: al_get_joystick_stick_flags,  Prev: al_get_joystick_axis_name,  Up: Joystick routines

11.15 al_get_joystick_button_name
=================================

const char *al_get_joystick_button_name(ALLEGRO_JOYSTICK *joy, int button)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L279)

Return the name of the given button.  If the button doesn’t exist, NULL
is returned.  Indices begin from 0.

See also: *note al_get_joystick_stick_name: #al_get_joystick_stick_name,
*note al_get_joystick_axis_name: #al_get_joystick_axis_name, *note
al_get_joystick_num_buttons: #al_get_joystick_num_buttons.


File: refman.info,  Node: al_get_joystick_stick_flags,  Next: al_get_joystick_num_sticks,  Prev: al_get_joystick_button_name,  Up: Joystick routines

11.16 al_get_joystick_stick_flags
=================================

int al_get_joystick_stick_flags(ALLEGRO_JOYSTICK *joy, int stick)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L207)

Return the flags of the given “stick”.  If the stick doesn’t exist, NULL
is returned.  Indices begin from 0.

See also: *note ALLEGRO_JOYFLAGS: #allegro_joyflags.


File: refman.info,  Node: al_get_joystick_num_sticks,  Next: al_get_joystick_num_axes,  Prev: al_get_joystick_stick_flags,  Up: Joystick routines

11.17 al_get_joystick_num_sticks
================================

int al_get_joystick_num_sticks(ALLEGRO_JOYSTICK *joy)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L196)

Return the number of “sticks” on the given joystick.  A stick has one or
more axes.

See also: *note al_get_joystick_num_axes: #al_get_joystick_num_axes,
*note al_get_joystick_num_buttons: #al_get_joystick_num_buttons.


File: refman.info,  Node: al_get_joystick_num_axes,  Next: al_get_joystick_num_buttons,  Prev: al_get_joystick_num_sticks,  Up: Joystick routines

11.18 al_get_joystick_num_axes
==============================

int al_get_joystick_num_axes(ALLEGRO_JOYSTICK *joy, int stick)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L237)

Return the number of axes on the given “stick”.  If the stick doesn’t
exist, 0 is returned.

See also: *note al_get_joystick_num_sticks: #al_get_joystick_num_sticks.


File: refman.info,  Node: al_get_joystick_num_buttons,  Next: al_get_joystick_state,  Prev: al_get_joystick_num_axes,  Up: Joystick routines

11.19 al_get_joystick_num_buttons
=================================

int al_get_joystick_num_buttons(ALLEGRO_JOYSTICK *joy)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L268)

Return the number of buttons on the joystick.

See also: *note al_get_joystick_num_sticks: #al_get_joystick_num_sticks.


File: refman.info,  Node: al_get_joystick_state,  Next: al_get_joystick_event_source,  Prev: al_get_joystick_num_buttons,  Up: Joystick routines

11.20 al_get_joystick_state
===========================

void al_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STATE *ret_state)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L294)

Get the current joystick state.

See also: *note ALLEGRO_JOYSTICK_STATE: #allegro_joystick_state, *note
al_get_joystick_num_buttons: #al_get_joystick_num_buttons, *note
al_get_joystick_num_axes: #al_get_joystick_num_axes.


File: refman.info,  Node: al_get_joystick_event_source,  Prev: al_get_joystick_state,  Up: Joystick routines

11.21 al_get_joystick_event_source
==================================

ALLEGRO_EVENT_SOURCE *al_get_joystick_event_source(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/joynu.c#L114)

Returns the global joystick event source.  All *note joystick events:
#allegro_event_joystick_axis. are generated by this event source.


File: refman.info,  Node: Keyboard routines,  Next: Memory management routines,  Prev: Joystick routines,  Up: Top

12 Keyboard routines
********************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_KEYBOARD_STATE::
* Key codes::
* Keyboard modifier flags::
* al_install_keyboard::
* al_is_keyboard_installed::
* al_uninstall_keyboard::
* al_get_keyboard_state::
* al_clear_keyboard_state::
* al_key_down::
* al_keycode_to_name::
* al_set_keyboard_leds::
* al_get_keyboard_event_source::


File: refman.info,  Node: ALLEGRO_KEYBOARD_STATE,  Next: Key codes,  Up: Keyboard routines

12.1 ALLEGRO_KEYBOARD_STATE
===========================

typedef struct ALLEGRO_KEYBOARD_STATE ALLEGRO_KEYBOARD_STATE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/keyboard.h#L33)

This is a structure that is used to hold a “snapshot” of a keyboard’s
state at a particular instant.  It contains the following publically
readable fields:

   • display - points to the display that had keyboard focus at the time
     the state was saved.  If no display was focused, this points to
     NULL.

You cannot read the state of keys directly.  Use the function *note
al_key_down: #al_key_down.


File: refman.info,  Node: Key codes,  Next: Keyboard modifier flags,  Prev: ALLEGRO_KEYBOARD_STATE,  Up: Keyboard routines

12.2 Key codes
==============

The constant ALLEGRO_KEY_MAX is always one higher than the highest key
code.  So if you want to use the key code as array index you can do
something like this:

bool pressed_keys[ALLEGRO_KEY_MAX];
//...
pressed_keys[key_code] = true;

These are the list of key codes used by Allegro, which are returned in
the event.keyboard.keycode field of the ALLEGRO_KEY_DOWN and
ALLEGRO_KEY_UP events and which you can pass to *note al_key_down:
#al_key_down.:

ALLEGRO_KEY_A ... ALLEGRO_KEY_Z
ALLEGRO_KEY_0 ... ALLEGRO_KEY_9
ALLEGRO_KEY_PAD_0 ... ALLEGRO_KEY_PAD_9
ALLEGRO_KEY_F1 ... ALLEGRO_KEY_F12
ALLEGRO_KEY_ESCAPE
ALLEGRO_KEY_TILDE
ALLEGRO_KEY_MINUS
ALLEGRO_KEY_EQUALS
ALLEGRO_KEY_BACKSPACE
ALLEGRO_KEY_TAB
ALLEGRO_KEY_OPENBRACE
ALLEGRO_KEY_CLOSEBRACE
ALLEGRO_KEY_ENTER
ALLEGRO_KEY_SEMICOLON
ALLEGRO_KEY_QUOTE
ALLEGRO_KEY_BACKSLASH
ALLEGRO_KEY_BACKSLASH2
ALLEGRO_KEY_COMMA
ALLEGRO_KEY_FULLSTOP
ALLEGRO_KEY_SLASH
ALLEGRO_KEY_SPACE
ALLEGRO_KEY_INSERT
ALLEGRO_KEY_DELETE
ALLEGRO_KEY_HOME
ALLEGRO_KEY_END
ALLEGRO_KEY_PGUP
ALLEGRO_KEY_PGDN
ALLEGRO_KEY_LEFT
ALLEGRO_KEY_RIGHT
ALLEGRO_KEY_UP
ALLEGRO_KEY_DOWN
ALLEGRO_KEY_PAD_SLASH
ALLEGRO_KEY_PAD_ASTERISK
ALLEGRO_KEY_PAD_MINUS
ALLEGRO_KEY_PAD_PLUS
ALLEGRO_KEY_PAD_DELETE
ALLEGRO_KEY_PAD_ENTER
ALLEGRO_KEY_PRINTSCREEN
ALLEGRO_KEY_PAUSE
ALLEGRO_KEY_ABNT_C1
ALLEGRO_KEY_YEN
ALLEGRO_KEY_KANA
ALLEGRO_KEY_CONVERT
ALLEGRO_KEY_NOCONVERT
ALLEGRO_KEY_AT
ALLEGRO_KEY_CIRCUMFLEX
ALLEGRO_KEY_COLON2
ALLEGRO_KEY_KANJI
ALLEGRO_KEY_LSHIFT
ALLEGRO_KEY_RSHIFT
ALLEGRO_KEY_LCTRL
ALLEGRO_KEY_RCTRL
ALLEGRO_KEY_ALT
ALLEGRO_KEY_ALTGR
ALLEGRO_KEY_LWIN
ALLEGRO_KEY_RWIN
ALLEGRO_KEY_MENU
ALLEGRO_KEY_SCROLLLOCK
ALLEGRO_KEY_NUMLOCK
ALLEGRO_KEY_CAPSLOCK
ALLEGRO_KEY_PAD_EQUALS
ALLEGRO_KEY_BACKQUOTE
ALLEGRO_KEY_SEMICOLON2
ALLEGRO_KEY_COMMAND

/* Since: 5.1.1 */
/* Android only for now */
ALLEGRO_KEY_BACK

/* Since: 5.1.2 */
/* Android only for now */
ALLEGRO_KEY_VOLUME_UP
ALLEGRO_KEY_VOLUME_DOWN

/* Since: 5.1.6 */
/* Android only for now */
ALLEGRO_KEY_SEARCH
ALLEGRO_KEY_DPAD_CENTER
ALLEGRO_KEY_BUTTON_X
ALLEGRO_KEY_BUTTON_Y
ALLEGRO_KEY_DPAD_UP
ALLEGRO_KEY_DPAD_DOWN
ALLEGRO_KEY_DPAD_LEFT
ALLEGRO_KEY_DPAD_RIGHT
ALLEGRO_KEY_SELECT
ALLEGRO_KEY_START
ALLEGRO_KEY_L1
ALLEGRO_KEY_R1


File: refman.info,  Node: Keyboard modifier flags,  Next: al_install_keyboard,  Prev: Key codes,  Up: Keyboard routines

12.3 Keyboard modifier flags
============================

ALLEGRO_KEYMOD_SHIFT
ALLEGRO_KEYMOD_CTRL
ALLEGRO_KEYMOD_ALT
ALLEGRO_KEYMOD_LWIN
ALLEGRO_KEYMOD_RWIN
ALLEGRO_KEYMOD_MENU
ALLEGRO_KEYMOD_ALTGR
ALLEGRO_KEYMOD_COMMAND
ALLEGRO_KEYMOD_SCROLLLOCK
ALLEGRO_KEYMOD_NUMLOCK
ALLEGRO_KEYMOD_CAPSLOCK
ALLEGRO_KEYMOD_INALTSEQ
ALLEGRO_KEYMOD_ACCENT1
ALLEGRO_KEYMOD_ACCENT2
ALLEGRO_KEYMOD_ACCENT3
ALLEGRO_KEYMOD_ACCENT4

The event field ‘keyboard.modifiers’ is a bitfield composed of these
constants.  These indicate the modifier keys which were pressed at the
time a character was typed.


File: refman.info,  Node: al_install_keyboard,  Next: al_is_keyboard_installed,  Prev: Keyboard modifier flags,  Up: Keyboard routines

12.4 al_install_keyboard
========================

bool al_install_keyboard(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L121)

Install a keyboard driver.  Returns true if successful.  If a driver was
already installed, nothing happens and true is returned.

See also: *note al_uninstall_keyboard: #al_uninstall_keyboard, *note
al_is_keyboard_installed: #al_is_keyboard_installed.


File: refman.info,  Node: al_is_keyboard_installed,  Next: al_uninstall_keyboard,  Prev: al_install_keyboard,  Up: Keyboard routines

12.5 al_is_keyboard_installed
=============================

bool al_is_keyboard_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L112)

Returns true if *note al_install_keyboard: #al_install_keyboard. was
called successfully.


File: refman.info,  Node: al_uninstall_keyboard,  Next: al_get_keyboard_state,  Prev: al_is_keyboard_installed,  Up: Keyboard routines

12.6 al_uninstall_keyboard
==========================

void al_uninstall_keyboard(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L172)

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.

See also: *note al_install_keyboard: #al_install_keyboard.


File: refman.info,  Node: al_get_keyboard_state,  Next: al_clear_keyboard_state,  Prev: al_uninstall_keyboard,  Up: Keyboard routines

12.7 al_get_keyboard_state
==========================

void al_get_keyboard_state(ALLEGRO_KEYBOARD_STATE *ret_state)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L239)

Save the state of the keyboard specified at the time the function is
called into the structure pointed to by _ret_state_.

See also: *note al_key_down: #al_key_down, *note
al_clear_keyboard_state: #al_clear_keyboard_state, *note
ALLEGRO_KEYBOARD_STATE: #allegro_keyboard_state.


File: refman.info,  Node: al_clear_keyboard_state,  Next: al_key_down,  Prev: al_get_keyboard_state,  Up: Keyboard routines

12.8 al_clear_keyboard_state
============================

void al_clear_keyboard_state(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L251)

Clear the state of the keyboard, emitting *note ALLEGRO_EVENT_KEY_UP:
#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 NULL 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
*note ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
#allegro_event_display_switch_out. events.

See also: *note al_get_keyboard_state: #al_get_keyboard_state, *note
ALLEGRO_KEYBOARD_STATE: #allegro_keyboard_state.

Since: 5.2.3

     _*note Unstable API: #unstable-api.:_ This is a new feature and the
     exact semantics are still being decided upon.


File: refman.info,  Node: al_key_down,  Next: al_keycode_to_name,  Prev: al_clear_keyboard_state,  Up: Keyboard routines

12.9 al_key_down
================

bool al_key_down(const ALLEGRO_KEYBOARD_STATE *state, int keycode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L284)

Return true if the key specified was held down in the state specified.

See also: *note ALLEGRO_KEYBOARD_STATE: #allegro_keyboard_state.


File: refman.info,  Node: al_keycode_to_name,  Next: al_set_keyboard_leds,  Prev: al_key_down,  Up: Keyboard routines

12.10 al_keycode_to_name
========================

const char *al_keycode_to_name(int keycode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L217)

Converts the given keycode to a description of the key.


File: refman.info,  Node: al_set_keyboard_leds,  Next: al_get_keyboard_event_source,  Prev: al_keycode_to_name,  Up: Keyboard routines

12.11 al_set_keyboard_leds
==========================

bool al_set_keyboard_leds(int leds)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L203)

Overrides the state of the keyboard LED indicators.  Set ‘leds’ to a
combination of the keyboard modifier flags to enable the corresponding
LED indicators (‘ALLEGRO_KEYMOD_NUMLOCK’, ‘ALLEGRO_KEYMOD_CAPSLOCK’ and
‘ALLEGRO_KEYMOD_SCROLLLOCK’ are supported) or to -1 to return to default
behavior.  False is returned if the current keyboard driver cannot set
LED indicators.


File: refman.info,  Node: al_get_keyboard_event_source,  Prev: al_set_keyboard_leds,  Up: Keyboard routines

12.12 al_get_keyboard_event_source
==================================

ALLEGRO_EVENT_SOURCE *al_get_keyboard_event_source(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/keybdnu.c#L293)

Retrieve the keyboard event source.  All *note keyboard events:
#allegro_event_key_down. are generated by this event source.

Returns NULL if the keyboard subsystem was not installed.


File: refman.info,  Node: Memory management routines,  Next: Miscellaneous routines,  Prev: Keyboard routines,  Up: Top

13 Memory management routines
*****************************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* al_malloc::
* al_free::
* al_realloc::
* al_calloc::
* al_malloc_with_context::
* al_free_with_context::
* al_realloc_with_context::
* al_calloc_with_context::
* ALLEGRO_MEMORY_INTERFACE::
* al_set_memory_interface::


File: refman.info,  Node: al_malloc,  Next: al_free,  Up: Memory management routines

13.1 al_malloc
==============

#define al_malloc(n) \
   (al_malloc_with_context((n), __LINE__, __FILE__, __func__))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/memory.h#L42)

Like malloc() in the C standard library, but the implementation may be
overridden.

This is a macro.

See also: *note al_free: #al_free, *note al_realloc: #al_realloc, *note
al_calloc: #al_calloc, *note al_malloc_with_context:
#al_malloc_with_context, *note al_set_memory_interface:
#al_set_memory_interface.


File: refman.info,  Node: al_free,  Next: al_realloc,  Prev: al_malloc,  Up: Memory management routines

13.2 al_free
============

#define al_free(p) \
   (al_free_with_context((p), __LINE__, __FILE__, __func__))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/memory.h#L47)

Like free() in the C standard library, but the implementation may be
overridden.

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 must be freed, you must use *note al_free:
#al_free. for portability to Windows.

This is a macro.

See also: *note al_malloc: #al_malloc, *note al_free_with_context:
#al_free_with_context.


File: refman.info,  Node: al_realloc,  Next: al_calloc,  Prev: al_free,  Up: Memory management routines

13.3 al_realloc
===============

#define al_realloc(p, n) \
   (al_realloc_with_context((p), (n), __LINE__, __FILE__, __func__))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/memory.h#L52)

Like realloc() in the C standard library, but the implementation may be
overridden.

This is a macro.

See also: *note al_malloc: #al_malloc, *note al_realloc_with_context:
#al_realloc_with_context.


File: refman.info,  Node: al_calloc,  Next: al_malloc_with_context,  Prev: al_realloc,  Up: Memory management routines

13.4 al_calloc
==============

#define al_calloc(c, n) \
   (al_calloc_with_context((c), (n), __LINE__, __FILE__, __func__))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/memory.h#L57)

Like calloc() in the C standard library, but the implementation may be
overridden.

This is a macro.

See also: *note al_malloc: #al_malloc, *note al_calloc_with_context:
#al_calloc_with_context.


File: refman.info,  Node: al_malloc_with_context,  Next: al_free_with_context,  Prev: al_calloc,  Up: Memory management routines

13.5 al_malloc_with_context
===========================

void *al_malloc_with_context(size_t n,
   int line, const char *file, const char *func)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/memory.c#L38)

This calls malloc() from the Allegro library (this matters on Windows),
unless overridden with *note al_set_memory_interface:
#al_set_memory_interface,

Generally you should use the *note al_malloc: #al_malloc. macro.


File: refman.info,  Node: al_free_with_context,  Next: al_realloc_with_context,  Prev: al_malloc_with_context,  Up: Memory management routines

13.6 al_free_with_context
=========================

void al_free_with_context(void *ptr,
   int line, const char *file, const char *func)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/memory.c#L51)

This calls free() from the Allegro library (this matters on Windows),
unless overridden with *note al_set_memory_interface:
#al_set_memory_interface.

Generally you should use the *note al_free: #al_free. macro.


File: refman.info,  Node: al_realloc_with_context,  Next: al_calloc_with_context,  Prev: al_free_with_context,  Up: Memory management routines

13.7 al_realloc_with_context
============================

void *al_realloc_with_context(void *ptr, size_t n,
   int line, const char *file, const char *func)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/memory.c#L64)

This calls realloc() from the Allegro library (this matters on Windows),
unless overridden with *note al_set_memory_interface:
#al_set_memory_interface,

Generally you should use the *note al_realloc: #al_realloc. macro.


File: refman.info,  Node: al_calloc_with_context,  Next: ALLEGRO_MEMORY_INTERFACE,  Prev: al_realloc_with_context,  Up: Memory management routines

13.8 al_calloc_with_context
===========================

void *al_calloc_with_context(size_t count, size_t n,
   int line, const char *file, const char *func)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/memory.c#L77)

This calls calloc() from the Allegro library (this matters on Windows),
unless overridden with *note al_set_memory_interface:
#al_set_memory_interface,

Generally you should use the *note al_calloc: #al_calloc. macro.


File: refman.info,  Node: ALLEGRO_MEMORY_INTERFACE,  Next: al_set_memory_interface,  Prev: al_calloc_with_context,  Up: Memory management routines

13.9 ALLEGRO_MEMORY_INTERFACE
=============================

typedef struct ALLEGRO_MEMORY_INTERFACE ALLEGRO_MEMORY_INTERFACE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/memory.h#L28)

This structure has the following fields.

void *(*mi_malloc)(size_t n, int line, const char *file, const char *func);
void (*mi_free)(void *ptr, int line, const char *file, const char *func);
void *(*mi_realloc)(void *ptr, size_t n, int line, const char *file,
                    const char *func);
void *(*mi_calloc)(size_t count, size_t n, int line, const char *file,
                   const char *func);

See also: *note al_set_memory_interface: #al_set_memory_interface.


File: refman.info,  Node: al_set_memory_interface,  Prev: ALLEGRO_MEMORY_INTERFACE,  Up: Memory management routines

13.10 al_set_memory_interface
=============================

void al_set_memory_interface(ALLEGRO_MEMORY_INTERFACE *memory_interface)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/memory.c#L29)

Override the memory management functions with implementations of *note
al_malloc_with_context: #al_malloc_with_context, *note
al_free_with_context: #al_free_with_context, *note
al_realloc_with_context: #al_realloc_with_context. and *note
al_calloc_with_context: #al_calloc_with_context.  The context arguments
may be used for debugging.  The new functions should be thread safe.

If the pointer is NULL, the default behaviour will be restored.

See also: *note ALLEGRO_MEMORY_INTERFACE: #allegro_memory_interface.


File: refman.info,  Node: Miscellaneous routines,  Next: Monitors,  Prev: Memory management routines,  Up: Top

14 Miscellaneous routines
*************************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_PI::
* al_run_main::


File: refman.info,  Node: ALLEGRO_PI,  Next: al_run_main,  Up: Miscellaneous routines

14.1 ALLEGRO_PI
===============

#define ALLEGRO_PI        3.14159265358979323846

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/base.h#L96)

C99 compilers have no predefined value like M_PI for the constant π, but
you can use this one instead.


File: refman.info,  Node: al_run_main,  Prev: ALLEGRO_PI,  Up: Miscellaneous routines

14.2 al_run_main
================

int al_run_main(int argc, char **argv, int (*user_main)(int, char **))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/allegro.c#L36)

This function is useful in cases where you don’t have a 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 *note
al_install_system: #al_install_system.  But some other system (like OSX)
don’t allow calling *note al_install_system: #al_install_system. in the
main thread.  al_run_main will know what to do in that case.

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


File: refman.info,  Node: Monitors,  Next: Mouse routines,  Prev: Miscellaneous routines,  Up: Top

15 Monitors
***********

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_MONITOR_INFO::
* al_get_new_display_adapter::
* al_set_new_display_adapter::
* al_get_monitor_info::
* al_get_monitor_dpi::
* al_get_num_video_adapters::
* al_get_monitor_refresh_rate::


File: refman.info,  Node: ALLEGRO_MONITOR_INFO,  Next: al_get_new_display_adapter,  Up: Monitors

15.1 ALLEGRO_MONITOR_INFO
=========================

typedef struct ALLEGRO_MONITOR_INFO

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/monitor.h#L13)

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

typedef struct ALLEGRO_MONITOR_INFO
{
   int x1;
   int y1;
   int x2;
   int y2;
} ALLEGRO_MONITOR_INFO;

See also: *note al_get_monitor_info: #al_get_monitor_info.


File: refman.info,  Node: al_get_new_display_adapter,  Next: al_set_new_display_adapter,  Prev: ALLEGRO_MONITOR_INFO,  Up: Monitors

15.2 al_get_new_display_adapter
===============================

int al_get_new_display_adapter(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L317)

Gets the video adapter index where new displays will be created by the
calling thread, if previously set with *note al_set_new_display_adapter:
#al_set_new_display_adapter.  Otherwise returns
‘ALLEGRO_DEFAULT_DISPLAY_ADAPTER’.

See also: *note al_set_new_display_adapter: #al_set_new_display_adapter.


File: refman.info,  Node: al_set_new_display_adapter,  Next: al_get_monitor_info,  Prev: al_get_new_display_adapter,  Up: Monitors

15.3 al_set_new_display_adapter
===============================

void al_set_new_display_adapter(int adapter)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L300)

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 *note al_get_num_video_adapters:
#al_get_num_video_adapters. and *note al_get_monitor_info:
#al_get_monitor_info.

To return to the default behaviour, pass
‘ALLEGRO_DEFAULT_DISPLAY_ADAPTER’.

See also: *note al_get_num_video_adapters: #al_get_num_video_adapters,
*note al_get_monitor_info: #al_get_monitor_info.


File: refman.info,  Node: al_get_monitor_info,  Next: al_get_monitor_dpi,  Prev: al_set_new_display_adapter,  Up: Monitors

15.4 al_get_monitor_info
========================

bool al_get_monitor_info(int adapter, ALLEGRO_MONITOR_INFO *info)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/monitor.c#L52)

Get information about a monitor’s position on the desktop.  adapter is a
number from 0 to al_get_num_video_adapters()-1.

On Windows, use *note al_set_new_display_flags:
#al_set_new_display_flags. to switch between Direct3D and OpenGL
backends, which will often have different adapters available.

Returns ‘true’ on success, ‘false’ on failure.

See also: *note ALLEGRO_MONITOR_INFO: #allegro_monitor_info, *note
al_get_num_video_adapters: #al_get_num_video_adapters.


File: refman.info,  Node: al_get_monitor_dpi,  Next: al_get_num_video_adapters,  Prev: al_get_monitor_info,  Up: Monitors

15.5 al_get_monitor_dpi
=======================

int al_get_monitor_dpi(int adapter)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/monitor.c#L68)

Get the dots per inch of a monitor attached to the display adapter.

Since: 5.2.5

See also: *note al_get_num_video_adapters: #al_get_num_video_adapters.


File: refman.info,  Node: al_get_num_video_adapters,  Next: al_get_monitor_refresh_rate,  Prev: al_get_monitor_dpi,  Up: Monitors

15.6 al_get_num_video_adapters
==============================

int al_get_num_video_adapters(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/monitor.c#L23)

Get 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 *note al_set_new_display_flags:
#al_set_new_display_flags. to switch between Direct3D and OpenGL
backends, which will often have different adapters available.

See also: *note al_get_monitor_info: #al_get_monitor_info.


File: refman.info,  Node: al_get_monitor_refresh_rate,  Prev: al_get_num_video_adapters,  Up: Monitors

15.7 al_get_monitor_refresh_rate
================================

int al_get_monitor_refresh_rate(int adapter)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/monitor.c#L36)

Returns the current refresh rate of a monitor attached to the display
adapter.

Since: 5.2.6

     _*note Unstable API: #unstable-api.:_ This is an experimental
     feature and currently only works on Windows.
See also: *note al_get_monitor_info: #al_get_monitor_info.


File: refman.info,  Node: Mouse routines,  Next: Path structures,  Prev: Monitors,  Up: Top

16 Mouse routines
*****************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_MOUSE_STATE::
* al_install_mouse::
* al_is_mouse_installed::
* al_uninstall_mouse::
* al_get_mouse_num_axes::
* al_get_mouse_num_buttons::
* al_get_mouse_state::
* al_get_mouse_state_axis::
* al_mouse_button_down::
* al_set_mouse_xy::
* al_set_mouse_z::
* al_set_mouse_w::
* al_set_mouse_axis::
* al_get_mouse_event_source::
* al_set_mouse_wheel_precision::
* al_get_mouse_wheel_precision::
* Mouse cursors::


File: refman.info,  Node: ALLEGRO_MOUSE_STATE,  Next: al_install_mouse,  Up: Mouse routines

16.1 ALLEGRO_MOUSE_STATE
========================

typedef struct ALLEGRO_MOUSE_STATE ALLEGRO_MOUSE_STATE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/mouse.h#L35)

Public fields (read only):

   • x - mouse x position

   • y - mouse y position

   • w, z - mouse wheel position (2D ‘ball’)

   • 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.

   • pressure - pressure, ranging from ‘0.0’ to ‘1.0’

See also: *note al_get_mouse_state: #al_get_mouse_state, *note
al_get_mouse_state_axis: #al_get_mouse_state_axis, *note
al_mouse_button_down: #al_mouse_button_down.


File: refman.info,  Node: al_install_mouse,  Next: al_is_mouse_installed,  Prev: ALLEGRO_MOUSE_STATE,  Up: Mouse routines

16.2 al_install_mouse
=====================

bool al_install_mouse(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L49)

Install a mouse driver.

Returns true if successful.  If a driver was already installed, nothing
happens and true is returned.


File: refman.info,  Node: al_is_mouse_installed,  Next: al_uninstall_mouse,  Prev: al_install_mouse,  Up: Mouse routines

16.3 al_is_mouse_installed
==========================

bool al_is_mouse_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L40)

Returns true if *note al_install_mouse: #al_install_mouse. was called
successfully.


File: refman.info,  Node: al_uninstall_mouse,  Next: al_get_mouse_num_axes,  Prev: al_is_mouse_installed,  Up: Mouse routines

16.4 al_uninstall_mouse
=======================

void al_uninstall_mouse(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L104)

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.


File: refman.info,  Node: al_get_mouse_num_axes,  Next: al_get_mouse_num_buttons,  Prev: al_uninstall_mouse,  Up: Mouse routines

16.5 al_get_mouse_num_axes
==========================

unsigned int al_get_mouse_num_axes(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L145)

Return the number of axes on the mouse.  The first axis is 0.

See also: *note al_get_mouse_num_buttons: #al_get_mouse_num_buttons.


File: refman.info,  Node: al_get_mouse_num_buttons,  Next: al_get_mouse_state,  Prev: al_get_mouse_num_axes,  Up: Mouse routines

16.6 al_get_mouse_num_buttons
=============================

unsigned int al_get_mouse_num_buttons(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L134)

Return the number of buttons on the mouse.  The first button is 1.

See also: *note al_get_mouse_num_axes: #al_get_mouse_num_axes.


File: refman.info,  Node: al_get_mouse_state,  Next: al_get_mouse_state_axis,  Prev: al_get_mouse_num_buttons,  Up: Mouse routines

16.7 al_get_mouse_state
=======================

void al_get_mouse_state(ALLEGRO_MOUSE_STATE *ret_state)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L209)

Save the state of the mouse specified at the time the function is called
into the given structure.

Example:

ALLEGRO_MOUSE_STATE state;

al_get_mouse_state(&state);
if (state.buttons & 1) {
    /* Primary (e.g. left) mouse button is held. */
    printf("Mouse position: (%d, %d)\n", state.x, state.y);
}
if (state.buttons & 2) {
    /* Secondary (e.g. right) mouse button is held. */
}
if (state.buttons & 4) {
    /* Tertiary (e.g. middle) mouse button is held. */
}

See also: *note ALLEGRO_MOUSE_STATE: #allegro_mouse_state, *note
al_get_mouse_state_axis: #al_get_mouse_state_axis, *note
al_mouse_button_down: #al_mouse_button_down.


File: refman.info,  Node: al_get_mouse_state_axis,  Next: al_mouse_button_down,  Prev: al_get_mouse_state,  Up: Mouse routines

16.8 al_get_mouse_state_axis
============================

int al_get_mouse_state_axis(const ALLEGRO_MOUSE_STATE *state, int axis)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L221)

Extract 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.

See also: *note ALLEGRO_MOUSE_STATE: #allegro_mouse_state, *note
al_get_mouse_state: #al_get_mouse_state, *note al_mouse_button_down:
#al_mouse_button_down.


File: refman.info,  Node: al_mouse_button_down,  Next: al_set_mouse_xy,  Prev: al_get_mouse_state_axis,  Up: Mouse routines

16.9 al_mouse_button_down
=========================

bool al_mouse_button_down(const ALLEGRO_MOUSE_STATE *state, int button)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L245)

Return true if the mouse button specified was held down in the state
specified.  Unlike most things, the first mouse button is numbered 1.

See also: *note ALLEGRO_MOUSE_STATE: #allegro_mouse_state, *note
al_get_mouse_state: #al_get_mouse_state, *note al_get_mouse_state_axis:
#al_get_mouse_state_axis.


File: refman.info,  Node: al_set_mouse_xy,  Next: al_set_mouse_z,  Prev: al_mouse_button_down,  Up: Mouse routines

16.10 al_set_mouse_xy
=====================

bool al_set_mouse_xy(ALLEGRO_DISPLAY *display, int x, int y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L156)

Try to position the mouse at the given coordinates on the given display.
The mouse movement resulting from a successful move will generate an
*note ALLEGRO_EVENT_MOUSE_WARPED: #allegro_event_mouse_warped. event.

Returns true on success, false on failure.

See also: *note al_set_mouse_z: #al_set_mouse_z, *note al_set_mouse_w:
#al_set_mouse_w.


File: refman.info,  Node: al_set_mouse_z,  Next: al_set_mouse_w,  Prev: al_set_mouse_xy,  Up: Mouse routines

16.11 al_set_mouse_z
====================

bool al_set_mouse_z(int z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L168)

Set the mouse wheel position to the given value.

Returns true on success, false on failure.

See also: *note al_set_mouse_w: #al_set_mouse_w.


File: refman.info,  Node: al_set_mouse_w,  Next: al_set_mouse_axis,  Prev: al_set_mouse_z,  Up: Mouse routines

16.12 al_set_mouse_w
====================

bool al_set_mouse_w(int w)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L180)

Set the second mouse wheel position to the given value.

Returns true on success, false on failure.

See also: *note al_set_mouse_z: #al_set_mouse_z.


File: refman.info,  Node: al_set_mouse_axis,  Next: al_get_mouse_event_source,  Prev: al_set_mouse_w,  Up: Mouse routines

16.13 al_set_mouse_axis
=======================

bool al_set_mouse_axis(int which, int value)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L192)

Set 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
*note al_set_mouse_xy: #al_set_mouse_xy. for that.

Returns true on success, false on failure.

See also: *note al_set_mouse_xy: #al_set_mouse_xy, *note al_set_mouse_z:
#al_set_mouse_z, *note al_set_mouse_w: #al_set_mouse_w.


File: refman.info,  Node: al_get_mouse_event_source,  Next: al_set_mouse_wheel_precision,  Prev: al_set_mouse_axis,  Up: Mouse routines

16.14 al_get_mouse_event_source
===============================

ALLEGRO_EVENT_SOURCE *al_get_mouse_event_source(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L305)

Retrieve the mouse event source.  All *note mouse events:
#allegro_event_mouse_axes. are generated by this event source.

Returns NULL if the mouse subsystem was not installed.


File: refman.info,  Node: al_set_mouse_wheel_precision,  Next: al_get_mouse_wheel_precision,  Prev: al_get_mouse_event_source,  Up: Mouse routines

16.15 al_set_mouse_wheel_precision
==================================

void al_set_mouse_wheel_precision(int precision)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L316)

Sets the precision of the mouse wheel (the z and w coordinates).  This
precision manifests itself as a multiplier on the ‘dz’ and ‘dw’ fields
in mouse events.  It also affects the ‘z’ and ‘w’ fields of events and
*note ALLEGRO_MOUSE_STATE: #allegro_mouse_state, but not in a simple way
if you alter the precision often, so it is suggested to reset those axes
to 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 ‘dz’ and ‘dw’ like so:

al_set_mouse_wheel_precision(120);

ALLEGRO_EVENT event;
al_wait_for_event(event_queue, &event);
if (event.type == ALLEGRO_EVENT_MOUSE_AXES) {
  double dz = (double)event.mouse.dz / al_get_mouse_wheel_precision();
  /* Use dz in some way... */
}

Precision is set to 1 by default.  It is impossible to set it to a lower
precision than that.

Since: 5.1.10

See also: *note al_get_mouse_wheel_precision:
#al_get_mouse_wheel_precision.


File: refman.info,  Node: al_get_mouse_wheel_precision,  Next: Mouse cursors,  Prev: al_set_mouse_wheel_precision,  Up: Mouse routines

16.16 al_get_mouse_wheel_precision
==================================

int al_get_mouse_wheel_precision(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L329)

Gets the precision of the mouse wheel (the z and w coordinates).

Since: 5.1.10

See also: *note al_set_mouse_wheel_precision:
#al_set_mouse_wheel_precision.


File: refman.info,  Node: Mouse cursors,  Prev: al_get_mouse_wheel_precision,  Up: Mouse routines

16.17 Mouse cursors
===================

* Menu:

* al_create_mouse_cursor::
* al_destroy_mouse_cursor::
* al_set_mouse_cursor::
* al_set_system_mouse_cursor::
* al_get_mouse_cursor_position::
* al_hide_mouse_cursor::
* al_show_mouse_cursor::
* al_grab_mouse::
* al_ungrab_mouse::


File: refman.info,  Node: al_create_mouse_cursor,  Next: al_destroy_mouse_cursor,  Up: Mouse cursors

16.17.1 al_create_mouse_cursor
------------------------------

ALLEGRO_MOUSE_CURSOR *al_create_mouse_cursor(ALLEGRO_BITMAP *bmp,
   int x_focus, int y_focus)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mouse_cursor.c#L24)

Create a mouse cursor from the bitmap provided.  ‘x_focus’ and ‘y_focus’
describe the bit of the cursor that will represent the actual mouse
position.

Returns a pointer to the cursor on success, or NULL on failure.

See also: *note al_set_mouse_cursor: #al_set_mouse_cursor, *note
al_destroy_mouse_cursor: #al_destroy_mouse_cursor.


File: refman.info,  Node: al_destroy_mouse_cursor,  Next: al_set_mouse_cursor,  Prev: al_create_mouse_cursor,  Up: Mouse cursors

16.17.2 al_destroy_mouse_cursor
-------------------------------

void al_destroy_mouse_cursor(ALLEGRO_MOUSE_CURSOR *cursor)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mouse_cursor.c#L37)

Free the memory used by the given cursor.

Has no effect if ‘cursor’ is NULL.

See also: *note al_create_mouse_cursor: #al_create_mouse_cursor.


File: refman.info,  Node: al_set_mouse_cursor,  Next: al_set_system_mouse_cursor,  Prev: al_destroy_mouse_cursor,  Up: Mouse cursors

16.17.3 al_set_mouse_cursor
---------------------------

bool al_set_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mouse_cursor.c#L54)

Set 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.

Returns true on success, false on failure.

See also: *note al_set_system_mouse_cursor: #al_set_system_mouse_cursor,
*note al_show_mouse_cursor: #al_show_mouse_cursor, *note
al_hide_mouse_cursor: #al_hide_mouse_cursor.


File: refman.info,  Node: al_set_system_mouse_cursor,  Next: al_get_mouse_cursor_position,  Prev: al_set_mouse_cursor,  Up: Mouse cursors

16.17.4 al_set_system_mouse_cursor
----------------------------------

bool al_set_system_mouse_cursor(ALLEGRO_DISPLAY *display,
   ALLEGRO_SYSTEM_MOUSE_CURSOR cursor_id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mouse_cursor.c#L71)

Set the given system 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.

If the cursor doesn’t exist on the current platform another cursor will
be silently be substituted.

The cursors are:

   • ALLEGRO_SYSTEM_MOUSE_CURSOR_DEFAULT
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_QUESTION
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_W
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_S
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SW
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_SE
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_PRECISION
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_LINK
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_ALT_SELECT
   • ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE

Returns true on success, false on failure.

See also: *note al_set_mouse_cursor: #al_set_mouse_cursor, *note
al_show_mouse_cursor: #al_show_mouse_cursor, *note al_hide_mouse_cursor:
#al_hide_mouse_cursor.


File: refman.info,  Node: al_get_mouse_cursor_position,  Next: al_hide_mouse_cursor,  Prev: al_set_system_mouse_cursor,  Up: Mouse cursors

16.17.5 al_get_mouse_cursor_position
------------------------------------

bool al_get_mouse_cursor_position(int *ret_x, int *ret_y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L257)

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.

Returns true on success, false on failure.


File: refman.info,  Node: al_hide_mouse_cursor,  Next: al_show_mouse_cursor,  Prev: al_get_mouse_cursor_position,  Up: Mouse cursors

16.17.6 al_hide_mouse_cursor
----------------------------

bool al_hide_mouse_cursor(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mouse_cursor.c#L109)

Hide the mouse cursor in the given display.  This has no effect on what
the current mouse cursor looks like; it just makes it disappear.

Returns true on success (or if the cursor already was hidden), false
otherwise.

See also: *note al_show_mouse_cursor: #al_show_mouse_cursor.


File: refman.info,  Node: al_show_mouse_cursor,  Next: al_grab_mouse,  Prev: al_hide_mouse_cursor,  Up: Mouse cursors

16.17.7 al_show_mouse_cursor
----------------------------

bool al_show_mouse_cursor(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mouse_cursor.c#L96)

Make a mouse cursor visible in the given display.

Returns true if a mouse cursor is shown as a result of the call (or one
already was visible), false otherwise.

See also: *note al_hide_mouse_cursor: #al_hide_mouse_cursor.


File: refman.info,  Node: al_grab_mouse,  Next: al_ungrab_mouse,  Prev: al_show_mouse_cursor,  Up: Mouse cursors

16.17.8 al_grab_mouse
---------------------

bool al_grab_mouse(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L277)

Confine the mouse cursor to the given display.  The mouse cursor can
only be confined to one display at a time.

Returns true if successful, otherwise returns false.  Do not assume that
the cursor will remain confined until you call *note al_ungrab_mouse:
#al_ungrab_mouse.  It may lose the confined status at any time for other
reasons.

     _Note:_ not yet implemented on Mac OS X.
See also: *note al_ungrab_mouse: #al_ungrab_mouse.


File: refman.info,  Node: al_ungrab_mouse,  Prev: al_grab_mouse,  Up: Mouse cursors

16.17.9 al_ungrab_mouse
-----------------------

bool al_ungrab_mouse(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/mousenu.c#L291)

Stop confining the mouse cursor to any display belonging to the program.

     _Note:_ not yet implemented on Mac OS X.
See also: *note al_grab_mouse: #al_grab_mouse.


File: refman.info,  Node: Path structures,  Next: State,  Prev: Mouse routines,  Up: Top

17 Path structures
******************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

We define a path as an optional _drive_, followed by zero or more
_directory components_, followed by an optional _filename_.  The
filename may be broken up into a _basename_ and an _extension_, where
the basename includes the start of the filename up to, but not
including, the last dot (.)  character.  If no dot character exists the
basename is the whole filename.  The extension is everything from the
last dot character to the end of the filename.

* Menu:

* al_create_path::
* al_create_path_for_directory::
* al_destroy_path::
* al_clone_path::
* al_join_paths::
* al_rebase_path::
* al_get_path_drive::
* al_get_path_num_components::
* al_get_path_component::
* al_get_path_tail::
* al_get_path_filename::
* al_get_path_basename::
* al_get_path_extension::
* al_set_path_drive::
* al_append_path_component::
* al_insert_path_component::
* al_replace_path_component::
* al_remove_path_component::
* al_drop_path_tail::
* al_set_path_filename::
* al_set_path_extension::
* al_path_cstr::
* al_path_ustr::
* al_make_path_canonical::


File: refman.info,  Node: al_create_path,  Next: al_create_path_for_directory,  Up: Path structures

17.1 al_create_path
===================

ALLEGRO_PATH *al_create_path(const char *str)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L156)

Create a path structure from a string.  The last component, if it is
followed by a directory separator and is neither “.” nor “..”, is
treated as the last directory name in the path.  Otherwise the last
component is treated as the filename.  The string may be NULL for an
empty path.

See also: *note al_create_path_for_directory:
#al_create_path_for_directory, *note al_destroy_path: #al_destroy_path.


File: refman.info,  Node: al_create_path_for_directory,  Next: al_destroy_path,  Prev: al_create_path,  Up: Path structures

17.2 al_create_path_for_directory
=================================

ALLEGRO_PATH *al_create_path_for_directory(const char *str)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L188)

This is the same as *note al_create_path: #al_create_path, but
interprets the passed string as a directory path.  The filename
component of the returned path will always be empty.

See also: *note al_create_path: #al_create_path, *note al_destroy_path:
#al_destroy_path.


File: refman.info,  Node: al_destroy_path,  Next: al_clone_path,  Prev: al_create_path_for_directory,  Up: Path structures

17.3 al_destroy_path
====================

void al_destroy_path(ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L429)

Free a path structure.  Does nothing if passed NULL.

See also: *note al_create_path: #al_create_path, *note
al_create_path_for_directory: #al_create_path_for_directory.


File: refman.info,  Node: al_clone_path,  Next: al_join_paths,  Prev: al_destroy_path,  Up: Path structures

17.4 al_clone_path
==================

ALLEGRO_PATH *al_clone_path(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L203)

Clones an ALLEGRO_PATH structure.  Returns NULL on failure.

See also: *note al_destroy_path: #al_destroy_path.


File: refman.info,  Node: al_join_paths,  Next: al_rebase_path,  Prev: al_clone_path,  Up: Path structures

17.5 al_join_paths
==================

bool al_join_paths(ALLEGRO_PATH *path, const ALLEGRO_PATH *tail)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L347)

Concatenate two path structures.  The first path structure is modified.
If ‘tail’ is an absolute path, this function does nothing.

If ‘tail’ is a relative path, all of its directory components will be
appended to ‘path’.  tail’s filename will also overwrite path’s
filename, even if it is just the empty string.

Tail’s drive is ignored.

Returns true if ‘tail’ was a relative path and so concatenated to
‘path’, otherwise returns false.

See also: *note al_rebase_path: #al_rebase_path.


File: refman.info,  Node: al_rebase_path,  Next: al_get_path_drive,  Prev: al_join_paths,  Up: Path structures

17.6 al_rebase_path
===================

bool al_rebase_path(const ALLEGRO_PATH *head, ALLEGRO_PATH *tail)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L374)

Concatenate two path structures, modifying the second path structure.
If _tail_ is an absolute path, this function does nothing.  Otherwise,
the drive and path components in _head_ are inserted at the start of
_tail_.

For example, if _head_ is “/anchor/” and _tail_ is “data/file.ext”, then
after the call _tail_ becomes “/anchor/data/file.ext”.

See also: *note al_join_paths: #al_join_paths.


File: refman.info,  Node: al_get_path_drive,  Next: al_get_path_num_components,  Prev: al_rebase_path,  Up: Path structures

17.7 al_get_path_drive
======================

const char *al_get_path_drive(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L481)

Return the drive letter on a path, or the empty string if there is none.

The “drive letter” is only used on Windows, and is usually a string like
“c:”, but may be something like “\\Computer Name” in the case of UNC
(Uniform Naming Convention) syntax.


File: refman.info,  Node: al_get_path_num_components,  Next: al_get_path_component,  Prev: al_get_path_drive,  Up: Path structures

17.8 al_get_path_num_components
===============================

int al_get_path_num_components(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L229)

Return the number of directory components in a path.

The directory components do not include the final part of a path (the
filename).

See also: *note al_get_path_component: #al_get_path_component.


File: refman.info,  Node: al_get_path_component,  Next: al_get_path_tail,  Prev: al_get_path_num_components,  Up: Path structures

17.9 al_get_path_component
==========================

const char *al_get_path_component(const ALLEGRO_PATH *path, int i)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L239)

Return the i’th directory component of a path, counting from zero.  If
the index is negative then count from the right, i.e. -1 refers to the
last path component.  It is an error to pass an index which is out of
bounds.

See also: *note al_get_path_num_components: #al_get_path_num_components,
*note al_get_path_tail: #al_get_path_tail.


File: refman.info,  Node: al_get_path_tail,  Next: al_get_path_filename,  Prev: al_get_path_component,  Up: Path structures

17.10 al_get_path_tail
======================

const char *al_get_path_tail(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L307)

Returns the last directory component, or NULL if there are no directory
components.


File: refman.info,  Node: al_get_path_filename,  Next: al_get_path_basename,  Prev: al_get_path_tail,  Up: Path structures

17.11 al_get_path_filename
==========================

const char *al_get_path_filename(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L504)

Return the filename part of the path, or the empty string if there is
none.

The returned pointer is valid only until the filename part of the path
is modified in any way, or until the path is destroyed.

See also: *note al_get_path_basename: #al_get_path_basename, *note
al_get_path_extension: #al_get_path_extension, *note
al_get_path_component: #al_get_path_component.


File: refman.info,  Node: al_get_path_basename,  Next: al_get_path_extension,  Prev: al_get_path_filename,  Up: Path structures

17.12 al_get_path_basename
==========================

const char *al_get_path_basename(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L549)

Return the basename, i.e. filename with the extension removed.  If the
filename doesn’t have an extension, the whole filename is the basename.
If there is no filename part then the empty string is returned.

The returned pointer is valid only until the filename part of the path
is modified in any way, or until the path is destroyed.

See also: *note al_get_path_filename: #al_get_path_filename, *note
al_get_path_extension: #al_get_path_extension.


File: refman.info,  Node: al_get_path_extension,  Next: al_set_path_drive,  Prev: al_get_path_basename,  Up: Path structures

17.13 al_get_path_extension
===========================

const char *al_get_path_extension(const ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L514)

Return a pointer to the start of the extension of the filename,
i.e. everything from the final dot (‘.’) character onwards.  If no dot
exists, returns an empty string.

The returned pointer is valid only until the filename part of the path
is modified in any way, or until the path is destroyed.

See also: *note al_get_path_filename: #al_get_path_filename, *note
al_get_path_basename: #al_get_path_basename.


File: refman.info,  Node: al_set_path_drive,  Next: al_append_path_component,  Prev: al_get_path_extension,  Up: Path structures

17.14 al_set_path_drive
=======================

void al_set_path_drive(ALLEGRO_PATH *path, const char *drive)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L468)

Set the drive string on a path.  The drive may be NULL, which is
equivalent to setting the drive string to the empty string.

See also: *note al_get_path_drive: #al_get_path_drive.


File: refman.info,  Node: al_append_path_component,  Next: al_insert_path_component,  Prev: al_set_path_drive,  Up: Path structures

17.15 al_append_path_component
==============================

void al_append_path_component(ALLEGRO_PATH *path, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L330)

Append a directory component.

See also: *note al_insert_path_component: #al_insert_path_component.


File: refman.info,  Node: al_insert_path_component,  Next: al_replace_path_component,  Prev: al_append_path_component,  Up: Path structures

17.16 al_insert_path_component
==============================

void al_insert_path_component(ALLEGRO_PATH *path, int i, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L289)

Insert a directory component at index i.  If the index is negative then
count from the right, i.e. -1 refers to the last path component.

It is an error to pass an index i which is not within these bounds: 0 <=
i <= al_get_path_num_components(path).

See also: *note al_append_path_component: #al_append_path_component,
*note al_replace_path_component: #al_replace_path_component, *note
al_remove_path_component: #al_remove_path_component.


File: refman.info,  Node: al_replace_path_component,  Next: al_remove_path_component,  Prev: al_insert_path_component,  Up: Path structures

17.17 al_replace_path_component
===============================

void al_replace_path_component(ALLEGRO_PATH *path, int i, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L255)

Replace the i’th directory component by another string.  If the index is
negative then count from the right, i.e. -1 refers to the last path
component.  It is an error to pass an index which is out of bounds.

See also: *note al_insert_path_component: #al_insert_path_component,
*note al_remove_path_component: #al_remove_path_component.


File: refman.info,  Node: al_remove_path_component,  Next: al_drop_path_tail,  Prev: al_replace_path_component,  Up: Path structures

17.18 al_remove_path_component
==============================

void al_remove_path_component(ALLEGRO_PATH *path, int i)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L272)

Delete the i’th directory component.  If the index is negative then
count from the right, i.e. -1 refers to the last path component.  It is
an error to pass an index which is out of bounds.

See also: *note al_insert_path_component: #al_insert_path_component,
*note al_replace_path_component: #al_replace_path_component, *note
al_drop_path_tail: #al_drop_path_tail.


File: refman.info,  Node: al_drop_path_tail,  Next: al_set_path_filename,  Prev: al_remove_path_component,  Up: Path structures

17.19 al_drop_path_tail
=======================

void al_drop_path_tail(ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L320)

Remove the last directory component, if any.

See also: *note al_remove_path_component: #al_remove_path_component.


File: refman.info,  Node: al_set_path_filename,  Next: al_set_path_extension,  Prev: al_drop_path_tail,  Up: Path structures

17.20 al_set_path_filename
==========================

void al_set_path_filename(ALLEGRO_PATH *path, const char *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L491)

Set the optional filename part of the path.  The filename may be NULL,
which is equivalent to setting the filename to the empty string.

See also: *note al_set_path_extension: #al_set_path_extension, *note
al_get_path_filename: #al_get_path_filename.


File: refman.info,  Node: al_set_path_extension,  Next: al_path_cstr,  Prev: al_set_path_filename,  Up: Path structures

17.21 al_set_path_extension
===========================

bool al_set_path_extension(ALLEGRO_PATH *path, char const *extension)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L529)

Replaces the extension of the path with the given one, i.e. replaces
everything from the final dot (‘.’) character onwards, including the
dot.  If the filename of the path has no extension, the given one is
appended.  Usually the new extension you supply should include a leading
dot.

Returns false if the path contains no filename part, i.e. the filename
part is the empty string.

See also: *note al_set_path_filename: #al_set_path_filename, *note
al_get_path_extension: #al_get_path_extension.


File: refman.info,  Node: al_path_cstr,  Next: al_path_ustr,  Prev: al_set_path_extension,  Up: Path structures

17.22 al_path_cstr
==================

const char *al_path_cstr(const ALLEGRO_PATH *path, char delim)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L413)

Convert a path to its string representation, i.e. optional drive,
followed by directory components separated by ‘delim’, followed by an
optional filename.

To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP
for ‘delim’.

The returned pointer is valid only until the path is modified in any
way, or until the path is destroyed.  This returns a null-terminated
string.  If you need an ALLEGRO_USTR instead, use *note al_path_ustr:
#al_path_ustr.

See also: *note al_path_ustr: #al_path_ustr.


File: refman.info,  Node: al_path_ustr,  Next: al_make_path_canonical,  Prev: al_path_cstr,  Up: Path structures

17.23 al_path_ustr
==================

const ALLEGRO_USTR *al_path_ustr(const ALLEGRO_PATH *path, char delim)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L420)

Convert a path to its string representation, i.e. optional drive,
followed by directory components separated by ‘delim’, followed by an
optional filename.

To use the current native path separator, use ALLEGRO_NATIVE_PATH_SEP
for ‘delim’.

The returned pointer is valid only until the path is modified in any
way, or until the path is destroyed.  This returns an ALLEGRO_USTR. If
you need a null-terminated string instead, use *note al_path_cstr:
#al_path_cstr.

Since: 5.2.3

See also: *note al_path_cstr: #al_path_cstr.


File: refman.info,  Node: al_make_path_canonical,  Prev: al_path_ustr,  Up: Path structures

17.24 al_make_path_canonical
============================

bool al_make_path_canonical(ALLEGRO_PATH *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/path.c#L566)

Removes any leading ‘..’ directory components in absolute paths.
Removes all ‘.’ directory components.

Note that this does _not_ collapse “x/../y” sections into “y”.  This is
by design.  If “/foo” on your system is a symlink to “/bar/baz”, then
“/foo/../quux” is actually “/bar/quux”, not “/quux” as a naive removal
of “..” components would give you.


File: refman.info,  Node: State,  Next: System routines,  Prev: Path structures,  Up: Top

18 State
********

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_STATE::
* ALLEGRO_STATE_FLAGS::
* al_restore_state::
* al_store_state::
* al_get_errno::
* al_set_errno::


File: refman.info,  Node: ALLEGRO_STATE,  Next: ALLEGRO_STATE_FLAGS,  Up: State

18.1 ALLEGRO_STATE
==================

typedef struct ALLEGRO_STATE ALLEGRO_STATE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/tls.h#L49)

Opaque type which is passed to *note al_store_state:
#al_store_state./*note al_restore_state: #al_restore_state.

The various state kept internally by Allegro can be displayed like this:

  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.)


File: refman.info,  Node: ALLEGRO_STATE_FLAGS,  Next: al_restore_state,  Prev: ALLEGRO_STATE,  Up: State

18.2 ALLEGRO_STATE_FLAGS
========================

typedef enum ALLEGRO_STATE_FLAGS

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/tls.h#L28)

Flags which can be passed to *note al_store_state:
#al_store_state./*note al_restore_state: #al_restore_state. as bit
combinations.  See *note al_store_state: #al_store_state. for the list
of flags.


File: refman.info,  Node: al_restore_state,  Next: al_store_state,  Prev: ALLEGRO_STATE_FLAGS,  Up: State

18.3 al_restore_state
=====================

void al_restore_state(ALLEGRO_STATE const *state)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L770)

Restores part of the state of the current thread from the given *note
ALLEGRO_STATE: #allegro_state. object.

See also: *note al_store_state: #al_store_state, *note
ALLEGRO_STATE_FLAGS: #allegro_state_flags.


File: refman.info,  Node: al_store_state,  Next: al_get_errno,  Prev: al_restore_state,  Up: State

18.4 al_store_state
===================

void al_store_state(ALLEGRO_STATE *state, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L700)

Stores part of the state of the current thread in the given *note
ALLEGRO_STATE: #allegro_state. object.  The flags parameter can take any
bit-combination of these flags:

   • ALLEGRO_STATE_NEW_DISPLAY_PARAMETERS - new_display_format,
     new_display_refresh_rate, new_display_flags
   • ALLEGRO_STATE_NEW_BITMAP_PARAMETERS - new_bitmap_format,
     new_bitmap_flags
   • ALLEGRO_STATE_DISPLAY - current_display
   • ALLEGRO_STATE_TARGET_BITMAP - target_bitmap
   • ALLEGRO_STATE_BLENDER - blender
   • ALLEGRO_STATE_TRANSFORM - current_transformation
   • ALLEGRO_STATE_PROJECTION_TRANSFORM -
     current_projection_transformation
   • ALLEGRO_STATE_NEW_FILE_INTERFACE - new_file_interface
   • ALLEGRO_STATE_BITMAP - same as ALLEGRO_STATE_NEW_BITMAP_PARAMETERS
     and ALLEGRO_STATE_TARGET_BITMAP
   • ALLEGRO_STATE_ALL - all of the above

See also: *note al_restore_state: #al_restore_state, *note
ALLEGRO_STATE: #allegro_state.


File: refman.info,  Node: al_get_errno,  Next: al_set_errno,  Prev: al_store_state,  Up: State

18.5 al_get_errno
=================

int al_get_errno(void)
GETTER(allegro_errno, 0)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L936)

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.


File: refman.info,  Node: al_set_errno,  Prev: al_get_errno,  Up: State

18.6 al_set_errno
=================

void al_set_errno(int errnum)
SETTER(allegro_errno, errnum)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/tls.c#L941)

Set the error number for the calling thread.


File: refman.info,  Node: System routines,  Next: Threads,  Prev: State,  Up: Top

19 System routines
******************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* al_install_system::
* al_init::
* al_uninstall_system::
* al_is_system_installed::
* al_get_allegro_version::
* al_get_standard_path::
* al_set_exe_name::
* al_set_app_name::
* al_set_org_name::
* al_get_app_name::
* al_get_org_name::
* al_get_system_config::
* al_get_system_id::
* al_register_assert_handler::
* al_register_trace_handler::
* al_get_cpu_count::
* al_get_ram_size::
* ALLEGRO_SYSTEM_ID::


File: refman.info,  Node: al_install_system,  Next: al_init,  Up: System routines

19.1 al_install_system
======================

bool al_install_system(int version, int (*atexit_ptr)(void (*)(void)))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L216)

Initialize the Allegro system.  No other Allegro functions can be called
before this (with one or two exceptions).

The version field should always be set to ALLEGRO_VERSION_INT.

If atexit_ptr is non-NULL, and if hasn’t been done already, *note
al_uninstall_system: #al_uninstall_system. will be registered as an
atexit function.

Returns true if Allegro was successfully initialized by this function
call (or already was initialized previously), false if Allegro cannot be
used.  A common reason for this function to fail is when the version of
Allegro you compiled your game against is not compatible with the
version of the shared libraries that were found on the system.

The version compatibility check works as follows.  Let A = xa.ya.za.* be
the version of Allegro you compiled with, and B = xb.yb.zb.* be the
version of Allegro found in the system shared library.

If you defined ‘ALLEGRO_UNSTABLE’ before including Allegro headers, then
version A is compatible with B only if xa.ya.za = xb.yb.zb.  Otherwise,
A is compatible with B only if xa.ya = xb.yb.

See also: *note al_init: #al_init.


File: refman.info,  Node: al_init,  Next: al_uninstall_system,  Prev: al_install_system,  Up: System routines

19.2 al_init
============

#define al_init()    (al_install_system(ALLEGRO_VERSION_INT, atexit))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/system.h#L30)

Like *note al_install_system: #al_install_system, but automatically
passes in the version and uses the atexit function visible in the
current binary.

     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 al_install_system either with a ‘NULL’ atexit_ptr,
     or with a pointer to atexit provided by the user of this shared
     library.
See also: *note al_install_system: #al_install_system.


File: refman.info,  Node: al_uninstall_system,  Next: al_is_system_installed,  Prev: al_init,  Up: System routines

19.3 al_uninstall_system
========================

void al_uninstall_system(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L315)

Closes down the Allegro system.

     Note: al_uninstall_system() can be called without a corresponding
     *note al_install_system: #al_install_system. call, e.g. from
     atexit().


File: refman.info,  Node: al_is_system_installed,  Next: al_get_allegro_version,  Prev: al_uninstall_system,  Up: System routines

19.4 al_is_system_installed
===========================

bool al_is_system_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L345)

Returns true if Allegro is initialized, otherwise returns false.


File: refman.info,  Node: al_get_allegro_version,  Next: al_get_standard_path,  Prev: al_is_system_installed,  Up: System routines

19.5 al_get_allegro_version
===========================

uint32_t al_get_allegro_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/allegro.c#L27)

Returns the (compiled) version of the Allegro library, packed into a
single integer as groups of 8 bits in the form ‘(major << 24) | (minor
<< 16) | (revision << 8) | release’.

You can use code like this to extract them:

uint32_t version = al_get_allegro_version();
int major = version >> 24;
int minor = (version >> 16) & 255;
int revision = (version >> 8) & 255;
int release = version & 255;

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.


File: refman.info,  Node: al_get_standard_path,  Next: al_set_exe_name,  Prev: al_get_allegro_version,  Up: System routines

19.6 al_get_standard_path
=========================

ALLEGRO_PATH *al_get_standard_path(int id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L380)

Gets a system path, depending on the ‘id’ parameter.  Some of these
paths may be affected by the organization and application name, so be
sure to set those before calling this function.

The paths are not guaranteed to be unique (e.g., SETTINGS and DATA may
be the same on some platforms), so you should be sure your filenames are
unique if you need to avoid naming collisions.  Also, a returned path
may not actually exist on the file system.

ALLEGRO_RESOURCES_PATH

     If you bundle data in a location relative to your executable, then
     you should use this path to locate that data.  On most platforms,
     this is the directory that contains the executable file.

     If called from an OS X app bundle, then this will point to the
     internal resource directory (<bundle.app>/Contents/Resources).  To
     maintain consistency, if you put your resources into a directory
     called “data” beneath the executable on some other platform (like
     Windows), then you should also create a directory called “data”
     under the OS X app bundle’s resource folder.

     You should not try to write to this path, as it is very likely
     read-only.

     If you install your resources in some other system directory (e.g.,
     in /usr/share or C:\ProgramData), then you are responsible for
     keeping track of that yourself.

ALLEGRO_TEMP_PATH

     Path to the directory for temporary files.
ALLEGRO_USER_HOME_PATH

     This is the user’s home directory.  You should not normally write
     files into this directory directly, or create any sub folders in
     it, without explicit permission from the user.  One practical
     application of this path would be to use it as the starting place
     of a file selector in a GUI.
ALLEGRO_USER_DOCUMENTS_PATH

     This location is easily accessible by the user, and is the place to
     store documents and files that the user might want to later open
     with an external program or transfer to another place.

     You should not save files here unless the user expects it, usually
     by explicit permission.

ALLEGRO_USER_DATA_PATH

     If your program saves any data that the user doesn’t need to access
     externally, then you should place it here.  This is generally the
     least intrusive place to store data.  This path will usually not be
     present on the file system, so make sure to create it before
     writing to it.
ALLEGRO_USER_SETTINGS_PATH

     If you are saving configuration files (especially if the user may
     want to edit them outside of your program), then you should place
     them here.  This path will usually not be present on the file
     system, so make sure to create it before writing to it.
ALLEGRO_EXENAME_PATH

     The full path to the executable.

Returns NULL on failure.  The returned path should be freed with *note
al_destroy_path: #al_destroy_path.

See also: *note al_set_app_name: #al_set_app_name, *note
al_set_org_name: #al_set_org_name, *note al_destroy_path:
#al_destroy_path, *note al_set_exe_name: #al_set_exe_name.


File: refman.info,  Node: al_set_exe_name,  Next: al_set_app_name,  Prev: al_get_standard_path,  Up: System routines

19.7 al_set_exe_name
====================

void al_set_exe_name(char const *path)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L404)

This override the executable name used by *note al_get_standard_path:
#al_get_standard_path. for ALLEGRO_EXENAME_PATH and
ALLEGRO_RESOURCES_PATH.

One possibility where changing this can be useful is if you use the
Python wrapper.  Allegro would then by default think that the system’s
Python executable is the current executable - but you can set it to the
.py file being executed instead.

Since: 5.0.6, 5.1.0

See also: *note al_get_standard_path: #al_get_standard_path.


File: refman.info,  Node: al_set_app_name,  Next: al_set_org_name,  Prev: al_set_exe_name,  Up: System routines

19.8 al_set_app_name
====================

void al_set_app_name(const char *app_name)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L427)

Sets the global application name.

The application name is used by *note al_get_standard_path:
#al_get_standard_path. to build the full path to an application’s files.

This function may be called before *note al_init: #al_init. or *note
al_install_system: #al_install_system.

See also: *note al_get_app_name: #al_get_app_name, *note
al_set_org_name: #al_set_org_name.


File: refman.info,  Node: al_set_org_name,  Next: al_get_app_name,  Prev: al_set_app_name,  Up: System routines

19.9 al_set_org_name
====================

void al_set_org_name(const char *org_name)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L416)

Sets the global organization name.

The organization name is used by *note al_get_standard_path:
#al_get_standard_path. to build the full path to an application’s files.

This function may be called before *note al_init: #al_init. or *note
al_install_system: #al_install_system.

See also: *note al_get_org_name: #al_get_org_name, *note
al_set_app_name: #al_set_app_name.


File: refman.info,  Node: al_get_app_name,  Next: al_get_org_name,  Prev: al_set_org_name,  Up: System routines

19.10 al_get_app_name
=====================

const char *al_get_app_name(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L451)

Returns the global application name string.

See also: *note al_set_app_name: #al_set_app_name.


File: refman.info,  Node: al_get_org_name,  Next: al_get_system_config,  Prev: al_get_app_name,  Up: System routines

19.11 al_get_org_name
=====================

const char *al_get_org_name(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L443)

Returns the global organization name string.

See also: *note al_set_org_name: #al_set_org_name.


File: refman.info,  Node: al_get_system_config,  Next: al_get_system_id,  Prev: al_get_org_name,  Up: System routines

19.12 al_get_system_config
==========================

ALLEGRO_CONFIG *al_get_system_config(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L370)

Returns the system configuration structure.  The returned configuration
should not be destroyed with *note al_destroy_config:
#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:

   • _Unix only:_ /etc/allegro5rc

   • _Unix only:_ $HOME/allegro5rc

   • _Unix only:_ $HOME/.allegro5rc

   • allegro5.cfg next to the executable

If multiple copies are found, then they are merged using *note
al_merge_config_into: #al_merge_config_into.

The contents of this file are documented inside a prototypical
‘allegro5.cfg’ that you can find in the root directory of the source
distributions of Allegro.  They are also reproduced below.

Note that Allegro will not look into that file unless you make a copy of
it and place it next to your executable!

#
#  Configuration file for the Allegro 5 library.
#
#  This file should be either in the same directory as your program.
#
#  On Unix, this file may also be stored as ~/.allegro5rc or /etc/allegro5rc.
#  If multiple files exist, they will be merged, with values from more specific
#  files overriding the less specific files.

[graphics]

# Graphics driver.
# Can be 'default', 'opengl' or 'direct3d' (Windows only).
driver=default

# Display configuration selection mode.
#
# Under Linux, it can be used to force the old GLX 1.2 way of choosing
# display settings or the new FBConfig method introduced with GLX 1.3.
#
# Under Windows, when using the OpenGL driver, setting it to old will
# use DescribePixelFormat and new will use wglGetPixelFormatAttribivARB
# (provided by WGL_ARB_pixel_format extension).
#
# Can be 'old' and 'new'. Default is 'new'.
config_selection=new

# What method to use to detect legacy cards for the Direct3D backend of the
# primitives addon. Can be 'default', which means it'll check that the pixel
# shader version supported is below some value. 'force_legacy' will force it to
# detect as a legacy card. 'force_modern' will force it to detect is as a modern
# card.
prim_d3d_legacy_detection=default

# For compatibility reasons, video bitmaps smaller than this size are
# backed by textures with this size. This is often no longer necessary
# on more modern systems, and should be set to < 16 if you're creating
# bitmaps smaller than this size. Note that on Android, this is ignored
# if smaller than 32.
min_bitmap_size=16

[audio]

# Driver can be 'default', 'openal', 'alsa', 'oss', 'pulseaudio' or 'directsound'
# depending on platform.
driver=default

# Mixer quality can be 'linear' (default), 'cubic' (best), or 'point' (bad).
# default_mixer_quality=linear

# The frequency to use for the default voice/mixer. Default: 44100.
# primary_voice_frequency=44100
# primary_mixer_frequency=44100

# Can be 'int16', otherwise defaults to float32.
# primary_voice_depth=float32
# primary_mixer_depth=float32

[oss]

# You can skip probing for OSS4 driver by setting this option to 'yes'.
# Default is 'no'.
force_ver3=no

# When OSS3 is used, you can choose a sound device here.
# Default is '/dev/dsp'.
device=/dev/dsp

[alsa]

# Set the ALSA sound device.
# Default is 'default'.
device=default

# Set the ALSA capture device, e.g. hw:0,0
# Default is 'default'.
capture_device=default

# Set the period size (in samples)
# Note that this is erroneously called 'buffer_size' for backwards
# compatibility.
buffer_size=32

# Set the buffer size (in samples)
buffer_size2=2048

[pulseaudio]

# Set the buffer size (in samples)
buffer_size=1024

[directsound]

# Set the DirectSound buffer size (in samples)
buffer_size = 8192

# Which window to attach the device to. Can be 'desktop', or 'foreground'. Try
# flipping this if there are issues initializing audio.
window = desktop

[opengl]

# If you want to support old OpenGL versions, you can make Allegro
# believe an older version than what you actually have is used with
# this key. This is only for testing/debugging purposes.

# force_opengl_version = 1.2

[opengl_disabled_extensions]

# Any OpenGL extensions can be listed here to make Allegro report them
# as not available. The extensions used by Allegro itself if available
# are shown below - uncommenting them would disable them:

# GL_ARB_texture_non_power_of_two=0
# GL_EXT_framebuffer_object=0

[image]

# Gamma handling of PNG files.
# A value of 0.0 means: Don't do any gamma correction.
# A value of -1.0 means: Use the value from the environment variable
# SCREEN_GAMMA (if available), otherwise fallback to a value of 2.2
# (a good guess for PC monitors, and the value for sRGB colourspace).
# Otherwise, the value is taken as-is.
png_screen_gamma = -1.0

# Compression level for PNG files. Possible values: 0-9, "best", "fastest",
# "none" or "default" (a sane compromise between size and speed).
png_compression_level = default

# Quality level for JPEG files. Possible values: 0-100
jpeg_quality_level = 75

# Quality level for WebP files. Possible values: 0-100 or "lossless"
webp_quality_level = lossless

[joystick]

# Linux: Allegro normally searches for joystick device N at /dev/input/jsN.
# You can override the device file path on a per-device basis, like this.

# device0=/dev/input/by-id/usb-blahblah-joystick

# Windows: You can choose between the XINPUT or DIRECTINPUT driver for
# joysticks and force feedback joysticks. Xinput is the more modern 
# system, but DirectInput has more force feedback capabilities for older 
# joysticks.
driver=XINPUT

# Windows: Use this to force an XInput DLL version, example "3" forces
# xinput1_3.dll. By default, the latest version is used.

# force_xinput_version = 3

[keyboard]

# You can trap/untrap the mouse cursor within a window with a key combination
# of your choice, e.g. "Ctrl-G", "Shift-Ctrl-G", "Ctrl-LShift", "RWin".
# This feature currently only works on X11 and Windows.

# toggle_mouse_grab_key = ScrollLock

# By default, you can press Ctrl-Alt-Delete or Ctrl-Alt-End to quit Allegro
# programs. Set this to false to disable this feature. This only works on
# Linux.

# enable_three_finger_exit = true

# By default, pressing the LED toggling keys (e.g. CapsLock) will also toggle
# the LED on the keyboard. Setting this to false disable that connection.
# This can only be controled on non-X11 Linux.

# enable_key_led_toggle = true


[trace]
# Comma-separated list of channels to log. Default is "all" which
# disables channel filtering. Some possible channels are:
# system,display,keyboard,opengl
# Channel names can be prefixed with - to exclude only those channels.
# Each addon and source-file can define additional channels though so
# there are more.
channels=all

# Log-level. Can be one of debug, info, warn, error, none or empty.
# In debug builds if it is empty or unset, then the level is set to debug.
# In release builds if it is empty or unset, then the level is set to none.
level=

# Set to 0 to disable line numbers in log files.
lines=1

# Set to 0 to disable timestamps in log files.
timestamps=1

# Set to 0 to disable function names in log files.
functions=1

[x11]
# Can be fullscreen_only, always, never
bypass_compositor = fullscreen_only

[xkeymap]
# Override X11 keycode. The below example maps X11 code 52 (Y) to Allegro
# code 26 (Z) and X11 code 29 (Z) to Allegro code 25 (Y).
# 52=26
# 29=25


[shader]
# If you want to support override version of the d3dx9_xx.dll library
# define this value.
# By default, latest installed version is used.

# force_d3dx9_version = 36

[ttf]

# Set these to something other than 0 to override the default page sizes for TTF
# glyphs.
min_page_size = 0
max_page_size = 0

# This entry contains characters that will be pre-catched during font loading.
# cache_text = a bcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

# Uncomment if you want only the characters in the cache_text entry to ever be drawn
# skip_cache_misses = true

[compatibility]

# Prior to 5.2.4 on Windows you had to manually resize the display when
# showing the menu using the dialog addon. After 5.2.4 this is done
# automatically, but may break old code that handled this eventuality.
# Set this to false for such code.
automatic_menu_display_resize = true


File: refman.info,  Node: al_get_system_id,  Next: al_register_assert_handler,  Prev: al_get_system_config,  Up: System routines

19.13 al_get_system_id
======================

ALLEGRO_SYSTEM_ID al_get_system_id(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L362)

Returns the platform that Allegro is running on.

Since: 5.2.5

See also: *note ALLEGRO_SYSTEM_ID: #allegro_system_id.


File: refman.info,  Node: al_register_assert_handler,  Next: al_register_trace_handler,  Prev: al_get_system_id,  Up: System routines

19.14 al_register_assert_handler
================================

void al_register_assert_handler(void (*handler)(char const *expr,
   char const *file, int line, char const *func))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/debug.c#L356)

Register a function to be called when an internal Allegro assertion
fails.  Pass NULL to reset to the default behaviour, which is to do
whatever the standard ‘assert()’ macro does.

Since: 5.0.6, 5.1.0


File: refman.info,  Node: al_register_trace_handler,  Next: al_get_cpu_count,  Prev: al_register_assert_handler,  Up: System routines

19.15 al_register_trace_handler
===============================

void al_register_trace_handler(void (*handler)(char const *))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/debug.c#L365)

Register a callback which is called whenever Allegro writes something to
its log files.  The default logging to allegro.log is disabled while
this callback is active.  Pass NULL to revert to the default logging.

This function may be called prior to al_install_system.

See the example allegro5.cfg for documentation on how to configure the
used debug channels, logging levels and trace format.

Since: 5.1.5


File: refman.info,  Node: al_get_cpu_count,  Next: al_get_ram_size,  Prev: al_register_trace_handler,  Up: System routines

19.16 al_get_cpu_count
======================

int al_get_cpu_count(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/cpu.c#L50)

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 *note al_install_system:
#al_install_system. or *note al_init: #al_init.

Since: 5.1.12


File: refman.info,  Node: al_get_ram_size,  Next: ALLEGRO_SYSTEM_ID,  Prev: al_get_cpu_count,  Up: System routines

19.17 al_get_ram_size
=====================

int al_get_ram_size(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/cpu.c#L77)

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 or more than what
this function returns 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 *note al_install_system:
#al_install_system. or *note al_init: #al_init.

Since: 5.1.12


File: refman.info,  Node: ALLEGRO_SYSTEM_ID,  Prev: al_get_ram_size,  Up: System routines

19.18 ALLEGRO_SYSTEM_ID
=======================

enum ALLEGRO_SYSTEM_ID {

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/system.h#L15)

The system Allegro is running on.

   • ALLEGRO_SYSTEM_ID_UNKNOWN - Unknown system.
   • ALLEGRO_SYSTEM_ID_XGLX - Xglx
   • ALLEGRO_SYSTEM_ID_WINDOWS - Windows
   • ALLEGRO_SYSTEM_ID_MACOSX - macOS
   • ALLEGRO_SYSTEM_ID_ANDROID - Android
   • ALLEGRO_SYSTEM_ID_IPHONE - iOS
   • ALLEGRO_SYSTEM_ID_GP2XWIZ - GP2XWIZ
   • ALLEGRO_SYSTEM_ID_RASPBERRYPI - Raspberry Pi
   • ALLEGRO_SYSTEM_ID_SDL - SDL

Since: 5.2.5

See also: *note al_get_system_id: #al_get_system_id.


File: refman.info,  Node: Threads,  Next: Time routines,  Prev: System routines,  Up: Top

20 Threads
**********

Allegro includes a simple cross-platform threading interface.  It is a
thin layer on top of two threading APIs: Windows threads and POSIX
Threads (pthreads).  Enforcing a consistent semantics on all platforms
would be difficult at best, hence the behaviour of the following
functions will differ subtly on different platforms (more so than
usual).  Your best bet is to be aware of this and code to the
intersection of the semantics and avoid edge cases.

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_THREAD::
* ALLEGRO_MUTEX::
* ALLEGRO_COND::
* al_create_thread::
* al_create_thread_with_stacksize::
* al_start_thread::
* al_join_thread::
* al_set_thread_should_stop::
* al_get_thread_should_stop::
* al_destroy_thread::
* al_run_detached_thread::
* al_create_mutex::
* al_create_mutex_recursive::
* al_lock_mutex::
* al_unlock_mutex::
* al_destroy_mutex::
* al_create_cond::
* al_destroy_cond::
* al_wait_cond::
* al_wait_cond_until::
* al_broadcast_cond::
* al_signal_cond::


File: refman.info,  Node: ALLEGRO_THREAD,  Next: ALLEGRO_MUTEX,  Up: Threads

20.1 ALLEGRO_THREAD
===================

typedef struct ALLEGRO_THREAD ALLEGRO_THREAD;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/threads.h#L27)

An opaque structure representing a thread.


File: refman.info,  Node: ALLEGRO_MUTEX,  Next: ALLEGRO_COND,  Prev: ALLEGRO_THREAD,  Up: Threads

20.2 ALLEGRO_MUTEX
==================

typedef struct ALLEGRO_MUTEX ALLEGRO_MUTEX;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/threads.h#L31)

An opaque structure representing a mutex.


File: refman.info,  Node: ALLEGRO_COND,  Next: al_create_thread,  Prev: ALLEGRO_MUTEX,  Up: Threads

20.3 ALLEGRO_COND
=================

typedef struct ALLEGRO_COND ALLEGRO_COND;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/threads.h#L35)

An opaque structure representing a condition variable.


File: refman.info,  Node: al_create_thread,  Next: al_create_thread_with_stacksize,  Prev: ALLEGRO_COND,  Up: Threads

20.4 al_create_thread
=====================

ALLEGRO_THREAD *al_create_thread(
   void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L115)

Spawn a new thread which begins executing ‘proc’.  The new thread is
passed its own thread handle and the value ‘arg’.

Returns a pointer to the thread on success.  Otherwise, returns NULL if
there was an error.

See also: *note al_start_thread: #al_start_thread, *note al_join_thread:
#al_join_thread.


File: refman.info,  Node: al_create_thread_with_stacksize,  Next: al_start_thread,  Prev: al_create_thread,  Up: Threads

20.5 al_create_thread_with_stacksize
====================================

ALLEGRO_THREAD *al_create_thread_with_stacksize(
   void *(*proc)(ALLEGRO_THREAD *thread, void *arg), void *arg, size_t stacksize)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L131)

Spawn a new thread with the give stacksize in bytes which begins
executing ‘proc’.  The new thread is passed its own thread handle and
the value ‘arg’.

Returns a pointer to the thread on success.  Otherwise, returns NULL if
there was an error.

Since: 5.2.5

     _*note Unstable API: #unstable-api.:_ New API, may want a better
     way to specify thread options.
See also: *note al_start_thread: #al_start_thread, *note al_join_thread:
#al_join_thread.


File: refman.info,  Node: al_start_thread,  Next: al_join_thread,  Prev: al_create_thread_with_stacksize,  Up: Threads

20.6 al_start_thread
====================

void al_start_thread(ALLEGRO_THREAD *thread)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L160)

When a thread is created, it is initially in a suspended state.  Calling
*note al_start_thread: #al_start_thread. will start its actual
execution.

Starting a thread which has already been started does nothing.

See also: *note al_create_thread: #al_create_thread.


File: refman.info,  Node: al_join_thread,  Next: al_set_thread_should_stop,  Prev: al_start_thread,  Up: Threads

20.7 al_join_thread
===================

void al_join_thread(ALLEGRO_THREAD *thread, void **ret_value)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L194)

Wait for the thread to finish executing.  This implicitly calls *note
al_set_thread_should_stop: #al_set_thread_should_stop. first.

If ‘ret_value’ is non-‘NULL’, the value returned by the thread function
will be stored at the location pointed to by ‘ret_value’.

See also: *note al_set_thread_should_stop: #al_set_thread_should_stop,
*note al_get_thread_should_stop: #al_get_thread_should_stop, *note
al_destroy_thread: #al_destroy_thread.


File: refman.info,  Node: al_set_thread_should_stop,  Next: al_get_thread_should_stop,  Prev: al_join_thread,  Up: Threads

20.8 al_set_thread_should_stop
==============================

void al_set_thread_should_stop(ALLEGRO_THREAD *thread)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L244)

Set the flag to indicate ‘thread’ should stop.  Returns immediately.

See also: *note al_join_thread: #al_join_thread, *note
al_get_thread_should_stop: #al_get_thread_should_stop.


File: refman.info,  Node: al_get_thread_should_stop,  Next: al_destroy_thread,  Prev: al_set_thread_should_stop,  Up: Threads

20.9 al_get_thread_should_stop
==============================

bool al_get_thread_should_stop(ALLEGRO_THREAD *thread)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L253)

Check if another thread is waiting for ‘thread’ to stop.  Threads which
run in a loop should check this periodically and act on it when
convenient.

Returns true if another thread has called *note al_join_thread:
#al_join_thread. or *note al_set_thread_should_stop:
#al_set_thread_should_stop. on this thread.

See also: *note al_join_thread: #al_join_thread, *note
al_set_thread_should_stop: #al_set_thread_should_stop.

     _Note:_ We don’t support forceful killing of threads.


File: refman.info,  Node: al_destroy_thread,  Next: al_run_detached_thread,  Prev: al_get_thread_should_stop,  Up: Threads

20.10 al_destroy_thread
=======================

void al_destroy_thread(ALLEGRO_THREAD *thread)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L262)

Free the resources used by a thread.  Implicitly performs *note
al_join_thread: #al_join_thread. on the thread if it hasn’t been done
already.

Does nothing if ‘thread’ is NULL.

See also: *note al_join_thread: #al_join_thread.


File: refman.info,  Node: al_run_detached_thread,  Next: al_create_mutex,  Prev: al_destroy_thread,  Up: Threads

20.11 al_run_detached_thread
============================

void al_run_detached_thread(void *(*proc)(void *arg), void *arg)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L147)

Runs the passed function in its own thread, with ‘arg’ passed to it as
only parameter.  This is similar to calling *note al_create_thread:
#al_create_thread, *note al_start_thread: #al_start_thread. and (after
the thread has finished) *note al_destroy_thread: #al_destroy_thread. -
but you don’t have the possibility of ever calling *note al_join_thread:
#al_join_thread. on the thread.


File: refman.info,  Node: al_create_mutex,  Next: al_create_mutex_recursive,  Prev: al_run_detached_thread,  Up: Threads

20.12 al_create_mutex
=====================

ALLEGRO_MUTEX *al_create_mutex(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L296)

Create the mutex object (a mutual exclusion device).  The mutex may or
may not support “recursive” locking.

Returns the mutex on success or ‘NULL’ on error.

See also: *note al_create_mutex_recursive: #al_create_mutex_recursive.


File: refman.info,  Node: al_create_mutex_recursive,  Next: al_lock_mutex,  Prev: al_create_mutex,  Up: Threads

20.13 al_create_mutex_recursive
===============================

ALLEGRO_MUTEX *al_create_mutex_recursive(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L309)

Create the mutex object (a mutual exclusion device), with support for
“recursive” locking.  That is, the mutex will count the number of times
it has been locked by the same thread.  If the caller tries to acquire a
lock on the mutex when it already holds the lock then the count is
incremented.  The mutex is only unlocked when the thread releases the
lock on the mutex an equal number of times, i.e. the count drops down to
zero.

See also: *note al_create_mutex: #al_create_mutex.


File: refman.info,  Node: al_lock_mutex,  Next: al_unlock_mutex,  Prev: al_create_mutex_recursive,  Up: Threads

20.14 al_lock_mutex
===================

void al_lock_mutex(ALLEGRO_MUTEX *mutex)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L322)

Acquire the lock on ‘mutex’.  If the mutex is already locked by another
thread, the call will block until the mutex becomes available and
locked.

If the mutex is already locked by the calling thread, then the behaviour
depends on whether the mutex was created with *note al_create_mutex:
#al_create_mutex. or *note al_create_mutex_recursive:
#al_create_mutex_recursive.  In the former case, the behaviour is
undefined; the most likely behaviour is deadlock.  In the latter case,
the count in the mutex will be incremented and the call will return
immediately.

See also: *note al_unlock_mutex: #al_unlock_mutex.

*We don’t yet have al_mutex_trylock.*


File: refman.info,  Node: al_unlock_mutex,  Next: al_destroy_mutex,  Prev: al_lock_mutex,  Up: Threads

20.15 al_unlock_mutex
=====================

void al_unlock_mutex(ALLEGRO_MUTEX *mutex)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L332)

Release the lock on ‘mutex’ if the calling thread holds the lock on it.

If the calling thread doesn’t hold the lock, or if the mutex is not
locked, undefined behaviour results.

See also: *note al_lock_mutex: #al_lock_mutex.


File: refman.info,  Node: al_destroy_mutex,  Next: al_create_cond,  Prev: al_unlock_mutex,  Up: Threads

20.16 al_destroy_mutex
======================

void al_destroy_mutex(ALLEGRO_MUTEX *mutex)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L341)

Free the resources used by the mutex.  The mutex should be unlocked.
Destroying a locked mutex results in undefined behaviour.

Does nothing if ‘mutex’ is ‘NULL’.


File: refman.info,  Node: al_create_cond,  Next: al_destroy_cond,  Prev: al_destroy_mutex,  Up: Threads

20.17 al_create_cond
====================

ALLEGRO_COND *al_create_cond(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L352)

Create a condition variable.

Returns the condition value on success or ‘NULL’ on error.


File: refman.info,  Node: al_destroy_cond,  Next: al_wait_cond,  Prev: al_create_cond,  Up: Threads

20.18 al_destroy_cond
=====================

void al_destroy_cond(ALLEGRO_COND *cond)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L364)

Destroy a condition variable.

Destroying a condition variable which has threads block on it results in
undefined behaviour.

Does nothing if ‘cond’ is ‘NULL’.


File: refman.info,  Node: al_wait_cond,  Next: al_wait_cond_until,  Prev: al_destroy_cond,  Up: Threads

20.19 al_wait_cond
==================

void al_wait_cond(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L375)

On entering this function, ‘mutex’ must be locked by the calling thread.
The function will atomically release ‘mutex’ and block on ‘cond’.  The
function will return when ‘cond’ is “signalled”, acquiring the lock on
the mutex in the process.

Example of proper use:

al_lock_mutex(mutex);
while (something_not_true) {
   al_wait_cond(cond, mutex);
}
do_something();
al_unlock_mutex(mutex);

The mutex should be locked before checking the condition, and should be
rechecked *note al_wait_cond: #al_wait_cond. returns.  *note
al_wait_cond: #al_wait_cond. can return for other reasons than the
condition becoming true (e.g. the process was signalled).  If multiple
threads are blocked on the condition variable, the condition may no
longer be true by the time the second and later threads are unblocked.
Remember not to unlock the mutex prematurely.

See also: *note al_wait_cond_until: #al_wait_cond_until, *note
al_broadcast_cond: #al_broadcast_cond, *note al_signal_cond:
#al_signal_cond.


File: refman.info,  Node: al_wait_cond_until,  Next: al_broadcast_cond,  Prev: al_wait_cond,  Up: Threads

20.20 al_wait_cond_until
========================

int al_wait_cond_until(ALLEGRO_COND *cond, ALLEGRO_MUTEX *mutex,
   const ALLEGRO_TIMEOUT *timeout)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L386)

Like *note al_wait_cond: #al_wait_cond. but the call can return if the
absolute time passes ‘timeout’ before the condition is signalled.

Returns zero on success, non-zero if the call timed out.

See also: *note al_wait_cond: #al_wait_cond.


File: refman.info,  Node: al_broadcast_cond,  Next: al_signal_cond,  Prev: al_wait_cond_until,  Up: Threads

20.21 al_broadcast_cond
=======================

void al_broadcast_cond(ALLEGRO_COND *cond)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L399)

Unblock all threads currently waiting on a condition variable.  That is,
broadcast that some condition which those threads were waiting for has
become true.

See also: *note al_signal_cond: #al_signal_cond.

     _Note:_ The pthreads spec says to lock the mutex associated with
     ‘cond’ before signalling for predictable scheduling behaviour.


File: refman.info,  Node: al_signal_cond,  Prev: al_broadcast_cond,  Up: Threads

20.22 al_signal_cond
====================

void al_signal_cond(ALLEGRO_COND *cond)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/threads.c#L409)

Unblock at least one thread waiting on a condition variable.

Generally you should use *note al_broadcast_cond: #al_broadcast_cond.
but *note al_signal_cond: #al_signal_cond. may be more efficient when
it’s applicable.

See also: *note al_broadcast_cond: #al_broadcast_cond.


File: refman.info,  Node: Time routines,  Next: Timer routines,  Prev: Threads,  Up: Top

21 Time routines
****************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_TIMEOUT::
* al_get_time::
* al_init_timeout::
* al_rest::


File: refman.info,  Node: ALLEGRO_TIMEOUT,  Next: al_get_time,  Up: Time routines

21.1 ALLEGRO_TIMEOUT
====================

typedef struct ALLEGRO_TIMEOUT ALLEGRO_TIMEOUT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/altime.h#L12)

Represent a timeout value.  The size of the structure is known so it can
be statically allocated.  The contents are private.

See also: *note al_init_timeout: #al_init_timeout.


File: refman.info,  Node: al_get_time,  Next: al_init_timeout,  Prev: ALLEGRO_TIMEOUT,  Up: Time routines

21.2 al_get_time
================

double al_get_time(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L503)

Return 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.


File: refman.info,  Node: al_init_timeout,  Next: al_rest,  Prev: al_get_time,  Up: Time routines

21.3 al_init_timeout
====================

void al_init_timeout(ALLEGRO_TIMEOUT *timeout, double seconds)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L526)

Set 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.

See also: *note ALLEGRO_TIMEOUT: #allegro_timeout, *note
al_wait_for_event_until: #al_wait_for_event_until.


File: refman.info,  Node: al_rest,  Prev: al_init_timeout,  Up: Time routines

21.4 al_rest
============

void al_rest(double seconds)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/system.c#L515)

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

al_rest(0.000001)

might pause for something like 10ms.  Also see the section on Timer
routines for easier ways to time your program without using up all CPU.


File: refman.info,  Node: Timer routines,  Next: Touch input,  Prev: Time routines,  Up: Top

22 Timer routines
*****************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_TIMER::
* ALLEGRO_USECS_TO_SECS::
* ALLEGRO_MSECS_TO_SECS::
* ALLEGRO_BPS_TO_SECS::
* ALLEGRO_BPM_TO_SECS::
* al_create_timer::
* al_start_timer::
* al_resume_timer::
* al_stop_timer::
* al_get_timer_started::
* al_destroy_timer::
* al_get_timer_count::
* al_set_timer_count::
* al_add_timer_count::
* al_get_timer_speed::
* al_set_timer_speed::
* al_get_timer_event_source::


File: refman.info,  Node: ALLEGRO_TIMER,  Next: ALLEGRO_USECS_TO_SECS,  Up: Timer routines

22.1 ALLEGRO_TIMER
==================

typedef struct ALLEGRO_TIMER ALLEGRO_TIMER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/timer.h#L46)

This is an abstract data type representing a timer object.


File: refman.info,  Node: ALLEGRO_USECS_TO_SECS,  Next: ALLEGRO_MSECS_TO_SECS,  Prev: ALLEGRO_TIMER,  Up: Timer routines

22.2 ALLEGRO_USECS_TO_SECS
==========================

#define ALLEGRO_USECS_TO_SECS(x)      ((x) / 1000000.0)

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/timer.h#L29)

Convert microseconds to seconds.


File: refman.info,  Node: ALLEGRO_MSECS_TO_SECS,  Next: ALLEGRO_BPS_TO_SECS,  Prev: ALLEGRO_USECS_TO_SECS,  Up: Timer routines

22.3 ALLEGRO_MSECS_TO_SECS
==========================

#define ALLEGRO_MSECS_TO_SECS(x)      ((x) / 1000.0)

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/timer.h#L33)

Convert milliseconds to seconds.


File: refman.info,  Node: ALLEGRO_BPS_TO_SECS,  Next: ALLEGRO_BPM_TO_SECS,  Prev: ALLEGRO_MSECS_TO_SECS,  Up: Timer routines

22.4 ALLEGRO_BPS_TO_SECS
========================

#define ALLEGRO_BPS_TO_SECS(x)        (1.0 / (x))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/timer.h#L37)

Convert beats per second to seconds.


File: refman.info,  Node: ALLEGRO_BPM_TO_SECS,  Next: al_create_timer,  Prev: ALLEGRO_BPS_TO_SECS,  Up: Timer routines

22.5 ALLEGRO_BPM_TO_SECS
========================

#define ALLEGRO_BPM_TO_SECS(x)        (60.0 / (x))

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/timer.h#L41)

Convert beats per minute to seconds.


File: refman.info,  Node: al_create_timer,  Next: al_start_timer,  Prev: ALLEGRO_BPM_TO_SECS,  Up: Timer routines

22.6 al_create_timer
====================

ALLEGRO_TIMER *al_create_timer(double speed_secs)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L229)

Allocates and initializes a timer.  If successful, a pointer to a new
timer object is returned, otherwise NULL is returned.  _speed_secs_ is
in seconds per “tick”, and must be positive.  The new timer is initially
stopped.

Usage note: typical granularity is on the order of microseconds, but
with some drivers might only be milliseconds.

See also: *note al_start_timer: #al_start_timer, *note al_destroy_timer:
#al_destroy_timer.


File: refman.info,  Node: al_start_timer,  Next: al_resume_timer,  Prev: al_create_timer,  Up: Timer routines

22.7 al_start_timer
===================

void al_start_timer(ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L272)

Start 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.

See also: *note al_stop_timer: #al_stop_timer, *note
al_get_timer_started: #al_get_timer_started, *note al_resume_timer:
#al_resume_timer.


File: refman.info,  Node: al_resume_timer,  Next: al_stop_timer,  Prev: al_start_timer,  Up: Timer routines

22.8 al_resume_timer
====================

void al_resume_timer(ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L281)

Resume 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
al_start_timer).

See also: *note al_start_timer: #al_start_timer, *note al_stop_timer:
#al_stop_timer, *note al_get_timer_started: #al_get_timer_started.


File: refman.info,  Node: al_stop_timer,  Next: al_get_timer_started,  Prev: al_resume_timer,  Up: Timer routines

22.9 al_stop_timer
==================

void al_stop_timer(ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L290)

Stop 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.

See also: *note al_start_timer: #al_start_timer, *note
al_get_timer_started: #al_get_timer_started, *note al_resume_timer:
#al_resume_timer.


File: refman.info,  Node: al_get_timer_started,  Next: al_destroy_timer,  Prev: al_stop_timer,  Up: Timer routines

22.10 al_get_timer_started
==========================

bool al_get_timer_started(const ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L310)

Return true if the timer specified is currently started.


File: refman.info,  Node: al_destroy_timer,  Next: al_get_timer_count,  Prev: al_get_timer_started,  Up: Timer routines

22.11 al_destroy_timer
======================

void al_destroy_timer(ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L256)

Uninstall 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 NULL pointer.

See also: *note al_create_timer: #al_create_timer.


File: refman.info,  Node: al_get_timer_count,  Next: al_set_timer_count,  Prev: al_destroy_timer,  Up: Timer routines

22.12 al_get_timer_count
========================

int64_t al_get_timer_count(const ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L353)

Return the timer’s counter value.  The timer can be started or stopped.

See also: *note al_set_timer_count: #al_set_timer_count.


File: refman.info,  Node: al_set_timer_count,  Next: al_add_timer_count,  Prev: al_get_timer_count,  Up: Timer routines

22.13 al_set_timer_count
========================

void al_set_timer_count(ALLEGRO_TIMER *timer, int64_t new_count)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L364)

Set the timer’s counter value.  The timer can be started or stopped.
The count value may be positive or negative, but will always be
incremented by +1 at each tick.

See also: *note al_get_timer_count: #al_get_timer_count, *note
al_add_timer_count: #al_add_timer_count.


File: refman.info,  Node: al_add_timer_count,  Next: al_get_timer_speed,  Prev: al_set_timer_count,  Up: Timer routines

22.14 al_add_timer_count
========================

void al_add_timer_count(ALLEGRO_TIMER *timer, int64_t diff)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L379)

Add _diff_ to the timer’s counter value.  This is similar to writing:

al_set_timer_count(timer, al_get_timer_count(timer) + diff);

except that the addition is performed atomically, so no ticks will be
lost.

See also: *note al_set_timer_count: #al_set_timer_count.


File: refman.info,  Node: al_get_timer_speed,  Next: al_set_timer_speed,  Prev: al_add_timer_count,  Up: Timer routines

22.15 al_get_timer_speed
========================

double al_get_timer_speed(const ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L321)

Return the timer’s speed, in seconds.  (The same value passed to *note
al_create_timer: #al_create_timer. or *note al_set_timer_speed:
#al_set_timer_speed.)

See also: *note al_set_timer_speed: #al_set_timer_speed.


File: refman.info,  Node: al_set_timer_speed,  Next: al_get_timer_event_source,  Prev: al_get_timer_speed,  Up: Timer routines

22.16 al_set_timer_speed
========================

void al_set_timer_speed(ALLEGRO_TIMER *timer, double new_speed_secs)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L332)

Set 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.

_speed_secs_ has exactly the same meaning as with *note al_create_timer:
#al_create_timer.

See also: *note al_get_timer_speed: #al_get_timer_speed.


File: refman.info,  Node: al_get_timer_event_source,  Prev: al_set_timer_speed,  Up: Timer routines

22.17 al_get_timer_event_source
===============================

ALLEGRO_EVENT_SOURCE *al_get_timer_event_source(ALLEGRO_TIMER *timer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/timernu.c#L421)

Retrieve the associated event source.  Timers will generate events of
type *note ALLEGRO_EVENT_TIMER: #allegro_event_timer.


File: refman.info,  Node: Touch input,  Next: Transformations,  Prev: Timer routines,  Up: Top

23 Touch input
**************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_TOUCH_INPUT::
* ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT::
* ALLEGRO_TOUCH_STATE::
* ALLEGRO_TOUCH_INPUT_STATE::
* ALLEGRO_MOUSE_EMULATION_MODE::
* al_install_touch_input::
* al_uninstall_touch_input::
* al_is_touch_input_installed::
* al_get_touch_input_state::
* al_set_mouse_emulation_mode::
* al_get_mouse_emulation_mode::
* al_get_touch_input_event_source::
* al_get_touch_input_mouse_emulation_event_source::


File: refman.info,  Node: ALLEGRO_TOUCH_INPUT,  Next: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT,  Up: Touch input

23.1 ALLEGRO_TOUCH_INPUT
========================

typedef struct ALLEGRO_TOUCH_INPUT ALLEGRO_TOUCH_INPUT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/touch_input.h#L34)

An abstract data type representing a physical touch screen or touch pad.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT,  Next: ALLEGRO_TOUCH_STATE,  Prev: ALLEGRO_TOUCH_INPUT,  Up: Touch input

23.2 ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT
========================================

#define ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT        16

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/touch_input.h#L29)

The maximum amount of simultaneous touches that can be detected.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_TOUCH_STATE,  Next: ALLEGRO_TOUCH_INPUT_STATE,  Prev: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT,  Up: Touch input

23.3 ALLEGRO_TOUCH_STATE
========================

typedef struct ALLEGRO_TOUCH_STATE ALLEGRO_TOUCH_STATE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/touch_input.h#L44)

This is a structure that is used to hold a “snapshot” of a touch at a
particular instant.

Public fields (read only):

   • id - identifier of the touch.  If the touch is valid, this is
     positive.
   • x - touch x position
   • y - touch y position
   • dx - touch relative x position
   • dy - touch relative y position
   • primary - TRUE if this touch is the primary one (usually the first
     one).
   • display - The *note ALLEGRO_DISPLAY: #allegro_display. that was
     touched.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_TOUCH_INPUT_STATE,  Next: ALLEGRO_MOUSE_EMULATION_MODE,  Prev: ALLEGRO_TOUCH_STATE,  Up: Touch input

23.4 ALLEGRO_TOUCH_INPUT_STATE
==============================

typedef struct ALLEGRO_TOUCH_INPUT_STATE ALLEGRO_TOUCH_INPUT_STATE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/touch_input.h#L39)

This is a structure that holds a snapshot of all simultaneous touches at
a particular instant.

Public fields (read only):

   • touches - an array of *note ALLEGRO_TOUCH_STATE:
     #allegro_touch_state.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_MOUSE_EMULATION_MODE,  Next: al_install_touch_input,  Prev: ALLEGRO_TOUCH_INPUT_STATE,  Up: Touch input

23.5 ALLEGRO_MOUSE_EMULATION_MODE
=================================

typedef enum ALLEGRO_MOUSE_EMULATION_MODE

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/touch_input.h#L71)

Type of mouse emulation to apply.

ALLEGRO_MOUSE_EMULATION_NONE

     Disables mouse emulation.
ALLEGRO_MOUSE_EMULATION_TRANSPARENT

     Enables transparent mouse emulation.
ALLEGRO_MOUSE_EMULATION_INCLUSIVE

     Enable inclusive mouse emulation.
ALLEGRO_MOUSE_EMULATION_EXCLUSIVE

     Enables exclusive mouse emulation.
ALLEGRO_MOUSE_EMULATION_5_0_x

     Enables mouse emulation that is backwards compatible with Allegro
     5.0.x.

Since: 5.1.0

     _*note Unstable API: #unstable-api.:_ Seems of limited value, as
     touch input tends to have different semantics compared to mouse
     input.


File: refman.info,  Node: al_install_touch_input,  Next: al_uninstall_touch_input,  Prev: ALLEGRO_MOUSE_EMULATION_MODE,  Up: Touch input

23.6 al_install_touch_input
===========================

bool al_install_touch_input(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L43)

Install a touch input driver, returning true if successful.  If a touch
input driver was already installed, returns true immediately.

Since: 5.1.0

See also: *note al_uninstall_touch_input: #al_uninstall_touch_input.


File: refman.info,  Node: al_uninstall_touch_input,  Next: al_is_touch_input_installed,  Prev: al_install_touch_input,  Up: Touch input

23.7 al_uninstall_touch_input
=============================

void al_uninstall_touch_input(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L68)

Uninstalls the active touch input driver.  If no touch input driver was
active, this function does nothing.

This function is automatically called when Allegro is shut down.

Since: 5.1.0

See also: *note al_install_touch_input: #al_install_touch_input.


File: refman.info,  Node: al_is_touch_input_installed,  Next: al_get_touch_input_state,  Prev: al_uninstall_touch_input,  Up: Touch input

23.8 al_is_touch_input_installed
================================

bool al_is_touch_input_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L35)

Returns true if *note al_install_touch_input: #al_install_touch_input.
was called successfully.

Since: 5.1.0


File: refman.info,  Node: al_get_touch_input_state,  Next: al_set_mouse_emulation_mode,  Prev: al_is_touch_input_installed,  Up: Touch input

23.9 al_get_touch_input_state
=============================

void al_get_touch_input_state(ALLEGRO_TOUCH_INPUT_STATE *ret_state)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L93)

Gets the current touch input state.  The touch information is copied
into the *note ALLEGRO_TOUCH_INPUT_STATE: #allegro_touch_input_state.
you provide to this function.

Since: 5.1.0


File: refman.info,  Node: al_set_mouse_emulation_mode,  Next: al_get_mouse_emulation_mode,  Prev: al_get_touch_input_state,  Up: Touch input

23.10 al_set_mouse_emulation_mode
=================================

void al_set_mouse_emulation_mode(int mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L104)

Sets the kind of mouse emulation for the touch input subsystem to
perform.

Since: 5.1.0

     _*note Unstable API: #unstable-api.:_ Seems of limited value, as
     touch input tends to have different semantics compared to mouse
     input.
See also: *note ALLEGRO_MOUSE_EMULATION_MODE:
#allegro_mouse_emulation_mode, *note al_get_mouse_emulation_mode:
#al_get_mouse_emulation_mode.


File: refman.info,  Node: al_get_mouse_emulation_mode,  Next: al_get_touch_input_event_source,  Prev: al_set_mouse_emulation_mode,  Up: Touch input

23.11 al_get_mouse_emulation_mode
=================================

int al_get_mouse_emulation_mode(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L117)

Returns the kind of mouse emulation which the touch input subsystem is
set to perform.

Since: 5.1.0

     _*note Unstable API: #unstable-api.:_ Seems of limited value, as
     touch input tends to have different semantics compared to mouse
     input.
See also: *note ALLEGRO_MOUSE_EMULATION_MODE:
#allegro_mouse_emulation_mode, *note al_set_mouse_emulation_mode:
#al_set_mouse_emulation_mode.


File: refman.info,  Node: al_get_touch_input_event_source,  Next: al_get_touch_input_mouse_emulation_event_source,  Prev: al_get_mouse_emulation_mode,  Up: Touch input

23.12 al_get_touch_input_event_source
=====================================

ALLEGRO_EVENT_SOURCE *al_get_touch_input_event_source(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L130)

Returns the global touch input event source.  This event source
generates *note touch input events: #allegro_event_touch_begin.

Since: 5.1.0

See also: *note ALLEGRO_EVENT_SOURCE: #allegro_event_source, *note
al_register_event_source: #al_register_event_source.


File: refman.info,  Node: al_get_touch_input_mouse_emulation_event_source,  Prev: al_get_touch_input_event_source,  Up: Touch input

23.13 al_get_touch_input_mouse_emulation_event_source
=====================================================

ALLEGRO_EVENT_SOURCE *al_get_touch_input_mouse_emulation_event_source(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/touch_input.c#L140)

Returns the global touch input event source for emulated mouse events.
This event source generates *note emulated mouse events:
#allegro_event_mouse_axes. that are based on touch events.

See also: *note ALLEGRO_EVENT_SOURCE: #allegro_event_source, *note
al_register_event_source: #al_register_event_source.

Since: 5.1.0

     _*note Unstable API: #unstable-api.:_ Seems of limited value, as
     touch input tends to have different semantics compared to mouse
     input.


File: refman.info,  Node: Transformations,  Next: UTF-8 string routines,  Prev: Touch input,  Up: Top

24 Transformations
******************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

Transformations allow you to transform the coordinates you use for
drawing operations without additional overhead.  Scaling, rotating,
translating, and combinations of these are possible as well as using
custom transformations.  There are two types of transformations that you
can set, ‘regular’ transformations and projection transformations.  The
projection transform is rarely used in 2D games, but is common in 3D
games to set up the projection from the 3D world to the 2D screen.
Typically, you would use the regular transform for non-projective types
of transformations (that is, translations, rotations, scales, skews...
i.e. transformations that are linear), while the projection transform
will be used for setting up perspective and possibly more advanced
effects.  It is possible to do everything with just using the projection
transformation (that is, you’d compose the projection transformation
with the non-projection transformations that, e.g., move the camera in
the world), but it is more convenient to use both for two reasons:

   • Regular transformations can be changed while the bitmap drawing is
     held (see *note al_hold_bitmap_drawing: #al_hold_bitmap_drawing.).

   • Regular transformations work with memory bitmaps.

As a result, if you’re making a 2D game, it’s best to leave the
projection transformations at their default values.

Both types of transformations are set per target-bitmap, i.e. a change
of the target bitmap will also change the active transformation.

Allegro provides convenience functions to construct transformations in
2D and 3D variants (the latter with a ‘_3d’ suffix), so you don’t have
to deal with the underlying matrix algebra yourself.

The transformations are combined in the order of the function
invocations.  Thus to create a transformation that first rotates a point
and then translates it, you would (starting with an identity
transformation) call *note al_rotate_transform: #al_rotate_transform.
and then *note al_translate_transform: #al_translate_transform.  This
approach is opposite of what OpenGL uses but similar to what Direct3D
uses.

For those who know the matrix algebra going behind the scenes, what the
transformation functions in Allegro do is “pre-multiply” the successive
transformations.  So, for example, if you have code that does:

al_identity_transform(&T);

al_compose_transform(&T, &T1);
al_compose_transform(&T, &T2);
al_compose_transform(&T, &T3);
al_compose_transform(&T, &T4);

The resultant matrix multiplication expression will look like this:

T4 * T3 * T2 * T1

Since the point coordinate vector term will go on the right of that
sequence of factors, the transformation that is called first, will also
be applied first.

This means if you have code like this:

al_identity_transform(&T1);
al_scale_transform(&T1, 2, 2);
al_identity_transform(&T2);
al_translate_transform(&T2, 100, 0);

al_identity_transform(&T);

al_compose_transform(&T, &T1);
al_compose_transform(&T, &T2);

al_use_transform(&T);

it does exactly the same as:

al_identity_transform(&T);
al_scale_transform(&T, 2, 2);
al_translate_transform(&T, 100, 0);
al_use_transform(&T);

* Menu:

* ALLEGRO_TRANSFORM::
* al_copy_transform::
* al_use_transform::
* al_get_current_transform::
* al_use_projection_transform::
* al_get_current_projection_transform::
* al_get_current_inverse_transform::
* al_invert_transform::
* al_transpose_transform::
* al_check_inverse::
* al_identity_transform::
* al_build_transform::
* al_build_camera_transform::
* al_translate_transform::
* al_rotate_transform::
* al_scale_transform::
* al_transform_coordinates::
* al_transform_coordinates_3d::
* al_transform_coordinates_4d::
* al_transform_coordinates_3d_projective::
* al_compose_transform::
* al_orthographic_transform::
* al_perspective_transform::
* al_translate_transform_3d::
* al_scale_transform_3d::
* al_rotate_transform_3d::
* al_horizontal_shear_transform::
* al_vertical_shear_transform::


File: refman.info,  Node: ALLEGRO_TRANSFORM,  Next: al_copy_transform,  Up: Transformations

24.1 ALLEGRO_TRANSFORM
======================

typedef struct ALLEGRO_TRANSFORM ALLEGRO_TRANSFORM;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/transformations.h#L12)

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.

_Fields:_

   • m - A 4x4 float matrix


File: refman.info,  Node: al_copy_transform,  Next: al_use_transform,  Prev: ALLEGRO_TRANSFORM,  Up: Transformations

24.2 al_copy_transform
======================

void al_copy_transform(ALLEGRO_TRANSFORM *dest, const ALLEGRO_TRANSFORM *src)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L30)

Makes a copy of a transformation.

_Parameters:_

   • dest - Source transformation
   • src - Destination transformation


File: refman.info,  Node: al_use_transform,  Next: al_get_current_transform,  Prev: al_copy_transform,  Up: Transformations

24.3 al_use_transform
=====================

void al_use_transform(const ALLEGRO_TRANSFORM *trans)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L40)

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.

void setup_my_transformation(void)
{
   ALLEGRO_TRANSFORM transform;
   al_translate_transform(&transform, 5, 10);
   al_use_transform(&transform);
}

_Parameters:_

   • trans - Transformation to use

See also: *note al_get_current_transform: #al_get_current_transform,
*note al_transform_coordinates: #al_transform_coordinates.


File: refman.info,  Node: al_get_current_transform,  Next: al_use_projection_transform,  Prev: al_use_transform,  Up: Transformations

24.4 al_get_current_transform
=============================

const ALLEGRO_TRANSFORM *al_get_current_transform(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L104)

Returns the transformation of the current target bitmap, as set by *note
al_use_transform: #al_use_transform.  If there is no target bitmap, this
function returns NULL.

_Returns:_ A pointer to the current transformation.

See also: *note al_get_current_projection_transform:
#al_get_current_projection_transform.


File: refman.info,  Node: al_use_projection_transform,  Next: al_get_current_projection_transform,  Prev: al_get_current_transform,  Up: Transformations

24.5 al_use_projection_transform
================================

void al_use_projection_transform(const ALLEGRO_TRANSFORM *trans)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L74)

Sets the projection transformation to be used for 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:

ALLEGRO_TRANSFORM trans;
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);

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.

Since: 5.1.9

See also: *note al_get_current_projection_transform:
#al_get_current_projection_transform, *note al_perspective_transform:
#al_perspective_transform, *note al_orthographic_transform:
#al_orthographic_transform.


File: refman.info,  Node: al_get_current_projection_transform,  Next: al_get_current_inverse_transform,  Prev: al_use_projection_transform,  Up: Transformations

24.6 al_get_current_projection_transform
========================================

const ALLEGRO_TRANSFORM *al_get_current_projection_transform(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L116)

If there is no target bitmap, this function returns NULL.

_Returns:_ A pointer to the current transformation.

Since: 5.1.9

See also: *note al_use_projection_transform:
#al_use_projection_transform.


File: refman.info,  Node: al_get_current_inverse_transform,  Next: al_invert_transform,  Prev: al_get_current_projection_transform,  Up: Transformations

24.7 al_get_current_inverse_transform
=====================================

const ALLEGRO_TRANSFORM *al_get_current_inverse_transform(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L128)

Returns the inverse of the current transformation of the target bitmap.
If there is no target bitmap, this function returns NULL.

This is similar to calling
‘al_invert_transform(al_get_current_transform())’ but the result of this
function is cached.

     _Note_: Allegro’s transformation inversion functions work correctly
     only with 2D transformations.
Since: 5.1.0


File: refman.info,  Node: al_invert_transform,  Next: al_transpose_transform,  Prev: al_get_current_inverse_transform,  Up: Transformations

24.8 al_invert_transform
========================

void al_invert_transform(ALLEGRO_TRANSFORM *trans)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L272)

Inverts the passed transformation.  If the transformation is nearly
singular (close to not having an inverse) then the returned
transformation may be invalid.  Use *note al_check_inverse:
#al_check_inverse. to ascertain if the transformation has an inverse
before inverting it if you are in doubt.

_Parameters:_

   • trans - Transformation to invert

     _Note_: Allegro’s transformation inversion functions work correctly
     only with 2D transformations.
See also: *note al_check_inverse: #al_check_inverse.


File: refman.info,  Node: al_transpose_transform,  Next: al_check_inverse,  Prev: al_invert_transform,  Up: Transformations

24.9 al_transpose_transform
===========================

void al_transpose_transform(ALLEGRO_TRANSFORM *trans)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L293)

Transposes the matrix of the given transform.  This can be used for
inversing a rotation transform.  For example:

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.

Since: 5.2.5


File: refman.info,  Node: al_check_inverse,  Next: al_identity_transform,  Prev: al_transpose_transform,  Up: Transformations

24.10 al_check_inverse
======================

int al_check_inverse(const ALLEGRO_TRANSFORM *trans, float tol)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L308)

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.

_Parameters:_

   • trans - Transformation to check
   • tol - Tolerance

_Returns:_ 1 if the transformation is invertible, 0 otherwise

     _Note_: Allegro’s transformation inversion functions work correctly
     only with 2D transformations.
See also: *note al_invert_transform: #al_invert_transform.


File: refman.info,  Node: al_identity_transform,  Next: al_build_transform,  Prev: al_check_inverse,  Up: Transformations

24.11 al_identity_transform
===========================

void al_identity_transform(ALLEGRO_TRANSFORM *trans)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L145)

Sets the transformation to be the identity transformation.  This is the
default transformation.  Use *note al_use_transform: #al_use_transform.
on an identity transformation to return to the default.

ALLEGRO_TRANSFORM t;
al_identity_transform(&t);
al_use_transform(&t);

_Parameters:_

   • trans - Transformation to alter

See also: *note al_translate_transform: #al_translate_transform, *note
al_rotate_transform: #al_rotate_transform, *note al_scale_transform:
#al_scale_transform.


File: refman.info,  Node: al_build_transform,  Next: al_build_camera_transform,  Prev: al_identity_transform,  Up: Transformations

24.12 al_build_transform
========================

void al_build_transform(ALLEGRO_TRANSFORM *trans, float x, float y,
   float sx, float sy, float theta)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L172)

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.

_Parameters:_

   • trans - Transformation to alter
   • x, y - Translation
   • sx, sy - Scale
   • theta - Rotation angle in radians

     _Note_: this function was previously documented to be equivalent to
     a different (and more useful) order of operations: identity, scale,
     rotate, translate.
See also: *note al_translate_transform: #al_translate_transform, *note
al_rotate_transform: #al_rotate_transform, *note al_scale_transform:
#al_scale_transform, *note al_compose_transform: #al_compose_transform.


File: refman.info,  Node: al_build_camera_transform,  Next: al_translate_transform,  Prev: al_build_transform,  Up: Transformations

24.13 al_build_camera_transform
===============================

void al_build_camera_transform(ALLEGRO_TRANSFORM *trans,
   float position_x, float position_y, float position_z,
   float look_x, float look_y, float look_z,
   float up_x, float up_y, float up_z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L204)

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:

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.

     _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:

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:

al_build_camera_transform(&t,
    1, 1, 1,
    5, 5, 5,
    1, 1, 0);

Since 5.1.9

See also: *note al_translate_transform_3d: #al_translate_transform_3d,
*note al_rotate_transform_3d: #al_rotate_transform_3d, *note
al_scale_transform_3d: #al_scale_transform_3d, *note
al_compose_transform: #al_compose_transform, *note al_use_transform:
#al_use_transform.


File: refman.info,  Node: al_translate_transform,  Next: al_rotate_transform,  Prev: al_build_camera_transform,  Up: Transformations

24.14 al_translate_transform
============================

void al_translate_transform(ALLEGRO_TRANSFORM *trans, float x, float y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L327)

Apply a translation to a transformation.

_Parameters:_

   • trans - Transformation to alter
   • x, y - Translation

See also: *note al_rotate_transform: #al_rotate_transform, *note
al_scale_transform: #al_scale_transform, *note al_build_transform:
#al_build_transform.


File: refman.info,  Node: al_rotate_transform,  Next: al_scale_transform,  Prev: al_translate_transform,  Up: Transformations

24.15 al_rotate_transform
=========================

void al_rotate_transform(ALLEGRO_TRANSFORM *trans, float theta)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L351)

Apply a rotation to a transformation.

_Parameters:_

   • trans - Transformation to alter
   • theta - Rotation angle in radians

See also: *note al_translate_transform: #al_translate_transform, *note
al_scale_transform: #al_scale_transform, *note al_build_transform:
#al_build_transform.


File: refman.info,  Node: al_scale_transform,  Next: al_transform_coordinates,  Prev: al_rotate_transform,  Up: Transformations

24.16 al_scale_transform
========================

void al_scale_transform(ALLEGRO_TRANSFORM *trans, float sx, float sy)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L375)

Apply a scale to a transformation.

_Parameters:_

   • trans - Transformation to alter
   • sx, sy - Scale

See also: *note al_translate_transform: #al_translate_transform, *note
al_rotate_transform: #al_rotate_transform, *note al_build_transform:
#al_build_transform.


File: refman.info,  Node: al_transform_coordinates,  Next: al_transform_coordinates_3d,  Prev: al_scale_transform,  Up: Transformations

24.17 al_transform_coordinates
==============================

void al_transform_coordinates(const ALLEGRO_TRANSFORM *trans, float *x, float *y)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L416)

Transform a pair of coordinates.

_Parameters:_

   • trans - Transformation to use
   • x, y - Pointers to the coordinates

See also: *note al_use_transform: #al_use_transform, *note
al_transform_coordinates_3d: #al_transform_coordinates_3d.


File: refman.info,  Node: al_transform_coordinates_3d,  Next: al_transform_coordinates_4d,  Prev: al_transform_coordinates,  Up: Transformations

24.18 al_transform_coordinates_3d
=================================

void al_transform_coordinates_3d(const ALLEGRO_TRANSFORM *trans,
   float *x, float *y, float *z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L431)

Transform x, y, z coordinates.

_Parameters:_

   • trans - Transformation to use
   • x, y, z - Pointers to the coordinates

Note: If you are using a projection transform you most likely will want
to use *note al_transform_coordinates_3d_projective:
#al_transform_coordinates_3d_projective. instead.

Since 5.1.9

See also: *note al_use_transform: #al_use_transform, *note
al_transform_coordinates: #al_transform_coordinates.


File: refman.info,  Node: al_transform_coordinates_4d,  Next: al_transform_coordinates_3d_projective,  Prev: al_transform_coordinates_3d,  Up: Transformations

24.19 al_transform_coordinates_4d
=================================

void al_transform_coordinates_4d(const ALLEGRO_TRANSFORM *trans,
   float *x, float *y, float *z, float *w)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L455)

Transform x, y, z, w coordinates.

_Parameters:_

   • trans - Transformation to use
   • x, y, z, w - Pointers to the coordinates

Since 5.2.4

See also: *note al_use_transform: #al_use_transform, *note
al_transform_coordinates: #al_transform_coordinates, *note
al_transform_coordinates_3d: #al_transform_coordinates_3d.


File: refman.info,  Node: al_transform_coordinates_3d_projective,  Next: al_compose_transform,  Prev: al_transform_coordinates_4d,  Up: Transformations

24.20 al_transform_coordinates_3d_projective
============================================

void al_transform_coordinates_3d_projective(const ALLEGRO_TRANSFORM *trans,
   float *x, float *y, float *z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L482)

Transform x, y, z as homogeneous coordinates.  This is the same as using
*note al_transform_coordinates_4d: #al_transform_coordinates_4d. with
the w coordinate set to 1, then dividing x, y, z by the resulting w.
This will provide the same normalized coordinates Allegro will draw to
when a projective transform is in effect as set with *note
al_use_projection_transform: #al_use_projection_transform.  To get the
actual pixel coordinates from those translate and scale like so (w and h
would be the pixel dimensions of the target bitmap):

x = w / 2 + x * w / 2
y = h / 2 - y * h / 2

_Parameters:_

   • trans - Transformation to use
   • x, y, z - Pointers to the coordinates

Example:

ALLEGRO_TRANSFORM t2;
al_copy_transform(&t2, al_get_current_transform());
al_compose_transform(&t2, al_get_current_projection_transform());

ALLEGRO_TRANSFORM t3;
al_identity_transform(&t3);
al_scale_transform(&t3, 0.5, -0.5);
al_translate_transform(&t3, 0.5, 0.5);
al_scale_transform(&t3, al_get_bitmap_width(al_get_target_bitmap()),
                   al_get_bitmap_height(al_get_target_bitmap()));

al_transform_coordinates_3d_projective(&t2, &x, &y, &z);
// x, y now contain normalized coordinates
al_transform_coordinates(&t3, &x, &y);
// x, y now contain pixel coordinates

Since 5.2.4

See also: *note al_use_transform: #al_use_transform, *note
al_transform_coordinates: #al_transform_coordinates, *note
al_transform_coordinates_3d: #al_transform_coordinates_3d, *note
al_use_projection_transform: #al_use_projection_transform.


File: refman.info,  Node: al_compose_transform,  Next: al_orthographic_transform,  Prev: al_transform_coordinates_3d_projective,  Up: Transformations

24.21 al_compose_transform
==========================

void al_compose_transform(ALLEGRO_TRANSFORM *trans, const ALLEGRO_TRANSFORM *other)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L494)

Compose (combine) two transformations by a matrix multiplication.

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 ‘trans’
and then applying ‘other’ and not the other way around.

_Parameters:_

   • trans - Transformation to alter
   • other - Transformation used to transform ‘trans’

See also: *note al_translate_transform: #al_translate_transform, *note
al_rotate_transform: #al_rotate_transform, *note al_scale_transform:
#al_scale_transform.


File: refman.info,  Node: al_orthographic_transform,  Next: al_perspective_transform,  Prev: al_compose_transform,  Up: Transformations

24.22 al_orthographic_transform
===============================

void al_orthographic_transform(ALLEGRO_TRANSFORM *trans,
   float left, float top, float n,
   float right, float bottom, float f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L540)

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 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.

The result of applying this transformation to coordinates will be to
normalize visible coordinates into the cube from -1/-1/-1 to 1/1/1.
Such a transformation is mostly useful for passing it to *note
al_use_projection_transform: #al_use_projection_transform. - see that
function for an example use.

Since: 5.1.3

See also: *note al_use_projection_transform:
#al_use_projection_transform, *note al_perspective_transform:
#al_perspective_transform.


File: refman.info,  Node: al_perspective_transform,  Next: al_translate_transform_3d,  Prev: al_orthographic_transform,  Up: Transformations

24.23 al_perspective_transform
==============================

void al_perspective_transform(ALLEGRO_TRANSFORM *trans,
   float left, float top, float n,
   float right, float bottom, float f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L601)

Like *note al_orthographic_transform: #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:

tan(hfov / 2) = (right - left) / 2 / near

and therefore

near = (right - left) / 2 / tan(hfov / 2)

Example 1:

   float w = 800, h = 450; // assume our display is 800 x 450
   float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view

   // Our projection goes from 0/0 to w/h with the near parameter set
   // for a 90 degree horizontal viewing angle.
   ALLEGRO_TRANSFORM projection;
   al_identity_transform(&projection);
   al_perspective_transform(&projection, 0, 0,
    w / 2 / fov,
    w, h,
    2000);
   al_use_projection_transform(&projection);

   // Set the camera z to +400 (which is exactly the near distance)
   ALLEGRO_TRANSFORM camera;
   al_build_camera_transform(&camera, 0, 0, 400, 0, 0, 0, 0, 1, 0);
   al_use_transform(&camera);

   // This will draw two rectangles at the left and right edge of the
   // screen and vertically centered. The x distance between them is 800
   // units, but the camera transform moves them 400 along z, so with
   // a 90° viewing angle both are visible.
   al_draw_filled_rectangle(0, 200, 50, 250, red;
   al_draw_filled_rectangle(750, 200, 800, 250, red);

Example 2:

   float w = 800, h = 450; // assume our display is 800 x 450
   float fov = tan(90 * ALLEGRO_PI / 180 / 2); // 90 degree field of view
   float aspect = h / w;
   float zoom = 2; // enlarge x 2

   // This projection is very different from the one in the first example.
   // Here we map the left and right edge of the screen to -1 and +1. And
   // the y axis goes from -1 at the bottom to +1 at the top, scaled by
   // the aspect ratio. We also add a zoom parameter so we can control
   // the visible portion of the scene independent of the field of view.
   ALLEGRO_TRANSFORM projection;
   al_identity_transform(&projection);
   al_perspective_transform(&projection,
      -1 / zoom, aspect / zoom,
      1 / fov,
      1 / zoom, -aspect / zoom,
      2000);
   al_use_projection_transform(&projection);

   // Moves everything by -4 in the z direction.
   ALLEGRO_TRANSFORM camera;
   al_build_camera_transform(&camera, 0, 0, 4, 0, 0, 0, 0, 1, 0);
   al_use_transform(&camera);

   // At a z distance of 4 with a 90° hfov everything would be scaled
   // down to 25%. However we also zoom 2-fold, so the final scaling is
   // 50%. This rectangle therefore will appear at a size of 400 x 225
   // pixel (assuming the display is 800 x 450).
   al_draw_filled_rectangle(-1, -1, 1, 1, red);

Since: 5.1.3

See also: *note al_use_projection_transform:
#al_use_projection_transform, *note al_orthographic_transform:
#al_orthographic_transform.


File: refman.info,  Node: al_translate_transform_3d,  Next: al_scale_transform_3d,  Prev: al_perspective_transform,  Up: Transformations

24.24 al_translate_transform_3d
===============================

void al_translate_transform_3d(ALLEGRO_TRANSFORM *trans, float x, float y,
    float z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L338)

Combines the given transformation with a transformation which translates
coordinates by the given vector.

Since: 5.1.3

See also: *note al_use_projection_transform:
#al_use_projection_transform.


File: refman.info,  Node: al_scale_transform_3d,  Next: al_rotate_transform_3d,  Prev: al_translate_transform_3d,  Up: Transformations

24.25 al_scale_transform_3d
===========================

void al_scale_transform_3d(ALLEGRO_TRANSFORM *trans, float sx, float sy,
    float sz)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L392)

Combines the given transformation with a transformation which scales
coordinates by the given vector.

Since: 5.1.3

See also: *note al_use_projection_transform:
#al_use_projection_transform.


File: refman.info,  Node: al_rotate_transform_3d,  Next: al_horizontal_shear_transform,  Prev: al_scale_transform_3d,  Up: Transformations

24.26 al_rotate_transform_3d
============================

void al_rotate_transform_3d(ALLEGRO_TRANSFORM *trans,
   float x, float y, float z, float angle)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L565)

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).

Since: 5.1.3


File: refman.info,  Node: al_horizontal_shear_transform,  Next: al_vertical_shear_transform,  Prev: al_rotate_transform_3d,  Up: Transformations

24.27 al_horizontal_shear_transform
===================================

void al_horizontal_shear_transform(ALLEGRO_TRANSFORM* trans, float theta)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L626)

Apply a horizontal shear to the transform

_Parameters:_

   • trans - Transformation to alter
   • theta - Rotation angle in radians

Since: 5.1.7

See also: *note al_vertical_shear_transform:
#al_vertical_shear_transform.


File: refman.info,  Node: al_vertical_shear_transform,  Prev: al_horizontal_shear_transform,  Up: Transformations

24.28 al_vertical_shear_transform
=================================

void al_vertical_shear_transform(ALLEGRO_TRANSFORM* trans, float theta)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/transformations.c#L640)

Apply a vertical shear to the transform

_Parameters:_

   • trans - Transformation to alter
   • theta - Rotation angle in radians

Since: 5.1.7

See also: *note al_horizontal_shear_transform:
#al_horizontal_shear_transform.


File: refman.info,  Node: UTF-8 string routines,  Next: Platform-specific functions,  Prev: Transformations,  Up: Top

25 UTF-8 string routines
************************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* About UTF-8 string routines::
* UTF-8 string types::
* Creating and destroying strings::
* Predefined strings::
* Creating strings by referencing other data::
* Sizes and offsets::
* Getting code points::
* Inserting into strings::
* Appending to strings::
* Removing parts of strings::
* Assigning one string to another::
* Replacing parts of string::
* Searching::
* Comparing::
* UTF-16 conversion::
* Low-level UTF-8 routines::
* Low-level UTF-16 routines::


File: refman.info,  Node: About UTF-8 string routines,  Next: UTF-8 string types,  Up: UTF-8 string routines

25.1 About UTF-8 string routines
================================

Some parts of the Allegro API, such as the font rountines, expect
Unicode strings encoded in UTF-8.  The following basic routines are
provided to help you work with UTF-8 strings, however it does _not_ mean
you need to use them.  You should consider another library (e.g. ICU) if
you require more functionality.

Briefly, Unicode is a standard consisting of a large character set of
over 100,000 characters, and rules, such as how to sort strings.  A
_code point_ is the integer value of a character, but not all code
points are characters, as some code points have other uses.  Unlike
legacy character sets, the set of code points is open ended and more are
assigned with time.

Clearly it is impossible to represent each code point with a 8-bit byte
(limited to 256 code points) or even a 16-bit integer (limited to 65536
code points).  It is possible to store code points in a 32-bit integers
but it is space inefficient, and not actually that useful (at least,
when handling the full complexity of Unicode; Allegro only does the very
basics).  There exist different Unicode Transformation Formats for
encoding code points into smaller _code units_.  The most important
transformation formats are UTF-8 and UTF-16.

UTF-8 is a _variable-length encoding_ which encodes each code point to
between one and four 8-bit bytes each.  UTF-8 has many nice properties,
but the main advantages are that it is backwards compatible with C
strings, and ASCII characters (code points in the range 0-127) are
encoded in UTF-8 exactly as they would be in ASCII.

UTF-16 is another variable-length encoding, but encodes each code point
to one or two 16-bit words each.  It is, of course, not compatible with
traditional C strings.  Allegro does not generally use UTF-16 strings.

Here is a diagram of the representation of the word “ål”, with a NUL
terminator, in both UTF-8 and UTF-16.

                   ---------------- ---------------- --------------
           String         å                l              NUL
                   ---------------- ---------------- --------------
      Code points    U+00E5 (229)     U+006C (108)     U+0000 (0)
                   ---------------- ---------------- --------------
      UTF-8 bytes     0xC3, 0xA5          0x6C            0x00
                   ---------------- ---------------- --------------
   UTF-16LE bytes     0xE5, 0x00       0x6C, 0x00      0x00, 0x00
                   ---------------- ---------------- --------------

You can see the aforementioned properties of UTF-8.  The first code
point U+00E5 (“å”) is outside of the ASCII range (0-127) so is encoded
to multiple code units – it requires two bytes.  U+006C (“l”) and U+0000
(NUL) both exist in the ASCII range so take exactly one byte each, as in
a pure ASCII string.  A zero byte never appears except to represent the
NUL character, so many functions which expect C-style strings will work
with UTF-8 strings without modification.

On the other hand, UTF-16 represents each code point by either one or
two 16-bit code units (two or four bytes).  The representation of each
16-bit code unit depends on the byte order; here we have demonstrated
little endian.

Both UTF-8 and UTF-16 are self-synchronising.  Starting from any offset
within a string, it is efficient to find the beginning of the previous
or next code point.

Not all sequences of bytes or 16-bit words are valid UTF-8 and UTF-16
strings respectively.  UTF-8 also has an additional problem of overlong
forms, where a code point value is encoded using more bytes than is
strictly necessary.  This is invalid and needs to be guarded against.

In the following “ustr” functions, be careful whether a function takes
code unit (byte) or code point indices.  In general, all position
parameters are in code unit offsets.  This may be surprising, but if you
think about it, it is required for good performance.  (It also means
some functions will work even if they do not contain UTF-8, since they
only care about storing bytes, so you may actually store arbitrary data
in the ALLEGRO_USTRs.)

For actual text processing, where you want to specify positions with
code point indices, you should use *note al_ustr_offset:
#al_ustr_offset. to find the code unit offset position.  However, most
of the time you would probably just work with byte offsets.


File: refman.info,  Node: UTF-8 string types,  Next: Creating and destroying strings,  Prev: About UTF-8 string routines,  Up: UTF-8 string routines

25.2 UTF-8 string types
=======================

* Menu:

* ALLEGRO_USTR::
* ALLEGRO_USTR_INFO::


File: refman.info,  Node: ALLEGRO_USTR,  Next: ALLEGRO_USTR_INFO,  Up: UTF-8 string types

25.2.1 ALLEGRO_USTR
-------------------

typedef struct _al_tagbstring ALLEGRO_USTR;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/utf8.h#L12)

An opaque type representing a string.  ALLEGRO_USTRs normally contain
UTF-8 encoded strings, but they may be used to hold any byte sequences,
including NULs.


File: refman.info,  Node: ALLEGRO_USTR_INFO,  Prev: ALLEGRO_USTR,  Up: UTF-8 string types

25.2.2 ALLEGRO_USTR_INFO
------------------------

typedef struct _al_tagbstring ALLEGRO_USTR_INFO;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/utf8.h#L16)

A type that holds additional information for an *note ALLEGRO_USTR:
#allegro_ustr. that references an external memory buffer.

See also: *note al_ref_cstr: #al_ref_cstr, *note al_ref_buffer:
#al_ref_buffer. and *note al_ref_ustr: #al_ref_ustr.


File: refman.info,  Node: Creating and destroying strings,  Next: Predefined strings,  Prev: UTF-8 string types,  Up: UTF-8 string routines

25.3 Creating and destroying strings
====================================

* Menu:

* al_ustr_new::
* al_ustr_new_from_buffer::
* al_ustr_newf::
* al_ustr_free::
* al_cstr::
* al_ustr_to_buffer::
* al_cstr_dup::
* al_ustr_dup::
* al_ustr_dup_substr::


File: refman.info,  Node: al_ustr_new,  Next: al_ustr_new_from_buffer,  Up: Creating and destroying strings

25.3.1 al_ustr_new
------------------

ALLEGRO_USTR *al_ustr_new(const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L62)

Create a new string containing a copy of the C-style string ‘s’.  The
string must eventually be freed with *note al_ustr_free: #al_ustr_free.

See also: *note al_ustr_new_from_buffer: #al_ustr_new_from_buffer, *note
al_ustr_newf: #al_ustr_newf, *note al_ustr_dup: #al_ustr_dup, *note
al_ustr_new_from_utf16: #al_ustr_new_from_utf16.


File: refman.info,  Node: al_ustr_new_from_buffer,  Next: al_ustr_newf,  Prev: al_ustr_new,  Up: Creating and destroying strings

25.3.2 al_ustr_new_from_buffer
------------------------------

ALLEGRO_USTR *al_ustr_new_from_buffer(const char *s, size_t size)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L70)

Create a new string containing a copy of the buffer pointed to by ‘s’ of
the given ‘size’ in bytes.  The string must eventually be freed with
*note al_ustr_free: #al_ustr_free.

See also: *note al_ustr_new: #al_ustr_new.


File: refman.info,  Node: al_ustr_newf,  Next: al_ustr_free,  Prev: al_ustr_new_from_buffer,  Up: Creating and destroying strings

25.3.3 al_ustr_newf
-------------------

ALLEGRO_USTR *al_ustr_newf(const char *fmt, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L78)

Create a new string using a printf-style format string.

_Notes:_

The “%s” specifier takes C string arguments, not ALLEGRO_USTRs.
Therefore to pass an ALLEGRO_USTR as a parameter you must use *note
al_cstr: #al_cstr, and it must be NUL terminated.  If the string
contains an embedded NUL byte everything from that byte onwards will be
ignored.

The “%c” specifier outputs a single byte, not the UTF-8 encoding of a
code point.  Therefore it is only usable for ASCII characters (value <=
127) or if you really mean to output byte values from 128–255.  To
insert the UTF-8 encoding of a code point, encode it into a memory
buffer using *note al_utf8_encode: #al_utf8_encode. then use the “%s”
specifier.  Remember to NUL terminate the buffer.

See also: *note al_ustr_new: #al_ustr_new, *note al_ustr_appendf:
#al_ustr_appendf.


File: refman.info,  Node: al_ustr_free,  Next: al_cstr,  Prev: al_ustr_newf,  Up: Creating and destroying strings

25.3.4 al_ustr_free
-------------------

void al_ustr_free(ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L93)

Free a previously allocated string.  Does nothing if the argument is
NULL.

See also: *note al_ustr_new: #al_ustr_new, *note
al_ustr_new_from_buffer: #al_ustr_new_from_buffer, *note al_ustr_newf:
#al_ustr_newf.


File: refman.info,  Node: al_cstr,  Next: al_ustr_to_buffer,  Prev: al_ustr_free,  Up: Creating and destroying strings

25.3.5 al_cstr
--------------

const char *al_cstr(const ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L101)

Get a ‘char *’ pointer to the data in a string.  This pointer will only
be valid while the *note ALLEGRO_USTR: #allegro_ustr. object is not
modified and not destroyed.  The pointer may be passed to functions
expecting C-style strings, with the following caveats:

   • ALLEGRO_USTRs are allowed to contain embedded NUL (‘'\0'’) bytes.
     That means ‘al_ustr_size(u)’ and ‘strlen(al_cstr(u))’ may not
     agree.

   • An ALLEGRO_USTR may be created in such a way that it is not NUL
     terminated.  A string which is dynamically allocated will always be
     NUL terminated, but a string which references the middle of another
     string or region of memory will _not_ be NUL terminated.

   • If the ALLEGRO_USTR references another string, the returned C
     string will point into the referenced string.  Again, no NUL
     terminator will be added to the referenced string.

See also: *note al_ustr_to_buffer: #al_ustr_to_buffer, *note
al_cstr_dup: #al_cstr_dup.


File: refman.info,  Node: al_ustr_to_buffer,  Next: al_cstr_dup,  Prev: al_cstr,  Up: Creating and destroying strings

25.3.6 al_ustr_to_buffer
------------------------

void al_ustr_to_buffer(const ALLEGRO_USTR *us, char *buffer, int size)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L110)

Write the contents of the string into a pre-allocated buffer of the
given size in bytes.  The result will always be NUL terminated, so a
maximum of ‘size - 1’ bytes will be copied.

See also: *note al_cstr: #al_cstr, *note al_cstr_dup: #al_cstr_dup.


File: refman.info,  Node: al_cstr_dup,  Next: al_ustr_dup,  Prev: al_ustr_to_buffer,  Up: Creating and destroying strings

25.3.7 al_cstr_dup
------------------

char *al_cstr_dup(const ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L126)

Create a NUL (‘'\0'’) terminated copy of the string.  Any embedded NUL
bytes will still be presented in the returned string.  The new string
must eventually be freed with *note al_free: #al_free.

If an error occurs NULL is returned.

See also: *note al_cstr: #al_cstr, *note al_ustr_to_buffer:
#al_ustr_to_buffer, *note al_free: #al_free.


File: refman.info,  Node: al_ustr_dup,  Next: al_ustr_dup_substr,  Prev: al_cstr_dup,  Up: Creating and destroying strings

25.3.8 al_ustr_dup
------------------

ALLEGRO_USTR *al_ustr_dup(const ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L134)

Return a duplicate copy of a string.  The new string will need to be
freed with *note al_ustr_free: #al_ustr_free.

See also: *note al_ustr_dup_substr: #al_ustr_dup_substr, *note
al_ustr_free: #al_ustr_free.


File: refman.info,  Node: al_ustr_dup_substr,  Prev: al_ustr_dup,  Up: Creating and destroying strings

25.3.9 al_ustr_dup_substr
-------------------------

ALLEGRO_USTR *al_ustr_dup_substr(const ALLEGRO_USTR *us, int start_pos,
   int end_pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L142)

Return a new copy of a string, containing its contents in the byte
interval [‘start_pos’, ‘end_pos’).  The new string will be NUL
terminated and will need to be freed with *note al_ustr_free:
#al_ustr_free.

If necessary, use *note al_ustr_offset: #al_ustr_offset. to find the
byte offsets for a given code point that you are interested in.

See also: *note al_ustr_dup: #al_ustr_dup, *note al_ustr_free:
#al_ustr_free.


File: refman.info,  Node: Predefined strings,  Next: Creating strings by referencing other data,  Prev: Creating and destroying strings,  Up: UTF-8 string routines

25.4 Predefined strings
=======================

* Menu:

* al_ustr_empty_string::


File: refman.info,  Node: al_ustr_empty_string,  Up: Predefined strings

25.4.1 al_ustr_empty_string
---------------------------

const ALLEGRO_USTR *al_ustr_empty_string(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L151)

Return a pointer to a static empty string.  The string is read only and
must not be freed.


File: refman.info,  Node: Creating strings by referencing other data,  Next: Sizes and offsets,  Prev: Predefined strings,  Up: UTF-8 string routines

25.5 Creating strings by referencing other data
===============================================

* Menu:

* al_ref_cstr::
* al_ref_buffer::
* al_ref_ustr::


File: refman.info,  Node: al_ref_cstr,  Next: al_ref_buffer,  Up: Creating strings by referencing other data

25.5.1 al_ref_cstr
------------------

const ALLEGRO_USTR *al_ref_cstr(ALLEGRO_USTR_INFO *info, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L160)

Create a string that references the storage of a C-style string.  The
information about the string (e.g. its size) is stored in the structure
pointed to by the ‘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:

ALLEGRO_USTR_INFO info;
ALLEGRO_USTR *us = al_ref_cstr(&info, "my string");

See also: *note al_ref_buffer: #al_ref_buffer, *note al_ref_ustr:
#al_ref_ustr.


File: refman.info,  Node: al_ref_buffer,  Next: al_ref_ustr,  Prev: al_ref_cstr,  Up: Creating strings by referencing other data

25.5.2 al_ref_buffer
--------------------

const ALLEGRO_USTR *al_ref_buffer(ALLEGRO_USTR_INFO *info, const char *s, size_t size)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L173)

Create 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.

See also: *note al_ref_cstr: #al_ref_cstr, *note al_ref_ustr:
#al_ref_ustr.


File: refman.info,  Node: al_ref_ustr,  Prev: al_ref_buffer,  Up: Creating strings by referencing other data

25.5.3 al_ref_ustr
------------------

const ALLEGRO_USTR *al_ref_ustr(ALLEGRO_USTR_INFO *info, const ALLEGRO_USTR *us,
   int start_pos, int end_pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L185)

Create a read-only string that references the storage of another *note
ALLEGRO_USTR: #allegro_ustr. string.  The information about the string
(e.g. its size) is stored in the structure pointed to by the ‘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 [‘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 *note
al_ustr_offset: #al_ustr_offset. to find the byte offsets.

See also: *note al_ref_cstr: #al_ref_cstr, *note al_ref_buffer:
#al_ref_buffer.


File: refman.info,  Node: Sizes and offsets,  Next: Getting code points,  Prev: Creating strings by referencing other data,  Up: UTF-8 string routines

25.6 Sizes and offsets
======================

* Menu:

* al_ustr_size::
* al_ustr_length::
* al_ustr_offset::
* al_ustr_next::
* al_ustr_prev::


File: refman.info,  Node: al_ustr_size,  Next: al_ustr_length,  Up: Sizes and offsets

25.6.1 al_ustr_size
-------------------

size_t al_ustr_size(const ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L197)

Return 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.

See also: *note al_ustr_length: #al_ustr_length.


File: refman.info,  Node: al_ustr_length,  Next: al_ustr_offset,  Prev: al_ustr_size,  Up: Sizes and offsets

25.6.2 al_ustr_length
---------------------

size_t al_ustr_length(const ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L205)

Return the number of code points in the string.

See also: *note al_ustr_size: #al_ustr_size, *note al_ustr_offset:
#al_ustr_offset.


File: refman.info,  Node: al_ustr_offset,  Next: al_ustr_next,  Prev: al_ustr_length,  Up: Sizes and offsets

25.6.3 al_ustr_offset
---------------------

int al_ustr_offset(const ALLEGRO_USTR *us, int index)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L219)

Return the byte offset (from the start of the string) of the code point
at the specified index in the string.  A zero index parameter will
return the first character of the string.  If 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 index is past the end of the string, returns the offset of the
end of the string.

See also: *note al_ustr_length: #al_ustr_length.


File: refman.info,  Node: al_ustr_next,  Next: al_ustr_prev,  Prev: al_ustr_offset,  Up: Sizes and offsets

25.6.4 al_ustr_next
-------------------

bool al_ustr_next(const ALLEGRO_USTR *us, int *pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L237)

Find the byte offset of the next code point in string, beginning at
‘*pos’.  ‘*pos’ does not have to be at the beginning of a code point.

Returns true on success, and the value pointed to by ‘pos’ will be
updated to the found offset.  Otherwise returns false if ‘*pos’ was
already at the end of the string, and ‘*pos’ is unmodified.

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.

See also: *note al_ustr_prev: #al_ustr_prev.


File: refman.info,  Node: al_ustr_prev,  Prev: al_ustr_next,  Up: Sizes and offsets

25.6.5 al_ustr_prev
-------------------

bool al_ustr_prev(const ALLEGRO_USTR *us, int *pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L259)

Find the byte offset of the previous code point in string, before
‘*pos’.  ‘*pos’ does not have to be at the beginning of a code point.
Returns true on success, and the value pointed to by ‘pos’ will be
updated to the found offset.  Otherwise returns false if ‘*pos’ was
already at the end of the string, and ‘*pos’ is unmodified.

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.

See also: *note al_ustr_next: #al_ustr_next.


File: refman.info,  Node: Getting code points,  Next: Inserting into strings,  Prev: Sizes and offsets,  Up: UTF-8 string routines

25.7 Getting code points
========================

* Menu:

* al_ustr_get::
* al_ustr_get_next::
* al_ustr_prev_get::


File: refman.info,  Node: al_ustr_get,  Next: al_ustr_get_next,  Up: Getting code points

25.7.1 al_ustr_get
------------------

int32_t al_ustr_get(const ALLEGRO_USTR *ub, int pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L283)

Return the code point in ‘ub’ beginning at byte offset ‘pos’.

On success returns the code point value.  If ‘pos’ was out of bounds
(e.g. past the end of the string), return -1.  On an error, such as an
invalid byte sequence, return -2.

See also: *note al_ustr_get_next: #al_ustr_get_next, *note
al_ustr_prev_get: #al_ustr_prev_get.


File: refman.info,  Node: al_ustr_get_next,  Next: al_ustr_prev_get,  Prev: al_ustr_get,  Up: Getting code points

25.7.2 al_ustr_get_next
-----------------------

int32_t al_ustr_get_next(const ALLEGRO_USTR *us, int *pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L368)

Find the code point in ‘us’ beginning at byte offset ‘*pos’, then
advance to the next code point.

On success return the code point value.  If ‘pos’ was out of bounds
(e.g. past the end of the string), return -1.  On an error, such as an
invalid byte sequence, return -2.  As with *note al_ustr_next:
#al_ustr_next, invalid byte sequences may be skipped while advancing.

See also: *note al_ustr_get: #al_ustr_get, *note al_ustr_prev_get:
#al_ustr_prev_get.


File: refman.info,  Node: al_ustr_prev_get,  Prev: al_ustr_get_next,  Up: Getting code points

25.7.3 al_ustr_prev_get
-----------------------

int32_t al_ustr_prev_get(const ALLEGRO_USTR *us, int *pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L390)

Find the beginning of a code point before byte offset ‘*pos’, then
return it.  Note this performs a _pre-increment_.

On success returns the code point value.  If ‘pos’ was out of bounds
(e.g. past the end of the string), return -1.  On an error, such as an
invalid byte sequence, return -2.  As with *note al_ustr_prev:
#al_ustr_prev, invalid byte sequences may be skipped while advancing.

See also: *note al_ustr_get_next: #al_ustr_get_next.


File: refman.info,  Node: Inserting into strings,  Next: Appending to strings,  Prev: Getting code points,  Up: UTF-8 string routines

25.8 Inserting into strings
===========================

* Menu:

* al_ustr_insert::
* al_ustr_insert_cstr::
* al_ustr_insert_chr::


File: refman.info,  Node: al_ustr_insert,  Next: al_ustr_insert_cstr,  Up: Inserting into strings

25.8.1 al_ustr_insert
---------------------

bool al_ustr_insert(ALLEGRO_USTR *us1, int pos, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L403)

Insert ‘us2’ into ‘us1’ beginning at byte offset ‘pos’.  ‘pos’ cannot be
less than 0.  If ‘pos’ is past the end of ‘us1’ then the space between
the end of the string and ‘pos’ will be padded with NUL (‘'\0'’) bytes.

If required, use *note al_ustr_offset: #al_ustr_offset. to find the byte
offset for a given code point index.

Returns true on success, false on error.

See also: *note al_ustr_insert_cstr: #al_ustr_insert_cstr, *note
al_ustr_insert_chr: #al_ustr_insert_chr, *note al_ustr_append:
#al_ustr_append, *note al_ustr_offset: #al_ustr_offset.


File: refman.info,  Node: al_ustr_insert_cstr,  Next: al_ustr_insert_chr,  Prev: al_ustr_insert,  Up: Inserting into strings

25.8.2 al_ustr_insert_cstr
--------------------------

bool al_ustr_insert_cstr(ALLEGRO_USTR *us, int pos, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L411)

Like *note al_ustr_insert: #al_ustr_insert. but inserts a C-style string
at byte offset ‘pos’.

See also: *note al_ustr_insert: #al_ustr_insert, *note
al_ustr_insert_chr: #al_ustr_insert_chr.


File: refman.info,  Node: al_ustr_insert_chr,  Prev: al_ustr_insert_cstr,  Up: Inserting into strings

25.8.3 al_ustr_insert_chr
-------------------------

size_t al_ustr_insert_chr(ALLEGRO_USTR *us, int pos, int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L421)

Insert a code point into ‘us’ beginning at byte offset ‘pos’.  ‘pos’
cannot be less than 0.  If ‘pos’ is past the end of ‘us’ then the space
between the end of the string and ‘pos’ will be padded with NUL (‘'\0'’)
bytes.

Returns the number of bytes inserted, or 0 on error.

See also: *note al_ustr_insert: #al_ustr_insert, *note
al_ustr_insert_cstr: #al_ustr_insert_cstr.


File: refman.info,  Node: Appending to strings,  Next: Removing parts of strings,  Prev: Inserting into strings,  Up: UTF-8 string routines

25.9 Appending to strings
=========================

* Menu:

* al_ustr_append::
* al_ustr_append_cstr::
* al_ustr_append_chr::
* al_ustr_appendf::
* al_ustr_vappendf::


File: refman.info,  Node: al_ustr_append,  Next: al_ustr_append_cstr,  Up: Appending to strings

25.9.1 al_ustr_append
---------------------

bool al_ustr_append(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L445)

Append ‘us2’ to the end of ‘us1’.

Returns true on success, false on error.

This function can be used to append an arbitrary buffer:

  ALLEGRO_USTR_INFO info;
  al_ustr_append(us, al_ref_buffer(&info, buf, size));

See also: *note al_ustr_append_cstr: #al_ustr_append_cstr, *note
al_ustr_append_chr: #al_ustr_append_chr, *note al_ustr_appendf:
#al_ustr_appendf, *note al_ustr_vappendf: #al_ustr_vappendf.


File: refman.info,  Node: al_ustr_append_cstr,  Next: al_ustr_append_chr,  Prev: al_ustr_append,  Up: Appending to strings

25.9.2 al_ustr_append_cstr
--------------------------

bool al_ustr_append_cstr(ALLEGRO_USTR *us, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L453)

Append C-style string ‘s’ to the end of ‘us’.

Returns true on success, false on error.

See also: *note al_ustr_append: #al_ustr_append.


File: refman.info,  Node: al_ustr_append_chr,  Next: al_ustr_appendf,  Prev: al_ustr_append_cstr,  Up: Appending to strings

25.9.3 al_ustr_append_chr
-------------------------

size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L461)

Append a code point to the end of ‘us’.

Returns the number of bytes added, or 0 on error.

See also: *note al_ustr_append: #al_ustr_append.


File: refman.info,  Node: al_ustr_appendf,  Next: al_ustr_vappendf,  Prev: al_ustr_append_chr,  Up: Appending to strings

25.9.4 al_ustr_appendf
----------------------

bool al_ustr_appendf(ALLEGRO_USTR *us, const char *fmt, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L475)

This function appends formatted output to the string ‘us’.  ‘fmt’ is a
printf-style format string.  See *note al_ustr_newf: #al_ustr_newf.
about the “%s” and “%c” specifiers.

Returns true on success, false on error.

See also: *note al_ustr_vappendf: #al_ustr_vappendf, *note
al_ustr_append: #al_ustr_append.


File: refman.info,  Node: al_ustr_vappendf,  Prev: al_ustr_appendf,  Up: Appending to strings

25.9.5 al_ustr_vappendf
-----------------------

bool al_ustr_vappendf(ALLEGRO_USTR *us, const char *fmt, va_list ap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L489)

Like *note al_ustr_appendf: #al_ustr_appendf. but you pass the variable
argument list directly, instead of the arguments themselves.  See *note
al_ustr_newf: #al_ustr_newf. about the “%s” and “%c” specifiers.

Returns true on success, false on error.

See also: *note al_ustr_appendf: #al_ustr_appendf, *note al_ustr_append:
#al_ustr_append.


File: refman.info,  Node: Removing parts of strings,  Next: Assigning one string to another,  Prev: Appending to strings,  Up: UTF-8 string routines

25.10 Removing parts of strings
===============================

* Menu:

* al_ustr_remove_chr::
* al_ustr_remove_range::
* al_ustr_truncate::
* al_ustr_ltrim_ws::
* al_ustr_rtrim_ws::
* al_ustr_trim_ws::


File: refman.info,  Node: al_ustr_remove_chr,  Next: al_ustr_remove_range,  Up: Removing parts of strings

25.10.1 al_ustr_remove_chr
--------------------------

bool al_ustr_remove_chr(ALLEGRO_USTR *us, int pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L525)

Remove the code point beginning at byte offset ‘pos’.  Returns true on
success.  If ‘pos’ is out of range or ‘pos’ is not the beginning of a
valid code point, returns false leaving the string unmodified.

Use *note al_ustr_offset: #al_ustr_offset. to find the byte offset for a
code-points offset.

See also: *note al_ustr_remove_range: #al_ustr_remove_range.


File: refman.info,  Node: al_ustr_remove_range,  Next: al_ustr_truncate,  Prev: al_ustr_remove_chr,  Up: Removing parts of strings

25.10.2 al_ustr_remove_range
----------------------------

bool al_ustr_remove_range(ALLEGRO_USTR *us, int start_pos, int end_pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L541)

Remove the interval [‘start_pos’, ‘end_pos’) from a string.  ‘start_pos’
and ‘end_pos’ are byte offsets.  Both may be past the end of the string
but cannot be less than 0 (the start of the string).

Returns true on success, false on error.

See also: *note al_ustr_remove_chr: #al_ustr_remove_chr, *note
al_ustr_truncate: #al_ustr_truncate.


File: refman.info,  Node: al_ustr_truncate,  Next: al_ustr_ltrim_ws,  Prev: al_ustr_remove_range,  Up: Removing parts of strings

25.10.3 al_ustr_truncate
------------------------

bool al_ustr_truncate(ALLEGRO_USTR *us, int start_pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L549)

Truncate a portion of a string from byte offset ‘start_pos’ onwards.
‘start_pos’ can be past the end of the string (has no effect) but cannot
be less than 0.

Returns true on success, false on error.

See also: *note al_ustr_remove_range: #al_ustr_remove_range, *note
al_ustr_ltrim_ws: #al_ustr_ltrim_ws, *note al_ustr_rtrim_ws:
#al_ustr_rtrim_ws, *note al_ustr_trim_ws: #al_ustr_trim_ws.


File: refman.info,  Node: al_ustr_ltrim_ws,  Next: al_ustr_rtrim_ws,  Prev: al_ustr_truncate,  Up: Removing parts of strings

25.10.4 al_ustr_ltrim_ws
------------------------

bool al_ustr_ltrim_ws(ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L557)

Remove leading whitespace characters from a string, as defined by the C
function ‘isspace()’.

Returns true on success, or false on error.

See also: *note al_ustr_rtrim_ws: #al_ustr_rtrim_ws, *note
al_ustr_trim_ws: #al_ustr_trim_ws.


File: refman.info,  Node: al_ustr_rtrim_ws,  Next: al_ustr_trim_ws,  Prev: al_ustr_ltrim_ws,  Up: Removing parts of strings

25.10.5 al_ustr_rtrim_ws
------------------------

bool al_ustr_rtrim_ws(ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L565)

Remove trailing (“right”) whitespace characters from a string, as
defined by the C function ‘isspace()’.

Returns true on success, or false on error.

See also: *note al_ustr_ltrim_ws: #al_ustr_ltrim_ws, *note
al_ustr_trim_ws: #al_ustr_trim_ws.


File: refman.info,  Node: al_ustr_trim_ws,  Prev: al_ustr_rtrim_ws,  Up: Removing parts of strings

25.10.6 al_ustr_trim_ws
-----------------------

bool al_ustr_trim_ws(ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L573)

Remove both leading and trailing whitespace characters from a string.

Returns true on success, or false on error.

See also: *note al_ustr_ltrim_ws: #al_ustr_ltrim_ws, *note
al_ustr_rtrim_ws: #al_ustr_rtrim_ws.


File: refman.info,  Node: Assigning one string to another,  Next: Replacing parts of string,  Prev: Removing parts of strings,  Up: UTF-8 string routines

25.11 Assigning one string to another
=====================================

* Menu:

* al_ustr_assign::
* al_ustr_assign_substr::
* al_ustr_assign_cstr::


File: refman.info,  Node: al_ustr_assign,  Next: al_ustr_assign_substr,  Up: Assigning one string to another

25.11.1 al_ustr_assign
----------------------

bool al_ustr_assign(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L581)

Overwrite the string ‘us1’ with another string ‘us2’.  Returns true on
success, false on error.

See also: *note al_ustr_assign_substr: #al_ustr_assign_substr, *note
al_ustr_assign_cstr: #al_ustr_assign_cstr.


File: refman.info,  Node: al_ustr_assign_substr,  Next: al_ustr_assign_cstr,  Prev: al_ustr_assign,  Up: Assigning one string to another

25.11.2 al_ustr_assign_substr
-----------------------------

bool al_ustr_assign_substr(ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2,
   int start_pos, int end_pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L589)

Overwrite the string ‘us1’ with the contents of ‘us2’ in the byte
interval [‘start_pos’, ‘end_pos’).  The end points will be clamped to
the bounds of ‘us2’.

Usually you will first have to use *note al_ustr_offset:
#al_ustr_offset. to find the byte offsets.

Returns true on success, false on error.

See also: *note al_ustr_assign: #al_ustr_assign, *note
al_ustr_assign_cstr: #al_ustr_assign_cstr.


File: refman.info,  Node: al_ustr_assign_cstr,  Prev: al_ustr_assign_substr,  Up: Assigning one string to another

25.11.3 al_ustr_assign_cstr
---------------------------

bool al_ustr_assign_cstr(ALLEGRO_USTR *us1, const char *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L599)

Overwrite the string ‘us1’ with the contents of the C-style string ‘s’.
Returns true on success, false on error.

See also: *note al_ustr_assign_substr: #al_ustr_assign_substr, *note
al_ustr_assign_cstr: #al_ustr_assign_cstr.


File: refman.info,  Node: Replacing parts of string,  Next: Searching,  Prev: Assigning one string to another,  Up: UTF-8 string routines

25.12 Replacing parts of string
===============================

* Menu:

* al_ustr_set_chr::
* al_ustr_replace_range::


File: refman.info,  Node: al_ustr_set_chr,  Next: al_ustr_replace_range,  Up: Replacing parts of string

25.12.1 al_ustr_set_chr
-----------------------

size_t al_ustr_set_chr(ALLEGRO_USTR *us, int start_pos, int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L607)

Replace the code point beginning at byte offset ‘start_pos’ with ‘c’.
‘start_pos’ cannot be less than 0.  If ‘start_pos’ is past the end of
‘us’ then the space between the end of the string and ‘start_pos’ will
be padded with NUL (‘'\0'’) bytes.  If ‘start_pos’ is not the start of a
valid code point, that is an error and the string will be unmodified.

On success, returns the number of bytes written, i.e. the offset to the
following code point.  On error, returns 0.

See also: *note al_ustr_replace_range: #al_ustr_replace_range.


File: refman.info,  Node: al_ustr_replace_range,  Prev: al_ustr_set_chr,  Up: Replacing parts of string

25.12.2 al_ustr_replace_range
-----------------------------

bool al_ustr_replace_range(ALLEGRO_USTR *us1, int start_pos1, int end_pos1,
   const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L647)

Replace the part of ‘us1’ in the byte interval [‘start_pos1’,
‘end_pos1’) with the contents of ‘us2’.  ‘start_pos1’ cannot be less
than 0.  If ‘start_pos1’ is past the end of ‘us1’ then the space between
the end of the string and ‘start_pos1’ will be padded with NUL (‘'\0'’)
bytes.

Use *note al_ustr_offset: #al_ustr_offset. to find the byte offsets.

Returns true on success, false on error.

See also: *note al_ustr_set_chr: #al_ustr_set_chr.


File: refman.info,  Node: Searching,  Next: Comparing,  Prev: Replacing parts of string,  Up: UTF-8 string routines

25.13 Searching
===============

* Menu:

* al_ustr_find_chr::
* al_ustr_rfind_chr::
* al_ustr_find_set::
* al_ustr_find_set_cstr::
* al_ustr_find_cset::
* al_ustr_find_cset_cstr::
* al_ustr_find_str::
* al_ustr_find_cstr::
* al_ustr_rfind_str::
* al_ustr_rfind_cstr::
* al_ustr_find_replace::
* al_ustr_find_replace_cstr::


File: refman.info,  Node: al_ustr_find_chr,  Next: al_ustr_rfind_chr,  Up: Searching

25.13.1 al_ustr_find_chr
------------------------

int al_ustr_find_chr(const ALLEGRO_USTR *us, int start_pos, int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L657)

Search for the encoding of code point ‘c’ in ‘us’ from byte offset
‘start_pos’ (inclusive).

Returns the position where it is found or -1 if it is not found.

See also: *note al_ustr_rfind_chr: #al_ustr_rfind_chr.


File: refman.info,  Node: al_ustr_rfind_chr,  Next: al_ustr_find_set,  Prev: al_ustr_find_chr,  Up: Searching

25.13.2 al_ustr_rfind_chr
-------------------------

int al_ustr_rfind_chr(const ALLEGRO_USTR *us, int end_pos, int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L688)

Search for the encoding of code point ‘c’ in ‘us’ backwards from byte
offset ‘end_pos’ (exclusive).  Returns the position where it is found or
-1 if it is not found.

See also: *note al_ustr_find_chr: #al_ustr_find_chr.


File: refman.info,  Node: al_ustr_find_set,  Next: al_ustr_find_set_cstr,  Prev: al_ustr_rfind_chr,  Up: Searching

25.13.3 al_ustr_find_set
------------------------

int al_ustr_find_set(const ALLEGRO_USTR *us, int start_pos,
   const ALLEGRO_USTR *accept)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L719)

This function finds the first code point in ‘us’, beginning from byte
offset ‘start_pos’, that matches any code point in ‘accept’.  Returns
the position if a code point was found.  Otherwise returns -1.

See also: *note al_ustr_find_set_cstr: #al_ustr_find_set_cstr, *note
al_ustr_find_cset: #al_ustr_find_cset.


File: refman.info,  Node: al_ustr_find_set_cstr,  Next: al_ustr_find_cset,  Prev: al_ustr_find_set,  Up: Searching

25.13.4 al_ustr_find_set_cstr
-----------------------------

int al_ustr_find_set_cstr(const ALLEGRO_USTR *us, int start_pos,
   const char *accept)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L757)

Like *note al_ustr_find_set: #al_ustr_find_set. but takes a C-style
string for ‘accept’.

See also: *note al_ustr_find_set: #al_ustr_find_set, *note
al_ustr_find_cset_cstr: #al_ustr_find_cset_cstr.


File: refman.info,  Node: al_ustr_find_cset,  Next: al_ustr_find_cset_cstr,  Prev: al_ustr_find_set_cstr,  Up: Searching

25.13.5 al_ustr_find_cset
-------------------------

int al_ustr_find_cset(const ALLEGRO_USTR *us, int start_pos,
   const ALLEGRO_USTR *reject)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L769)

This function finds the first code point in ‘us’, beginning from byte
offset ‘start_pos’, that does _not_ match any code point in ‘reject’.
In other words it finds a code point in the complementary set of
‘reject’.  Returns the byte position of that code point, if any.
Otherwise returns -1.

See also: *note al_ustr_find_cset_cstr: #al_ustr_find_cset_cstr, *note
al_ustr_find_set: #al_ustr_find_set.


File: refman.info,  Node: al_ustr_find_cset_cstr,  Next: al_ustr_find_str,  Prev: al_ustr_find_cset,  Up: Searching

25.13.6 al_ustr_find_cset_cstr
------------------------------

int al_ustr_find_cset_cstr(const ALLEGRO_USTR *us, int start_pos,
   const char *reject)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L811)

Like *note al_ustr_find_cset: #al_ustr_find_cset. but takes a C-style
string for ‘reject’.

See also: *note al_ustr_find_cset: #al_ustr_find_cset, *note
al_ustr_find_set_cstr: #al_ustr_find_set_cstr.


File: refman.info,  Node: al_ustr_find_str,  Next: al_ustr_find_cstr,  Prev: al_ustr_find_cset_cstr,  Up: Searching

25.13.7 al_ustr_find_str
------------------------

int al_ustr_find_str(const ALLEGRO_USTR *haystack, int start_pos,
   const ALLEGRO_USTR *needle)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L823)

Find the first occurrence of string ‘needle’ in ‘haystack’, beginning
from byte offset ‘start_pos’ (inclusive).  Return the byte offset of the
occurrence if it is found, otherwise return -1.

See also: *note al_ustr_find_cstr: #al_ustr_find_cstr, *note
al_ustr_rfind_str: #al_ustr_rfind_str, *note al_ustr_find_replace:
#al_ustr_find_replace.


File: refman.info,  Node: al_ustr_find_cstr,  Next: al_ustr_rfind_str,  Prev: al_ustr_find_str,  Up: Searching

25.13.8 al_ustr_find_cstr
-------------------------

int al_ustr_find_cstr(const ALLEGRO_USTR *haystack, int start_pos,
   const char *needle)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L833)

Like *note al_ustr_find_str: #al_ustr_find_str. but takes a C-style
string for ‘needle’.

See also: *note al_ustr_find_str: #al_ustr_find_str, *note
al_ustr_rfind_cstr: #al_ustr_rfind_cstr.


File: refman.info,  Node: al_ustr_rfind_str,  Next: al_ustr_rfind_cstr,  Prev: al_ustr_find_cstr,  Up: Searching

25.13.9 al_ustr_rfind_str
-------------------------

int al_ustr_rfind_str(const ALLEGRO_USTR *haystack, int end_pos,
   const ALLEGRO_USTR *needle)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L845)

Find the last occurrence of string ‘needle’ in ‘haystack’ before byte
offset ‘end_pos’ (exclusive).  Return the byte offset of the occurrence
if it is found, otherwise return -1.

See also: *note al_ustr_rfind_cstr: #al_ustr_rfind_cstr, *note
al_ustr_find_str: #al_ustr_find_str.


File: refman.info,  Node: al_ustr_rfind_cstr,  Next: al_ustr_find_replace,  Prev: al_ustr_rfind_str,  Up: Searching

25.13.10 al_ustr_rfind_cstr
---------------------------

int al_ustr_rfind_cstr(const ALLEGRO_USTR *haystack, int end_pos,
   const char *needle)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L855)

Like *note al_ustr_rfind_str: #al_ustr_rfind_str. but takes a C-style
string for ‘needle’.

See also: *note al_ustr_rfind_str: #al_ustr_rfind_str, *note
al_ustr_find_cstr: #al_ustr_find_cstr.


File: refman.info,  Node: al_ustr_find_replace,  Next: al_ustr_find_replace_cstr,  Prev: al_ustr_rfind_cstr,  Up: Searching

25.13.11 al_ustr_find_replace
-----------------------------

bool al_ustr_find_replace(ALLEGRO_USTR *us, int start_pos,
   const ALLEGRO_USTR *find, const ALLEGRO_USTR *replace)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L867)

Replace all occurrences of ‘find’ in ‘us’ with ‘replace’, beginning at
byte offset ‘start_pos’.  The ‘find’ string must be non-empty.  Returns
true on success, false on error.

See also: *note al_ustr_find_replace_cstr: #al_ustr_find_replace_cstr.


File: refman.info,  Node: al_ustr_find_replace_cstr,  Prev: al_ustr_find_replace,  Up: Searching

25.13.12 al_ustr_find_replace_cstr
----------------------------------

bool al_ustr_find_replace_cstr(ALLEGRO_USTR *us, int start_pos,
   const char *find, const char *replace)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L876)

Like *note al_ustr_find_replace: #al_ustr_find_replace. but takes
C-style strings for ‘find’ and ‘replace’.


File: refman.info,  Node: Comparing,  Next: UTF-16 conversion,  Prev: Searching,  Up: UTF-8 string routines

25.14 Comparing
===============

* Menu:

* al_ustr_equal::
* al_ustr_compare::
* al_ustr_ncompare::
* al_ustr_has_prefix::
* al_ustr_has_prefix_cstr::
* al_ustr_has_suffix::
* al_ustr_has_suffix_cstr::


File: refman.info,  Node: al_ustr_equal,  Next: al_ustr_compare,  Up: Comparing

25.14.1 al_ustr_equal
---------------------

bool al_ustr_equal(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L890)

Return true iff the two strings are equal.  This function is more
efficient than *note al_ustr_compare: #al_ustr_compare. so is preferable
if ordering is not important.

See also: *note al_ustr_compare: #al_ustr_compare.


File: refman.info,  Node: al_ustr_compare,  Next: al_ustr_ncompare,  Prev: al_ustr_equal,  Up: Comparing

25.14.2 al_ustr_compare
-----------------------

int al_ustr_compare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L898)

This function compares ‘us1’ and ‘us2’ by code point values.  Returns
zero if the strings are equal, a positive number if ‘us1’ comes after
‘us2’, else a negative number.

This does _not_ take into account locale-specific sorting rules.  For
that you will need to use another library.

See also: *note al_ustr_ncompare: #al_ustr_ncompare, *note
al_ustr_equal: #al_ustr_equal.


File: refman.info,  Node: al_ustr_ncompare,  Next: al_ustr_has_prefix,  Prev: al_ustr_compare,  Up: Comparing

25.14.3 al_ustr_ncompare
------------------------

int al_ustr_ncompare(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2, int n)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L920)

Like *note al_ustr_compare: #al_ustr_compare. but only compares up to
the first ‘n’ code points of both strings.

Returns zero if the strings are equal, a positive number if ‘us1’ comes
after ‘us2’, else a negative number.

See also: *note al_ustr_compare: #al_ustr_compare, *note al_ustr_equal:
#al_ustr_equal.


File: refman.info,  Node: al_ustr_has_prefix,  Next: al_ustr_has_prefix_cstr,  Prev: al_ustr_ncompare,  Up: Comparing

25.14.4 al_ustr_has_prefix
--------------------------

bool al_ustr_has_prefix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L945)

Returns true iff ‘us1’ begins with ‘us2’.

See also: *note al_ustr_has_prefix_cstr: #al_ustr_has_prefix_cstr, *note
al_ustr_has_suffix: #al_ustr_has_suffix.


File: refman.info,  Node: al_ustr_has_prefix_cstr,  Next: al_ustr_has_suffix,  Prev: al_ustr_has_prefix,  Up: Comparing

25.14.5 al_ustr_has_prefix_cstr
-------------------------------

bool al_ustr_has_prefix_cstr(const ALLEGRO_USTR *us1, const char *s2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L953)

Returns true iff ‘us1’ begins with ‘s2’.

See also: *note al_ustr_has_prefix: #al_ustr_has_prefix, *note
al_ustr_has_suffix_cstr: #al_ustr_has_suffix_cstr.


File: refman.info,  Node: al_ustr_has_suffix,  Next: al_ustr_has_suffix_cstr,  Prev: al_ustr_has_prefix_cstr,  Up: Comparing

25.14.6 al_ustr_has_suffix
--------------------------

bool al_ustr_has_suffix(const ALLEGRO_USTR *us1, const ALLEGRO_USTR *us2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L964)

Returns true iff ‘us1’ ends with ‘us2’.

See also: *note al_ustr_has_suffix_cstr: #al_ustr_has_suffix_cstr, *note
al_ustr_has_prefix: #al_ustr_has_prefix.


File: refman.info,  Node: al_ustr_has_suffix_cstr,  Prev: al_ustr_has_suffix,  Up: Comparing

25.14.7 al_ustr_has_suffix_cstr
-------------------------------

bool al_ustr_has_suffix_cstr(const ALLEGRO_USTR *us1, const char *s2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L977)

Returns true iff ‘us1’ ends with ‘s2’.

See also: *note al_ustr_has_suffix: #al_ustr_has_suffix, *note
al_ustr_has_prefix_cstr: #al_ustr_has_prefix_cstr.


File: refman.info,  Node: UTF-16 conversion,  Next: Low-level UTF-8 routines,  Prev: Comparing,  Up: UTF-8 string routines

25.15 UTF-16 conversion
=======================

* Menu:

* al_ustr_new_from_utf16::
* al_ustr_size_utf16::
* al_ustr_encode_utf16::


File: refman.info,  Node: al_ustr_new_from_utf16,  Next: al_ustr_size_utf16,  Up: UTF-16 conversion

25.15.1 al_ustr_new_from_utf16
------------------------------

ALLEGRO_USTR *al_ustr_new_from_utf16(uint16_t const *s)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L1105)

Create a new string containing a copy of the 0-terminated string ‘s’
which must be encoded as UTF-16.  The string must eventually be freed
with *note al_ustr_free: #al_ustr_free.

See also: *note al_ustr_new: #al_ustr_new.


File: refman.info,  Node: al_ustr_size_utf16,  Next: al_ustr_encode_utf16,  Prev: al_ustr_new_from_utf16,  Up: UTF-16 conversion

25.15.2 al_ustr_size_utf16
--------------------------

size_t al_ustr_size_utf16(const ALLEGRO_USTR *us)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L1127)

Returns the number of bytes required to encode the string in UTF-16
(including the terminating 0).  Usually called before *note
al_ustr_encode_utf16: #al_ustr_encode_utf16. to determine the size of
the buffer to allocate.

See also: *note al_ustr_size: #al_ustr_size.


File: refman.info,  Node: al_ustr_encode_utf16,  Prev: al_ustr_size_utf16,  Up: UTF-16 conversion

25.15.3 al_ustr_encode_utf16
----------------------------

size_t al_ustr_encode_utf16(const ALLEGRO_USTR *us, uint16_t *s,
   size_t n)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L1147)

Encode the string into the given buffer, in UTF-16.  Returns the number
of bytes written.  There are never more than ‘n’ bytes written.  The
minimum size to encode the complete string can be queried with *note
al_ustr_size_utf16: #al_ustr_size_utf16.  If the ‘n’ parameter is
smaller than that, the string will be truncated but still always 0
terminated.

See also: *note al_ustr_size_utf16: #al_ustr_size_utf16, *note
al_utf16_encode: #al_utf16_encode.


File: refman.info,  Node: Low-level UTF-8 routines,  Next: Low-level UTF-16 routines,  Prev: UTF-16 conversion,  Up: UTF-8 string routines

25.16 Low-level UTF-8 routines
==============================

* Menu:

* al_utf8_width::
* al_utf8_encode::


File: refman.info,  Node: al_utf8_width,  Next: al_utf8_encode,  Up: Low-level UTF-8 routines

25.16.1 al_utf8_width
---------------------

size_t al_utf8_width(int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L988)

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.

See also: *note al_utf8_encode: #al_utf8_encode, *note al_utf16_width:
#al_utf16_width.


File: refman.info,  Node: al_utf8_encode,  Prev: al_utf8_width,  Up: Low-level UTF-8 routines

25.16.2 al_utf8_encode
----------------------

size_t al_utf8_encode(char s[], int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L1010)

Encode the specified code point to UTF-8 into the buffer ‘s’.  The
buffer must have enough space to hold the encoding, which takes between
1 and 4 bytes.  This routine will refuse to encode code points above
0x10FFFF.

Returns the number of bytes written, which is the same as that returned
by *note al_utf8_width: #al_utf8_width.

See also: *note al_utf16_encode: #al_utf16_encode.


File: refman.info,  Node: Low-level UTF-16 routines,  Prev: Low-level UTF-8 routines,  Up: UTF-8 string routines

25.17 Low-level UTF-16 routines
===============================

* Menu:

* al_utf16_width::
* al_utf16_encode::


File: refman.info,  Node: al_utf16_width,  Next: al_utf16_encode,  Up: Low-level UTF-16 routines

25.17.1 al_utf16_width
----------------------

size_t al_utf16_width(int c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L1047)

Returns the number of bytes that would be occupied by the specified code
point when encoded in UTF-16.  This is either 2 or 4 bytes for legal
code point values.  Otherwise returns 0.

See also: *note al_utf16_encode: #al_utf16_encode, *note al_utf8_width:
#al_utf8_width.


File: refman.info,  Node: al_utf16_encode,  Prev: al_utf16_width,  Up: Low-level UTF-16 routines

25.17.2 al_utf16_encode
-----------------------

size_t al_utf16_encode(uint16_t s[], int32_t c)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/utf8.c#L1067)

Encode the specified code point to UTF-16 into the buffer ‘s’.  The
buffer must have enough space to hold the encoding, which takes either 2
or 4 bytes.  This routine will refuse to encode code points above
0x10FFFF.

Returns the number of bytes written, which is the same as that returned
by *note al_utf16_width: #al_utf16_width.

See also: *note al_utf8_encode: #al_utf8_encode, *note
al_ustr_encode_utf16: #al_ustr_encode_utf16.


File: refman.info,  Node: Platform-specific functions,  Next: Direct3D integration,  Prev: UTF-8 string routines,  Up: Top

26 Platform-specific functions
******************************

* Menu:

* Windows::
* Mac OS X::
* iPhone::
* Android::
* X11::


File: refman.info,  Node: Windows,  Next: Mac OS X,  Up: Platform-specific functions

26.1 Windows
============

These functions are declared in the following header file:

 #include <allegro5/allegro_windows.h>

* Menu:

* al_get_win_window_handle::
* al_win_add_window_callback::
* al_win_remove_window_callback::


File: refman.info,  Node: al_get_win_window_handle,  Next: al_win_add_window_callback,  Up: Windows

26.1.1 al_get_win_window_handle
-------------------------------

HWND al_get_win_window_handle(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/wwindow.c#L1391)

Returns the handle to the window that the passed display is using.


File: refman.info,  Node: al_win_add_window_callback,  Next: al_win_remove_window_callback,  Prev: al_get_win_window_handle,  Up: Windows

26.1.2 al_win_add_window_callback
---------------------------------

bool al_win_add_window_callback(ALLEGRO_DISPLAY *display,
   bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam,
   LPARAM lparam, LRESULT *result, void *userdata), void *userdata)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/wwindow.c#L1419)

The specified callback function will intercept the window’s message
before Allegro processes it.  If the callback function consumes the
event, then it should return true.  In that case, Allegro will not do
anything with the event.

Optionally, you may use ‘result’ to customize what Allegro will return
return in response to this event.  By default, Allegro returns ‘TRUE’.

The ‘userdata’ pointer can be used to supply additional context to the
callback function.

The callbacks are executed in the same order they were added.

Returns true if the callback was added.

Since: 5.1.2


File: refman.info,  Node: al_win_remove_window_callback,  Prev: al_win_add_window_callback,  Up: Windows

26.1.3 al_win_remove_window_callback
------------------------------------

bool al_win_remove_window_callback(ALLEGRO_DISPLAY *display,
   bool (*callback)(ALLEGRO_DISPLAY *display, UINT message, WPARAM wparam,
   LPARAM lparam, LRESULT *result, void *userdata), void *userdata)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/wwindow.c#L1448)

Removes the callback that was previously registered with *note
al_win_add_window_callback: #al_win_add_window_callback.  The ‘userdata’
pointer must be the same as what was used during the registration of the
callback.

Returns true if the callback was removed.

Since: 5.1.2


File: refman.info,  Node: Mac OS X,  Next: iPhone,  Prev: Windows,  Up: Platform-specific functions

26.2 Mac OS X
=============

These functions are declared in the following header file:

 #include <allegro5/allegro_osx.h>

* Menu:

* al_osx_get_window::


File: refman.info,  Node: al_osx_get_window,  Up: Mac OS X

26.2.1 al_osx_get_window
------------------------

NSWindow* al_osx_get_window(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/macosx/osxgl.m#L2558)

Retrieves the NSWindow handle associated with the Allegro display.

Since: 5.0.8, 5.1.3


File: refman.info,  Node: iPhone,  Next: Android,  Prev: Mac OS X,  Up: Platform-specific functions

26.3 iPhone
===========

These functions are declared in the following header file:

 #include <allegro5/allegro_iphone.h>

* Menu:

* al_iphone_set_statusbar_orientation::
* al_iphone_get_view::
* al_iphone_get_window::


File: refman.info,  Node: al_iphone_set_statusbar_orientation,  Next: al_iphone_get_view,  Up: iPhone

26.3.1 al_iphone_set_statusbar_orientation
------------------------------------------

void al_iphone_set_statusbar_orientation(int o)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/iphone/allegroAppDelegate.m#L216)

Sets the orientation of the status bar, which can be one of the
following:

   • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT
   • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_PORTRAIT_UPSIDE_DOWN
   • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_RIGHT
   • ALLEGRO_IPHONE_STATUSBAR_ORIENTATION_LANDSCAPE_LEFT

Since: 5.1.0


File: refman.info,  Node: al_iphone_get_view,  Next: al_iphone_get_window,  Prev: al_iphone_set_statusbar_orientation,  Up: iPhone

26.3.2 al_iphone_get_view
-------------------------

UIView *al_iphone_get_view(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/iphone/allegroAppDelegate.m#L158)

Retrieves the UIView* (EAGLView*) associated with the Allegro display.

Since: 5.1.0


File: refman.info,  Node: al_iphone_get_window,  Prev: al_iphone_get_view,  Up: iPhone

26.3.3 al_iphone_get_window
---------------------------

UIWindow *al_iphone_get_window(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/iphone/allegroAppDelegate.m#L144)

Retrieves the UIWindow* associated with the Allegro display.

Since: 5.1.0


File: refman.info,  Node: Android,  Next: X11,  Prev: iPhone,  Up: Platform-specific functions

26.4 Android
============

These functions are declared in the following header file:

 #include <allegro5/allegro_android.h>

* Menu:

* al_android_set_apk_file_interface::
* al_android_set_apk_fs_interface::
* al_android_get_os_version::
* al_android_get_jni_env::
* al_android_get_activity::


File: refman.info,  Node: al_android_set_apk_file_interface,  Next: al_android_set_apk_fs_interface,  Up: Android

26.4.1 al_android_set_apk_file_interface
----------------------------------------

void al_android_set_apk_file_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/android/android_apk_file.c#L306)

This function will set up a custom *note ALLEGRO_FILE_INTERFACE:
#allegro_file_interface. that makes all future calls of *note al_fopen:
#al_fopen. read from the applicatons’s APK file.

     _Note:_ Currently, access to the APK file after calling this
     function is read only.
Since: 5.1.2


File: refman.info,  Node: al_android_set_apk_fs_interface,  Next: al_android_get_os_version,  Prev: al_android_set_apk_file_interface,  Up: Android

26.4.2 al_android_set_apk_fs_interface
--------------------------------------

void al_android_set_apk_fs_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/android/android_apk_fs.c#L302)

This function will set up a custom *note ALLEGRO_FS_INTERFACE:
#allegro_fs_interface. which allows working within the APK filesystem.
The filesystem root is your assets directory and there is read-only
access to all files within.

     _Note:_ Some things like querying file size or attributes are not
     supported by this.  You can always use the PhysFS addon to open the
     APK file (it is just a regular .zip file) and get more complete
     information.
Since: 5.1.13


File: refman.info,  Node: al_android_get_os_version,  Next: al_android_get_jni_env,  Prev: al_android_set_apk_fs_interface,  Up: Android

26.4.3 al_android_get_os_version
--------------------------------

const char *al_android_get_os_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/android/android_system.c#L599)

Returns a pointer to a static buffer that contains the version string of
the Android platform that the calling Allegro program is running on.

Since: 5.1.2


File: refman.info,  Node: al_android_get_jni_env,  Next: al_android_get_activity,  Prev: al_android_get_os_version,  Up: Android

26.4.4 al_android_get_jni_env
-----------------------------

JNIEnv *al_android_get_jni_env(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/android/android_system.c#L647)

Returns the Android JNI environment used by Allegro to call into Java.
As a convenience this function provides it to the user so there is no
need to obtain it yourself.

For example if you have a Java method “void send(String message)” in
your activity class, you could call it like this from C code:

JNIEnv * env = al_android_get_jni_env();
jclass class_id = (* env)->GetObjectClass(env, al_android_get_activity());
jmethodID method_id = (* env)->GetMethodID(env, class_id, "send",
    "(Ljava/lang/String;)V");
jstring jdata = (* env)->NewStringUTF(env, "Hello Java!");
(* env)->CallVoidMethod(env, al_android_get_activity(), method_id, jdata);
(* env)->DeleteLocalRef(env, jdata);

Since: 5.2.2

     _*note Unstable API: #unstable-api.:_ This API is new and subject
     to refinement.


File: refman.info,  Node: al_android_get_activity,  Prev: al_android_get_jni_env,  Up: Android

26.4.5 al_android_get_activity
------------------------------

jobject al_android_get_activity(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/android/android_system.c#L654)

Returns the Java Android activity used by Allegro.  This is the same
object created by Android from the class you specify in your manifest
and either an instance of AllegroActivity or a derived class.

Since: 5.2.2

     _*note Unstable API: #unstable-api.:_ This API is new and subject
     to refinement.


File: refman.info,  Node: X11,  Prev: Android,  Up: Platform-specific functions

26.5 X11
========

These functions are declared in the following header file:

 #include <allegro5/allegro_x.h>

* Menu:

* al_get_x_window_id::
* al_x_set_initial_icon::


File: refman.info,  Node: al_get_x_window_id,  Next: al_x_set_initial_icon,  Up: X11

26.5.1 al_get_x_window_id
-------------------------

XID al_get_x_window_id(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/x/xwindow.c#L397)

Retrieves the XID associated with the Allegro display.

Since: 5.1.12


File: refman.info,  Node: al_x_set_initial_icon,  Prev: al_get_x_window_id,  Up: X11

26.5.2 al_x_set_initial_icon
----------------------------

bool al_x_set_initial_icon(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/x/xsystem.c#L148)

On some window managers (notably Ubuntu’s Unity) al_set_display_icon
doesn’t work and you need to use a .desktop file.  But with this
function you can set an icon before calling al_create_display.  This
works by setting the icon before XMapWindow.

Since: 5.2.3

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: Direct3D integration,  Next: OpenGL integration,  Prev: Platform-specific functions,  Up: Top

27 Direct3D integration
***********************

These functions are declared in the following header file:

 #include <allegro5/allegro_direct3d.h>

* Menu:

* al_get_d3d_device::
* al_get_d3d_system_texture::
* al_get_d3d_video_texture::
* al_have_d3d_non_pow2_texture_support::
* al_have_d3d_non_square_texture_support::
* al_get_d3d_texture_size::
* al_get_d3d_texture_position::
* al_is_d3d_device_lost::
* al_set_d3d_device_release_callback::
* al_set_d3d_device_restore_callback::


File: refman.info,  Node: al_get_d3d_device,  Next: al_get_d3d_system_texture,  Up: Direct3D integration

27.1 al_get_d3d_device
======================

LPDIRECT3DDEVICE9 al_get_d3d_device(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L2572)

Returns the Direct3D device of the display.  The return value is
undefined if the display was not created with the Direct3D flag.

_Returns:_ A pointer to the Direct3D device.


File: refman.info,  Node: al_get_d3d_system_texture,  Next: al_get_d3d_video_texture,  Prev: al_get_d3d_device,  Up: Direct3D integration

27.2 al_get_d3d_system_texture
==============================

LPDIRECT3DTEXTURE9 al_get_d3d_system_texture(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L2580)

Returns the system texture (stored with the D3DPOOL_SYSTEMMEM flags).
This texture is used for the render-to-texture feature set.

_Returns:_ A pointer to the Direct3D system texture.


File: refman.info,  Node: al_get_d3d_video_texture,  Next: al_have_d3d_non_pow2_texture_support,  Prev: al_get_d3d_system_texture,  Up: Direct3D integration

27.3 al_get_d3d_video_texture
=============================

LPDIRECT3DTEXTURE9 al_get_d3d_video_texture(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L2588)

Returns the video texture (stored with the D3DPOOL_DEFAULT or
D3DPOOL_MANAGED flags depending on whether render-to-texture is enabled
or disabled respectively).

_Returns:_ A pointer to the Direct3D video texture.


File: refman.info,  Node: al_have_d3d_non_pow2_texture_support,  Next: al_have_d3d_non_square_texture_support,  Prev: al_get_d3d_video_texture,  Up: Direct3D integration

27.4 al_have_d3d_non_pow2_texture_support
=========================================

bool al_have_d3d_non_pow2_texture_support(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L241)

Returns whether the Direct3D device supports textures whose dimensions
are not powers of two.

_Returns:_ True if device supports NPOT textures, false otherwise.


File: refman.info,  Node: al_have_d3d_non_square_texture_support,  Next: al_get_d3d_texture_size,  Prev: al_have_d3d_non_pow2_texture_support,  Up: Direct3D integration

27.5 al_have_d3d_non_square_texture_support
===========================================

bool al_have_d3d_non_square_texture_support(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L283)

Returns whether the Direct3D device supports textures that are not
square.

_Returns:_ True if the Direct3D device supports non-square textures,
false otherwise.


File: refman.info,  Node: al_get_d3d_texture_size,  Next: al_get_d3d_texture_position,  Prev: al_have_d3d_non_square_texture_support,  Up: Direct3D integration

27.6 al_get_d3d_texture_size
============================

bool al_get_d3d_texture_size(ALLEGRO_BITMAP *bitmap, int *width, int *height)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_bmp.cpp#L105)

Retrieves the size of the Direct3D texture used for the bitmap.

Returns true on success, false on failure.  Zero width and height are
returned if the bitmap is not a Direct3D bitmap.

Since: 5.1.0

See also: *note al_get_d3d_texture_position:
#al_get_d3d_texture_position.


File: refman.info,  Node: al_get_d3d_texture_position,  Next: al_is_d3d_device_lost,  Prev: al_get_d3d_texture_size,  Up: Direct3D integration

27.7 al_get_d3d_texture_position
================================

void al_get_d3d_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L2596)

Returns the u/v coordinates for the top/left corner of the bitmap within
the used texture, in pixels.

_Parameters:_

   • bitmap - ALLEGRO_BITMAP to examine
   • u - Will hold the returned u coordinate
   • v - Will hold the returned v coordinate

See also: *note al_get_d3d_texture_size: #al_get_d3d_texture_size.


File: refman.info,  Node: al_is_d3d_device_lost,  Next: al_set_d3d_device_release_callback,  Prev: al_get_d3d_texture_position,  Up: Direct3D integration

27.8 al_is_d3d_device_lost
==========================

bool al_is_d3d_device_lost(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L2608)

Returns a boolean indicating whether or not the Direct3D device
belonging to the given display is in a lost state.

_Parameters:_

   • display - The display that the device you wish to check is attached
     to


File: refman.info,  Node: al_set_d3d_device_release_callback,  Next: al_set_d3d_device_restore_callback,  Prev: al_is_d3d_device_lost,  Up: Direct3D integration

27.9 al_set_d3d_device_release_callback
=======================================

void al_set_d3d_device_release_callback(
   void (*callback)(ALLEGRO_DISPLAY *display))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L219)

The callback will be called whenever a D3D device is reset (minimize,
toggle fullscreen window, etc).  In the callback you should release any
d3d resources you have created yourself.  The callback receives the
affected display as a parameter.

Pass NULL to disable the callback.

Since: 5.1.0


File: refman.info,  Node: al_set_d3d_device_restore_callback,  Prev: al_set_d3d_device_release_callback,  Up: Direct3D integration

27.10 al_set_d3d_device_restore_callback
========================================

void al_set_d3d_device_restore_callback(
   void (*callback)(ALLEGRO_DISPLAY *display))

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/win/d3d_disp.cpp#L227)

The callback will be called whenever a D3D device that has been reset is
restored.  In the callback you should restore any d3d resources you have
created yourself.  The callback receives the affected display as a
parameter.

Pass NULL to disable the callback.

Since: 5.1.0


File: refman.info,  Node: OpenGL integration,  Next: Audio addon,  Prev: Direct3D integration,  Up: Top

28 OpenGL integration
*********************

These functions are declared in the following header file:

 #include <allegro5/allegro_opengl.h>

* Menu:

* al_get_opengl_extension_list::
* al_get_opengl_proc_address::
* al_get_opengl_texture::
* al_get_opengl_texture_size::
* al_get_opengl_texture_position::
* al_get_opengl_program_object::
* al_get_opengl_fbo::
* al_remove_opengl_fbo::
* al_have_opengl_extension::
* al_get_opengl_version::
* al_get_opengl_variant::
* al_set_current_opengl_context::
* OpenGL configuration::


File: refman.info,  Node: al_get_opengl_extension_list,  Next: al_get_opengl_proc_address,  Up: OpenGL integration

28.1 al_get_opengl_extension_list
=================================

ALLEGRO_OGL_EXT_LIST *al_get_opengl_extension_list(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/extensions.c#L917)

Returns the list of OpenGL extensions supported by Allegro, for the
given display.

Allegro will keep information about all extensions it knows about in a
structure returned by ‘al_get_opengl_extension_list’.

For example:

if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multitexture) {
   //use it
}

The extension will be set to true if available for the given display and
false otherwise.  This means to use the definitions and functions from
an OpenGL extension, all you need to do is to check for it as above at
run time, after acquiring the OpenGL display from Allegro.

Under Windows, this will also work with WGL extensions, and under Unix
with GLX extensions.

In case you want to manually check for extensions and load function
pointers yourself (say, in case the Allegro developers did not include
it yet), you can use the *note al_have_opengl_extension:
#al_have_opengl_extension. and *note al_get_opengl_proc_address:
#al_get_opengl_proc_address. functions instead.

     _Note:_ the exact extensions exposed depend on how Allegro was
     compiled.  It is recommended to use *note al_have_opengl_extension:
     #al_have_opengl_extension. and *note al_get_opengl_proc_address:
     #al_get_opengl_proc_address. for the most stable experience.


File: refman.info,  Node: al_get_opengl_proc_address,  Next: al_get_opengl_texture,  Prev: al_get_opengl_extension_list,  Up: OpenGL integration

28.2 al_get_opengl_proc_address
===============================

void *al_get_opengl_proc_address(const char *name)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/extensions.c#L578)

Helper to get the address of an OpenGL symbol

Example:

How to get the function _glMultiTexCoord3fARB_ that comes with ARB’s
Multitexture extension:

// define the type of the function
ALLEGRO_DEFINE_PROC_TYPE(void, MULTI_TEX_FUNC,
                         (GLenum, GLfloat, GLfloat, GLfloat));
// declare the function pointer
MULTI_TEX_FUNC glMultiTexCoord3fARB;
// get the address of the function
glMultiTexCoord3fARB = (MULTI_TEX_FUNC) al_get_opengl_proc_address(
                                                        "glMultiTexCoord3fARB");

If _glMultiTexCoord3fARB_ is not NULL then it can be used as if it has
been defined in the OpenGL core library.

     _Note:_ Under Windows, OpenGL functions may need a special calling
     convention, so it’s best to always use the ALLEGRO_DEFINE_PROC_TYPE
     macro when declaring function pointer types for OpenGL functions.
Parameters:

name - The name of the symbol you want to link to.

_Return value:_

A pointer to the symbol if available or NULL otherwise.


File: refman.info,  Node: al_get_opengl_texture,  Next: al_get_opengl_texture_size,  Prev: al_get_opengl_proc_address,  Up: OpenGL integration

28.3 al_get_opengl_texture
==========================

GLuint al_get_opengl_texture(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_bitmap.c#L1161)

Returns the OpenGL texture id internally used by the given bitmap if it
uses one, else 0.

Example:

bitmap = al_load_bitmap("my_texture.png");
texture = al_get_opengl_texture(bitmap);
if (texture != 0)
    glBindTexture(GL_TEXTURE_2D, texture);


File: refman.info,  Node: al_get_opengl_texture_size,  Next: al_get_opengl_texture_position,  Prev: al_get_opengl_texture,  Up: OpenGL integration

28.4 al_get_opengl_texture_size
===============================

bool al_get_opengl_texture_size(ALLEGRO_BITMAP *bitmap, int *w, int *h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_bitmap.c#L1227)

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.

Returns true on success, false on failure.  Zero width and height are
returned if the bitmap is not an OpenGL bitmap.

See also: *note al_get_opengl_texture_position:
#al_get_opengl_texture_position.


File: refman.info,  Node: al_get_opengl_texture_position,  Next: al_get_opengl_program_object,  Prev: al_get_opengl_texture_size,  Up: OpenGL integration

28.5 al_get_opengl_texture_position
===================================

void al_get_opengl_texture_position(ALLEGRO_BITMAP *bitmap, int *u, int *v)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_bitmap.c#L1251)

Returns the u/v coordinates for the top/left corner of the bitmap within
the used texture, in pixels.

See also: *note al_get_opengl_texture_size: #al_get_opengl_texture_size.


File: refman.info,  Node: al_get_opengl_program_object,  Next: al_get_opengl_fbo,  Prev: al_get_opengl_texture_position,  Up: OpenGL integration

28.6 al_get_opengl_program_object
=================================

GLuint al_get_opengl_program_object(ALLEGRO_SHADER *shader)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_shader.c#L511)

Returns the OpenGL program object associated with this shader, if the
platform is ‘ALLEGRO_SHADER_GLSL’.  Otherwise, returns 0.


File: refman.info,  Node: al_get_opengl_fbo,  Next: al_remove_opengl_fbo,  Prev: al_get_opengl_program_object,  Up: OpenGL integration

28.7 al_get_opengl_fbo
======================

GLuint al_get_opengl_fbo(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_bitmap.c#L1201)

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 *note al_remove_opengl_fbo:
#al_remove_opengl_fbo. on the bitmap.

     _Note:_ In Allegro 5.0.0 this function only returned an FBO which
     had previously been created by calling *note al_set_target_bitmap:
     #al_set_target_bitmap.  It would not attempt to create an FBO
     itself.  This has since been changed.
See also: *note al_remove_opengl_fbo: #al_remove_opengl_fbo, *note
al_set_target_bitmap: #al_set_target_bitmap.


File: refman.info,  Node: al_remove_opengl_fbo,  Next: al_have_opengl_extension,  Prev: al_get_opengl_fbo,  Up: OpenGL integration

28.8 al_remove_opengl_fbo
=========================

void al_remove_opengl_fbo(ALLEGRO_BITMAP *bitmap)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_bitmap.c#L1174)

Explicitly free an OpenGL FBO created for a bitmap, if it has one.
Usually you do not need to worry about freeing FBOs, unless you use
*note al_get_opengl_fbo: #al_get_opengl_fbo.

See also: *note al_get_opengl_fbo: #al_get_opengl_fbo, *note
al_set_target_bitmap: #al_set_target_bitmap.


File: refman.info,  Node: al_have_opengl_extension,  Next: al_get_opengl_version,  Prev: al_remove_opengl_fbo,  Up: OpenGL integration

28.9 al_have_opengl_extension
=============================

bool al_have_opengl_extension(const char *extension)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/extensions.c#L560)

This function is a helper to determine whether an OpenGL extension is
available on the given display or not.

Example:

bool packedpixels = al_have_opengl_extension("GL_EXT_packed_pixels");

If _packedpixels_ is true then you can safely use the constants related
to the packed pixels extension.

Returns true if the extension is available; false otherwise.


File: refman.info,  Node: al_get_opengl_version,  Next: al_get_opengl_variant,  Prev: al_have_opengl_extension,  Up: OpenGL integration

28.10 al_get_opengl_version
===========================

uint32_t al_get_opengl_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/extensions.c#L216)

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 0x01000000, “1.2.1” is returned as 0x01020100, and “1.2.2”
as 0x01020200, etc.

A valid OpenGL context must exist for this function to work, which means
you may _not_ call it before *note al_create_display:
#al_create_display.

See also: *note al_get_opengl_variant: #al_get_opengl_variant.


File: refman.info,  Node: al_get_opengl_variant,  Next: al_set_current_opengl_context,  Prev: al_get_opengl_version,  Up: OpenGL integration

28.11 al_get_opengl_variant
===========================

int al_get_opengl_variant(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/extensions.c#L234)

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:

ALLEGRO_DESKTOP_OPENGL

     Regular OpenGL as seen on desktop/laptop computers.
ALLEGRO_OPENGL_ES

     Trimmed down version of OpenGL used on many small consumer
     electronic devices such as handheld (and sometimes full size)
     consoles.

See also: *note al_get_opengl_version: #al_get_opengl_version.


File: refman.info,  Node: al_set_current_opengl_context,  Next: OpenGL configuration,  Prev: al_get_opengl_variant,  Up: OpenGL integration

28.12 al_set_current_opengl_context
===================================

void al_set_current_opengl_context(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/opengl/ogl_display.c#L90)

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
NULL.

Normally you do not need to use this function, as the context will be
made current when you call *note al_set_target_bitmap:
#al_set_target_bitmap. or *note al_set_target_backbuffer:
#al_set_target_backbuffer.  You might need it if you created an OpenGL
“forward compatible” context.  Then *note al_get_backbuffer:
#al_get_backbuffer. only returns NULL, so it would not work to pass that
to *note al_set_target_bitmap: #al_set_target_bitmap.


File: refman.info,  Node: OpenGL configuration,  Prev: al_set_current_opengl_context,  Up: OpenGL integration

28.13 OpenGL configuration
==========================

You can disable the detection of any OpenGL extension by Allegro with a
section like this in allegro5.cfg:

[opengl_disabled_extensions]
GL_ARB_texture_non_power_of_two=0
GL_EXT_framebuffer_object=0

Any extension which appears in the section is treated as not available
(it does not matter if you set it to 0 or any other value).


File: refman.info,  Node: Audio addon,  Next: Audio codecs addon,  Prev: OpenGL integration,  Up: Top

29 Audio addon
**************

These functions are declared in the following header file.  Link with
allegro_audio.

 #include <allegro5/allegro_audio.h>

* Menu:

* Basic Audio::
* Samples::
* Advanced Audio::
* Sample instances::
* Audio streams::
* Advanced audio file I/O::
* Audio recording::
* Audio devices::
* Voices::
* Mixers::
* Miscelaneous::


File: refman.info,  Node: Basic Audio,  Next: Samples,  Up: Audio addon

29.1 Basic Audio
================

In order to just play some sounds (called samples in Allegro) and
background music, here’s how to quick start with Allegro’s audio addon:
Call *note al_reserve_samples: #al_reserve_samples. with the number of
samples you’d like to be able to play simultaneously (don’t forget to
call *note al_install_audio: #al_install_audio. beforehand).  If these
succeed, you can now call *note al_play_sample: #al_play_sample, with
data obtained by *note al_load_sample: #al_load_sample, for example
(don’t forget to *note initialize the acodec addon:
#al_init_acodec_addon.).  In order to stop samples, you can use the
*note ALLEGRO_SAMPLE_ID: #allegro_sample_id. that al_play_sample
returns.

If you want to play large audio files (e.g. background music) without
loading the whole file at once you can use *note al_play_audio_stream:
#al_play_audio_stream. (after calling *note al_reserve_samples:
#al_reserve_samples.).  This will load and play an
‘ALLEGRO_AUDIO_STREAM’.  Note that the basic API only supports on such
audio stream playing at once.

* Menu:

* ALLEGRO_SAMPLE_ID::
* al_install_audio::
* al_uninstall_audio::
* al_is_audio_installed::
* al_reserve_samples::
* al_play_sample::
* al_stop_sample::
* al_stop_samples::
* al_lock_sample_id::
* al_unlock_sample_id::
* al_play_audio_stream::
* al_play_audio_stream_f::


File: refman.info,  Node: ALLEGRO_SAMPLE_ID,  Next: al_install_audio,  Up: Basic Audio

29.1.1 ALLEGRO_SAMPLE_ID
------------------------

typedef struct ALLEGRO_SAMPLE_ID ALLEGRO_SAMPLE_ID;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L151)

An ALLEGRO_SAMPLE_ID represents a sample being played via *note
al_play_sample: #al_play_sample.  It can be used to later
sALLEGRO_BITMAP_WRAPtop the sample with *note al_stop_sample:
#al_stop_sample.  The underlying ALLEGRO_SAMPLE_INSTANCE can be
extracted using *note al_lock_sample_id: #al_lock_sample_id.


File: refman.info,  Node: al_install_audio,  Next: al_uninstall_audio,  Prev: ALLEGRO_SAMPLE_ID,  Up: Basic Audio

29.1.2 al_install_audio
-----------------------

bool al_install_audio(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L422)

Install the audio subsystem.

Returns true on success, false on failure.

     Note: most users will call *note al_reserve_samples:
     #al_reserve_samples. and *note al_init_acodec_addon:
     #al_init_acodec_addon. after this.
See also: *note al_reserve_samples: #al_reserve_samples, *note
al_uninstall_audio: #al_uninstall_audio, *note al_is_audio_installed:
#al_is_audio_installed, *note al_init_acodec_addon:
#al_init_acodec_addon.


File: refman.info,  Node: al_uninstall_audio,  Next: al_is_audio_installed,  Prev: al_install_audio,  Up: Basic Audio

29.1.3 al_uninstall_audio
-------------------------

void al_uninstall_audio(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L441)

Uninstalls the audio subsystem.

See also: *note al_install_audio: #al_install_audio.


File: refman.info,  Node: al_is_audio_installed,  Next: al_reserve_samples,  Prev: al_uninstall_audio,  Up: Basic Audio

29.1.4 al_is_audio_installed
----------------------------

bool al_is_audio_installed(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L456)

Returns true if *note al_install_audio: #al_install_audio. was called
previously and returned successfully.


File: refman.info,  Node: al_reserve_samples,  Next: al_play_sample,  Prev: al_is_audio_installed,  Up: Basic Audio

29.1.5 al_reserve_samples
-------------------------

bool al_reserve_samples(int reserve_samples)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L207)

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.

If you call this function a second time with a smaller number of
samples, then the excess internal sample instances will be destroyed
causing some sounds to stop and some instances returned by *note
al_lock_sample_id: #al_lock_sample_id. to be invalidated.

This diagram illustrates the structures that are set up:

                                      sample instance 1
                                    / sample instance 2
default voice <-- default mixer <---         .
                                    \        .
                                      sample instance N

Returns true on success, false on error.  *note al_install_audio:
#al_install_audio. must have been called first.

See also: *note al_set_default_mixer: #al_set_default_mixer, *note
al_play_sample: #al_play_sample.


File: refman.info,  Node: al_play_sample,  Next: al_stop_sample,  Prev: al_reserve_samples,  Up: Basic Audio

29.1.6 al_play_sample
---------------------

bool al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed,
   ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L342)

Plays a sample on one of the sample instances created by *note
al_reserve_samples: #al_reserve_samples.  Returns true on success, false
on failure.  Playback may fail because all the reserved sample instances
are currently used.

Parameters:

   • gain - relative volume at which the sample is played; 1.0 is
     normal.
   • pan - 0.0 is centred, -1.0 is left, 1.0 is right, or
     ALLEGRO_AUDIO_PAN_NONE.
   • speed - relative speed at which the sample is played; 1.0 is
     normal.
   • loop - ALLEGRO_PLAYMODE_ONCE, ALLEGRO_PLAYMODE_LOOP, or
     ALLEGRO_PLAYMODE_BIDIR
   • ret_id - if non-NULL the variable which this points to will be
     assigned an id representing the sample being played.  If *note
     al_play_sample: #al_play_sample. returns ‘false’, then the contents
     of ret_id are invalid and must not be used as argument to other
     functions.

See also: *note al_load_sample: #al_load_sample, *note ALLEGRO_PLAYMODE:
#allegro_playmode, *note ALLEGRO_AUDIO_PAN_NONE:
#allegro_audio_pan_none, *note ALLEGRO_SAMPLE_ID: #allegro_sample_id,
*note al_stop_sample: #al_stop_sample, *note al_stop_samples:
#al_stop_samples, *note al_lock_sample_id: #al_lock_sample_id.


File: refman.info,  Node: al_stop_sample,  Next: al_stop_samples,  Prev: al_play_sample,  Up: Basic Audio

29.1.7 al_stop_sample
---------------------

void al_stop_sample(ALLEGRO_SAMPLE_ID *spl_id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L401)

Stop the sample started by *note al_play_sample: #al_play_sample.

See also: *note al_stop_samples: #al_stop_samples.


File: refman.info,  Node: al_stop_samples,  Next: al_lock_sample_id,  Prev: al_stop_sample,  Up: Basic Audio

29.1.8 al_stop_samples
----------------------

void al_stop_samples(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L451)

Stop all samples started by *note al_play_sample: #al_play_sample.

See also: *note al_stop_sample: #al_stop_sample.


File: refman.info,  Node: al_lock_sample_id,  Next: al_unlock_sample_id,  Prev: al_stop_samples,  Up: Basic Audio

29.1.9 al_lock_sample_id
------------------------

ALLEGRO_SAMPLE_INSTANCE* al_lock_sample_id(ALLEGRO_SAMPLE_ID *spl_id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L417)

Locks a *note ALLEGRO_SAMPLE_ID: #allegro_sample_id, returning the
underlying *note ALLEGRO_SAMPLE_INSTANCE: #allegro_sample_instance.
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 ‘NULL’ if the sound corresponding to the id is
no longer playing.

While locked, ‘ALLEGRO_SAMPLE_ID’ will be unavailable to additional
calls to *note al_play_sample: #al_play_sample, even if the sound stops
while locked.  To put the ‘ALLEGRO_SAMPLE_ID’ back into the pool for
reuse, make sure to call ‘al_unlock_sample_id’ when you’re done with the
instance.

See also: *note al_play_sample: #al_play_sample, *note
al_unlock_sample_id: #al_unlock_sample_id.

Since: 5.2.3

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: al_unlock_sample_id,  Next: al_play_audio_stream,  Prev: al_lock_sample_id,  Up: Basic Audio

29.1.10 al_unlock_sample_id
---------------------------

void al_unlock_sample_id(ALLEGRO_SAMPLE_ID *spl_id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L435)

Unlocks a *note ALLEGRO_SAMPLE_ID: #allegro_sample_id, allowing future
calls to *note al_play_sample: #al_play_sample. to reuse it if possible.
Note that after the id is unlocked, the *note ALLEGRO_SAMPLE_INSTANCE:
#allegro_sample_instance. that was previously returned by *note
al_lock_sample_id: #al_lock_sample_id. will possibly be playing a
different sound, so you should only use it after locking the id again.

See also: *note al_play_sample: #al_play_sample, *note
al_lock_sample_id: #al_lock_sample_id.

Since: 5.2.3

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: al_play_audio_stream,  Next: al_play_audio_stream_f,  Prev: al_unlock_sample_id,  Up: Basic Audio

29.1.11 al_play_audio_stream
----------------------------

ALLEGRO_AUDIO_STREAM *al_play_audio_stream(const char *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L410)

Loads and plays an audio file from disk as it is needed.  This API can
only play one audio stream at a time.

Returns the stream on success, NULL on failure.  You must not destroy
the returned stream, it will be automatically destroyed when the addon
is shut down.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_play_audio_stream_f: #al_play_audio_stream_f, *note
al_load_audio_stream: #al_load_audio_stream.

Since: 5.2.8

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: al_play_audio_stream_f,  Prev: al_play_audio_stream,  Up: Basic Audio

29.1.12 al_play_audio_stream_f
------------------------------

ALLEGRO_AUDIO_STREAM *al_play_audio_stream_f(ALLEGRO_FILE *fp, const char *ident)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L433)

Loads and plays an audio file from *note ALLEGRO_FILE: #allegro_file.
stream as it is needed.

The file type is determined by the passed ‘ident’ parameter, which is a
file name extension including the leading dot.

Returns the stream on success, NULL on failure.  You must not destroy
the returned stream, it will be automatically destroyed when the addon
is shut down.  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.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_play_audio_stream: #al_play_audio_stream, *note
al_load_audio_stream_f: #al_load_audio_stream_f.

Since: 5.2.8

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: Samples,  Next: Advanced Audio,  Prev: Basic Audio,  Up: Audio addon

29.2 Samples
============

* Menu:

* ALLEGRO_SAMPLE::
* al_create_sample::
* al_load_sample::
* al_load_sample_f::
* al_save_sample::
* al_save_sample_f::
* al_destroy_sample::
* al_get_sample_channels::
* al_get_sample_depth::
* al_get_sample_frequency::
* al_get_sample_length::
* al_get_sample_data::


File: refman.info,  Node: ALLEGRO_SAMPLE,  Next: al_create_sample,  Up: Samples

29.2.1 ALLEGRO_SAMPLE
---------------------

typedef struct ALLEGRO_SAMPLE ALLEGRO_SAMPLE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L146)

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.

See also: *note ALLEGRO_SAMPLE_INSTANCE: #allegro_sample_instance.


File: refman.info,  Node: al_create_sample,  Next: al_load_sample,  Prev: ALLEGRO_SAMPLE,  Up: Samples

29.2.2 al_create_sample
-----------------------

ALLEGRO_SAMPLE *al_create_sample(void *buf, unsigned int samples,
   unsigned int freq, ALLEGRO_AUDIO_DEPTH depth,
   ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L135)

Create a sample data structure from the supplied buffer.  If ‘free_buf’
is true then the buffer will be freed with *note al_free: #al_free. when
the sample data structure is destroyed.  For portability (especially
Windows), the buffer should have been allocated with *note al_malloc:
#al_malloc.  Otherwise you should free the sample data yourself.

A sample that is referred to by the ‘samples’ parameter refers to a
sequence channel intensities.  E.g.  if you’re making a stereo sample
with the ‘samples’ set to 4, then the layout of the data in ‘buf’ will
be:

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:

int sample_size = al_get_channel_count(chan_conf)
                  * al_get_audio_depth_size(depth);
int bytes = samples * sample_size;
void *buffer = al_malloc(bytes);

See also: *note al_destroy_sample: #al_destroy_sample, *note
ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth, *note ALLEGRO_CHANNEL_CONF:
#allegro_channel_conf.


File: refman.info,  Node: al_load_sample,  Next: al_load_sample_f,  Prev: al_create_sample,  Up: Samples

29.2.3 al_load_sample
---------------------

ALLEGRO_SAMPLE *al_load_sample(const char *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L306)

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 *note
al_load_audio_stream: #al_load_audio_stream. or *note
al_play_audio_stream: #al_play_audio_stream.

Returns the sample on success, NULL on failure.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_register_sample_loader: #al_register_sample_loader,
*note al_init_acodec_addon: #al_init_acodec_addon.


File: refman.info,  Node: al_load_sample_f,  Next: al_save_sample,  Prev: al_load_sample,  Up: Samples

29.2.4 al_load_sample_f
-----------------------

ALLEGRO_SAMPLE *al_load_sample_f(ALLEGRO_FILE* fp, const char *ident)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L336)

Loads an audio file from an *note ALLEGRO_FILE: #allegro_file. stream
into an *note ALLEGRO_SAMPLE: #allegro_sample.  The file type is
determined by the passed ‘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 *note
al_load_audio_stream_f: #al_load_audio_stream_f. or *note
al_play_audio_stream_f: #al_play_audio_stream_f.

Returns the sample on success, NULL on failure.  The file remains open
afterwards.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_register_sample_loader_f:
#al_register_sample_loader_f, *note al_init_acodec_addon:
#al_init_acodec_addon.


File: refman.info,  Node: al_save_sample,  Next: al_save_sample_f,  Prev: al_load_sample_f,  Up: Samples

29.2.5 al_save_sample
---------------------

bool al_save_sample(const char *filename, ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L457)

Writes a sample into a file.  Currently, wav is the only supported
format, and the extension must be “.wav”.

Returns true on success, false on error.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_save_sample_f: #al_save_sample_f, *note
al_register_sample_saver: #al_register_sample_saver, *note
al_init_acodec_addon: #al_init_acodec_addon.


File: refman.info,  Node: al_save_sample_f,  Next: al_destroy_sample,  Prev: al_save_sample,  Up: Samples

29.2.6 al_save_sample_f
-----------------------

bool al_save_sample_f(ALLEGRO_FILE *fp, const char *ident, ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L484)

Writes a sample into a *note ALLEGRO_FILE: #allegro_file. filestream.
Currently, wav is the only supported format, and the extension must be
“.wav”.

Returns true on success, false on error.  The file remains open
afterwards.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_save_sample: #al_save_sample, *note
al_register_sample_saver_f: #al_register_sample_saver_f, *note
al_init_acodec_addon: #al_init_acodec_addon.


File: refman.info,  Node: al_destroy_sample,  Next: al_get_sample_channels,  Prev: al_save_sample_f,  Up: Samples

29.2.7 al_destroy_sample
------------------------

void al_destroy_sample(ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L188)

Free the sample data structure.  If it was created with the ‘free_buf’
parameter set to true, then the buffer will be freed with *note al_free:
#al_free.

This function will stop any sample instances which may be playing the
buffer referenced by the *note ALLEGRO_SAMPLE: #allegro_sample.

See also: *note al_destroy_sample_instance: #al_destroy_sample_instance,
*note al_stop_sample: #al_stop_sample, *note al_stop_samples:
#al_stop_samples.


File: refman.info,  Node: al_get_sample_channels,  Next: al_get_sample_depth,  Prev: al_destroy_sample,  Up: Samples

29.2.8 al_get_sample_channels
-----------------------------

ALLEGRO_CHANNEL_CONF al_get_sample_channels(const ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L494)

Return the channel configuration of the sample.

See also: *note ALLEGRO_CHANNEL_CONF: #allegro_channel_conf, *note
al_get_sample_depth: #al_get_sample_depth, *note
al_get_sample_frequency: #al_get_sample_frequency, *note
al_get_sample_length: #al_get_sample_length, *note al_get_sample_data:
#al_get_sample_data.


File: refman.info,  Node: al_get_sample_depth,  Next: al_get_sample_frequency,  Prev: al_get_sample_channels,  Up: Samples

29.2.9 al_get_sample_depth
--------------------------

ALLEGRO_AUDIO_DEPTH al_get_sample_depth(const ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L484)

Return the audio depth of the sample.

See also: *note ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth, *note
al_get_sample_channels: #al_get_sample_channels, *note
al_get_sample_frequency: #al_get_sample_frequency, *note
al_get_sample_length: #al_get_sample_length, *note al_get_sample_data:
#al_get_sample_data.


File: refman.info,  Node: al_get_sample_frequency,  Next: al_get_sample_length,  Prev: al_get_sample_depth,  Up: Samples

29.2.10 al_get_sample_frequency
-------------------------------

unsigned int al_get_sample_frequency(const ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L464)

Return the frequency (in Hz) of the sample.

See also: *note al_get_sample_channels: #al_get_sample_channels, *note
al_get_sample_depth: #al_get_sample_depth, *note al_get_sample_length:
#al_get_sample_length, *note al_get_sample_data: #al_get_sample_data.


File: refman.info,  Node: al_get_sample_length,  Next: al_get_sample_data,  Prev: al_get_sample_frequency,  Up: Samples

29.2.11 al_get_sample_length
----------------------------

unsigned int al_get_sample_length(const ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L474)

Return the length of the sample in sample values.

See also: *note al_get_sample_channels: #al_get_sample_channels, *note
al_get_sample_depth: #al_get_sample_depth, *note
al_get_sample_frequency: #al_get_sample_frequency, *note
al_get_sample_data: #al_get_sample_data.


File: refman.info,  Node: al_get_sample_data,  Prev: al_get_sample_length,  Up: Samples

29.2.12 al_get_sample_data
--------------------------

void *al_get_sample_data(const ALLEGRO_SAMPLE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L504)

Return a pointer to the raw sample data.

See also: *note al_get_sample_channels: #al_get_sample_channels, *note
al_get_sample_depth: #al_get_sample_depth, *note
al_get_sample_frequency: #al_get_sample_frequency, *note
al_get_sample_length: #al_get_sample_length.


File: refman.info,  Node: Advanced Audio,  Next: Sample instances,  Prev: Samples,  Up: Audio addon

29.3 Advanced Audio
===================

For more fine-grained control over audio output, here’s a short
description of the basic concepts:

Voices represent audio devices on the system.  Basically, every audio
output chain that you want to be heard needs to end up in a voice.  As
voices are on the hardware/driver side of things, there is only limited
control over their parameters (frequency, sample format, channel
configuration).  The number of available voices is limited as well.
Typically, you will only use one voice and attach a mixer to it.
Calling *note al_reserve_samples: #al_reserve_samples. will do this for
you by setting up a default voice and mixer; it can also be achieved by
calling *note al_restore_default_mixer: #al_restore_default_mixer.
Although you _can_ attach sample instances and audio streams directly to
a voice without using a mixer, it is, as of now, not recommended.  In
contrast to mixers, you can only attach a single object to a voice
anyway.

Mixers mix several sample instances and/or audio streams into a single
output buffer, converting sample data with differing formats according
to their output parameters (frequency, depth, channels) in the process.
In order to play several samples/streams at once reliably, you will need
at least one mixer.  A mixer that is not (indirectly) attached to a
voice will remain silent.  For most use cases, one (default) mixer
attached to a single voice will be sufficient.  You may attach mixers to
other mixers in order to create complex audio chains.

Samples (*note ALLEGRO_SAMPLE: #allegro_sample.) just represent
“passive” buffers for sample data in memory.  In order to play a sample,
a sample instance (*note ALLEGRO_SAMPLE_INSTANCE:
#allegro_sample_instance.) needs to be created and attached to a mixer
(or voice).  Sample instances control _how_ the underlying samples are
played.  Several playback parameters (position, speed, gain, pan,
playmode, playing/paused) can be adjusted.  Particularly, multiple
instances may be created from the same sample, e.g. with different
parameters.

Audio streams (*note ALLEGRO_AUDIO_STREAM: #allegro_audio_stream.) are
similar to sample instances insofar as they respond to the same playback
parameters and have to be attached to mixers or voices.  A single audio
stream can only be played once simultaneously.

For example, consider the following configuration of the audio system.

ALLEGRO_VOICE* voice = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16,
    ALLEGRO_CHANNEL_CONF_2);

ALLEGRO_MIXER* mixer_1 = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32,
    ALLEGRO_CHANNEL_CONF_2);
ALLEGRO_MIXER* mixer_2 = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32,
    ALLEGRO_CHANNEL_CONF_2);

/* Load a stream, the stream starts in a playing state and just needs
 * to be attached to actually output sound. */
ALLEGRO_AUDIO_STREAM* stream = al_load_audio_stream("music.ogg", 4, 2048);

/* The sample needs sample instances to output sound. */
ALLEGRO_SAMPLE* sample = al_load_sample("sound.wav")
ALLEGRO_SAMPLE_INSTANCE* instance_1 = al_create_sample_instance(sample);
ALLEGRO_SAMPLE_INSTANCE* instance_2 = al_create_sample_instance(sample);

/* Attach everything up (see diagram). */
al_attach_mixer_to_voice(mixer_1, voice);
al_attach_mixer_to_mixer(mixer_2, mixer_1);
al_attach_audio_stream_to_mixer(stream, mixer_1);
al_attach_sample_instance_to_mixer(instance_1, mixer_2);
al_attach_sample_instance_to_mixer(instance_2, mixer_2);

/* Play two copies of the sound simultaneously. */
al_set_sample_instance_playing(instance_1, true);
al_set_sample_instance_playing(instance_2, true);

[An example configuration of the audio system
to play music and a sound.]


_An example configuration of the audio system to play music and a
sound._
Since we have two mixers, with the sample instances connected to a
different mixer than the audio stream, you can control the volume of all
the instances independently from the music by setting the gain of the
mixer / stream.  Having two sample instances lets you play two copies of
the sample simultaneously.

With this in mind, another look at *note al_reserve_samples:
#al_reserve_samples. and *note al_play_sample: #al_play_sample. is due:
What the former does internally is to create a specified number of
sample instances that are “empty” at first, i.e. with no sample data
set.  When al_play_sample is called, it’ll use one of these internal
sample instances that is not currently playing to play the requested
sample.  All of these sample instances will be attached to the default
mixer, which can be changed via *note al_set_default_mixer:
#al_set_default_mixer.


File: refman.info,  Node: Sample instances,  Next: Audio streams,  Prev: Advanced Audio,  Up: Audio addon

29.4 Sample instances
=====================

* Menu:

* ALLEGRO_SAMPLE_INSTANCE::
* al_create_sample_instance::
* al_destroy_sample_instance::
* al_play_sample_instance::
* al_stop_sample_instance::
* al_get_sample_instance_channels::
* al_get_sample_instance_depth::
* al_get_sample_instance_frequency::
* al_get_sample_instance_length::
* al_set_sample_instance_length::
* al_get_sample_instance_position::
* al_set_sample_instance_position::
* al_get_sample_instance_speed::
* al_set_sample_instance_speed::
* al_get_sample_instance_gain::
* al_set_sample_instance_gain::
* al_get_sample_instance_pan::
* al_set_sample_instance_pan::
* al_get_sample_instance_time::
* al_get_sample_instance_playmode::
* al_set_sample_instance_playmode::
* al_get_sample_instance_playing::
* al_set_sample_instance_playing::
* al_get_sample_instance_attached::
* al_detach_sample_instance::
* al_get_sample::
* al_set_sample::
* al_set_sample_instance_channel_matrix::


File: refman.info,  Node: ALLEGRO_SAMPLE_INSTANCE,  Next: al_create_sample_instance,  Up: Sample instances

29.4.1 ALLEGRO_SAMPLE_INSTANCE
------------------------------

typedef struct ALLEGRO_SAMPLE_INSTANCE ALLEGRO_SAMPLE_INSTANCE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L161)

An ALLEGRO_SAMPLE_INSTANCE object 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 *note ALLEGRO_SAMPLE: #allegro_sample.
object.  Multiple instances may be created from the same ALLEGRO_SAMPLE.
An ALLEGRO_SAMPLE must not be destroyed while there are instances which
reference it.

To actually produce audio output, an ALLEGRO_SAMPLE_INSTANCE must be
attached to an *note ALLEGRO_MIXER: #allegro_mixer. which eventually
reaches an *note ALLEGRO_VOICE: #allegro_voice. object.

See also: *note ALLEGRO_SAMPLE: #allegro_sample.


File: refman.info,  Node: al_create_sample_instance,  Next: al_destroy_sample_instance,  Prev: ALLEGRO_SAMPLE_INSTANCE,  Up: Sample instances

29.4.2 al_create_sample_instance
--------------------------------

ALLEGRO_SAMPLE_INSTANCE *al_create_sample_instance(ALLEGRO_SAMPLE *sample_data)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L152)

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 NULL. You can then set the sample data later with
*note al_set_sample: #al_set_sample.

See also: *note al_destroy_sample_instance: #al_destroy_sample_instance.


File: refman.info,  Node: al_destroy_sample_instance,  Next: al_play_sample_instance,  Prev: al_create_sample_instance,  Up: Sample instances

29.4.3 al_destroy_sample_instance
---------------------------------

void al_destroy_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L195)

Detaches the sample instance from anything it may be attached to and
frees it (the sample data, i.e. its ALLEGRO_SAMPLE, is _not_ freed!).

See also: *note al_create_sample_instance: #al_create_sample_instance.


File: refman.info,  Node: al_play_sample_instance,  Next: al_stop_sample_instance,  Prev: al_destroy_sample_instance,  Up: Sample instances

29.4.4 al_play_sample_instance
------------------------------

bool al_play_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L218)

Play the sample instance.  Returns true on success, false on failure.

See also: *note al_stop_sample_instance: #al_stop_sample_instance.


File: refman.info,  Node: al_stop_sample_instance,  Next: al_get_sample_instance_channels,  Prev: al_play_sample_instance,  Up: Sample instances

29.4.5 al_stop_sample_instance
------------------------------

bool al_stop_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L228)

Stop an sample instance playing.

See also: *note al_play_sample_instance: #al_play_sample_instance.


File: refman.info,  Node: al_get_sample_instance_channels,  Next: al_get_sample_instance_depth,  Prev: al_stop_sample_instance,  Up: Sample instances

29.4.6 al_get_sample_instance_channels
--------------------------------------

ALLEGRO_CHANNEL_CONF al_get_sample_instance_channels(
   const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L324)

Return the channel configuration of the sample instance’s sample data.

See also: *note ALLEGRO_CHANNEL_CONF: #allegro_channel_conf.


File: refman.info,  Node: al_get_sample_instance_depth,  Next: al_get_sample_instance_frequency,  Prev: al_get_sample_instance_channels,  Up: Sample instances

29.4.7 al_get_sample_instance_depth
-----------------------------------

ALLEGRO_AUDIO_DEPTH al_get_sample_instance_depth(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L314)

Return the audio depth of the sample instance’s sample data.

See also: *note ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth.


File: refman.info,  Node: al_get_sample_instance_frequency,  Next: al_get_sample_instance_length,  Prev: al_get_sample_instance_depth,  Up: Sample instances

29.4.8 al_get_sample_instance_frequency
---------------------------------------

unsigned int al_get_sample_instance_frequency(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L238)

Return the frequency (in Hz) of the sample instance’s sample data.


File: refman.info,  Node: al_get_sample_instance_length,  Next: al_set_sample_instance_length,  Prev: al_get_sample_instance_frequency,  Up: Sample instances

29.4.9 al_get_sample_instance_length
------------------------------------

unsigned int al_get_sample_instance_length(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L248)

Return the length of the sample instance in sample values.  This
property may differ from the length of the instance’s sample data.

See also: *note al_set_sample_instance_length:
#al_set_sample_instance_length, *note al_get_sample_instance_time:
#al_get_sample_instance_time.


File: refman.info,  Node: al_set_sample_instance_length,  Next: al_get_sample_instance_position,  Prev: al_get_sample_instance_length,  Up: Sample instances

29.4.10 al_set_sample_instance_length
-------------------------------------

bool al_set_sample_instance_length(ALLEGRO_SAMPLE_INSTANCE *spl,
   unsigned int val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L392)

Set 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.

See also: *note al_get_sample_instance_length:
#al_get_sample_instance_length.


File: refman.info,  Node: al_get_sample_instance_position,  Next: al_set_sample_instance_position,  Prev: al_set_sample_instance_length,  Up: Sample instances

29.4.11 al_get_sample_instance_position
---------------------------------------

unsigned int al_get_sample_instance_position(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L258)

Get the playback position of a sample instance.

See also: *note al_set_sample_instance_position:
#al_set_sample_instance_position.


File: refman.info,  Node: al_set_sample_instance_position,  Next: al_get_sample_instance_speed,  Prev: al_get_sample_instance_position,  Up: Sample instances

29.4.12 al_set_sample_instance_position
---------------------------------------

bool al_set_sample_instance_position(ALLEGRO_SAMPLE_INSTANCE *spl,
   unsigned int val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L370)

Set the playback position of a sample instance.

Returns true on success, false on failure.

See also: *note al_get_sample_instance_position:
#al_get_sample_instance_position.


File: refman.info,  Node: al_get_sample_instance_speed,  Next: al_set_sample_instance_speed,  Prev: al_set_sample_instance_position,  Up: Sample instances

29.4.13 al_get_sample_instance_speed
------------------------------------

float al_get_sample_instance_speed(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L273)

Return the relative playback speed of the sample instance.

See also: *note al_set_sample_instance_speed:
#al_set_sample_instance_speed.


File: refman.info,  Node: al_set_sample_instance_speed,  Next: al_get_sample_instance_gain,  Prev: al_get_sample_instance_speed,  Up: Sample instances

29.4.14 al_set_sample_instance_speed
------------------------------------

bool al_set_sample_instance_speed(ALLEGRO_SAMPLE_INSTANCE *spl, float val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L411)

Set 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.

See also: *note al_get_sample_instance_speed:
#al_get_sample_instance_speed.


File: refman.info,  Node: al_get_sample_instance_gain,  Next: al_set_sample_instance_gain,  Prev: al_set_sample_instance_speed,  Up: Sample instances

29.4.15 al_get_sample_instance_gain
-----------------------------------

float al_get_sample_instance_gain(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L283)

Return the playback gain of the sample instance.

See also: *note al_set_sample_instance_gain:
#al_set_sample_instance_gain.


File: refman.info,  Node: al_set_sample_instance_gain,  Next: al_get_sample_instance_pan,  Prev: al_get_sample_instance_gain,  Up: Sample instances

29.4.16 al_set_sample_instance_gain
-----------------------------------

bool al_set_sample_instance_gain(ALLEGRO_SAMPLE_INSTANCE *spl, float val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L452)

Set the playback gain of the sample instance.

Returns true on success, false on failure.  Will fail if the sample
instance is attached directly to a voice.

See also: *note al_get_sample_instance_gain:
#al_get_sample_instance_gain.


File: refman.info,  Node: al_get_sample_instance_pan,  Next: al_set_sample_instance_pan,  Prev: al_set_sample_instance_gain,  Up: Sample instances

29.4.17 al_get_sample_instance_pan
----------------------------------

float al_get_sample_instance_pan(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L293)

Get the pan value of the sample instance.

See also: *note al_set_sample_instance_pan: #al_set_sample_instance_pan.


File: refman.info,  Node: al_set_sample_instance_pan,  Next: al_get_sample_instance_time,  Prev: al_get_sample_instance_pan,  Up: Sample instances

29.4.18 al_set_sample_instance_pan
----------------------------------

bool al_set_sample_instance_pan(ALLEGRO_SAMPLE_INSTANCE *spl, float val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L483)

Set 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
*note ALLEGRO_AUDIO_PAN_NONE: #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.

     Note: panning samples with more than two channels doesn’t work yet.
Returns true on success, false on failure.  Will fail if the sample
instance is attached directly to a voice.

See also: *note al_get_sample_instance_pan: #al_get_sample_instance_pan,
*note ALLEGRO_AUDIO_PAN_NONE: #allegro_audio_pan_none.


File: refman.info,  Node: al_get_sample_instance_time,  Next: al_get_sample_instance_playmode,  Prev: al_set_sample_instance_pan,  Up: Sample instances

29.4.19 al_get_sample_instance_time
-----------------------------------

float al_get_sample_instance_time(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L303)

Return the length of the sample instance in seconds, assuming a playback
speed of 1.0.

See also: *note al_get_sample_instance_length:
#al_get_sample_instance_length.


File: refman.info,  Node: al_get_sample_instance_playmode,  Next: al_set_sample_instance_playmode,  Prev: al_get_sample_instance_time,  Up: Sample instances

29.4.20 al_get_sample_instance_playmode
---------------------------------------

ALLEGRO_PLAYMODE al_get_sample_instance_playmode(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L335)

Return the playback mode of the sample instance.

See also: *note ALLEGRO_PLAYMODE: #allegro_playmode, *note
al_set_sample_instance_playmode: #al_set_sample_instance_playmode.


File: refman.info,  Node: al_set_sample_instance_playmode,  Next: al_get_sample_instance_playing,  Prev: al_get_sample_instance_playmode,  Up: Sample instances

29.4.21 al_set_sample_instance_playmode
---------------------------------------

bool al_set_sample_instance_playmode(ALLEGRO_SAMPLE_INSTANCE *spl,
   ALLEGRO_PLAYMODE val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L518)

Set the playback mode of the sample instance.

Returns true on success, false on failure.

See also: *note ALLEGRO_PLAYMODE: #allegro_playmode, *note
al_get_sample_instance_playmode: #al_get_sample_instance_playmode.


File: refman.info,  Node: al_get_sample_instance_playing,  Next: al_set_sample_instance_playing,  Prev: al_set_sample_instance_playmode,  Up: Sample instances

29.4.22 al_get_sample_instance_playing
--------------------------------------

bool al_get_sample_instance_playing(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L345)

Return true if the sample instance is in the playing state.  This may be
true even if the instance is not attached to anything.

See also: *note al_set_sample_instance_playing:
#al_set_sample_instance_playing.


File: refman.info,  Node: al_set_sample_instance_playing,  Next: al_get_sample_instance_attached,  Prev: al_get_sample_instance_playing,  Up: Sample instances

29.4.23 al_set_sample_instance_playing
--------------------------------------

bool al_set_sample_instance_playing(ALLEGRO_SAMPLE_INSTANCE *spl, bool val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L547)

Change whether the sample instance is playing.

The instance does not need to be attached to anything (since: 5.1.8).

Returns true on success, false on failure.

See also: *note al_get_sample_instance_playing:
#al_get_sample_instance_playing.


File: refman.info,  Node: al_get_sample_instance_attached,  Next: al_detach_sample_instance,  Prev: al_set_sample_instance_playing,  Up: Sample instances

29.4.24 al_get_sample_instance_attached
---------------------------------------

bool al_get_sample_instance_attached(const ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L360)

Return whether the sample instance is attached to something.

See also: *note al_attach_sample_instance_to_mixer:
#al_attach_sample_instance_to_mixer, *note
al_attach_sample_instance_to_voice: #al_attach_sample_instance_to_voice,
*note al_detach_sample_instance: #al_detach_sample_instance.


File: refman.info,  Node: al_detach_sample_instance,  Next: al_get_sample,  Prev: al_get_sample_instance_attached,  Up: Sample instances

29.4.25 al_detach_sample_instance
---------------------------------

bool al_detach_sample_instance(ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L575)

Detach the sample instance from whatever it’s attached to, if anything.

Returns true on success.

See also: *note al_attach_sample_instance_to_mixer:
#al_attach_sample_instance_to_mixer, *note
al_attach_sample_instance_to_voice: #al_attach_sample_instance_to_voice,
*note al_get_sample_instance_attached: #al_get_sample_instance_attached.


File: refman.info,  Node: al_get_sample,  Next: al_set_sample,  Prev: al_detach_sample_instance,  Up: Sample instances

29.4.26 al_get_sample
---------------------

ALLEGRO_SAMPLE *al_get_sample(ALLEGRO_SAMPLE_INSTANCE *spl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L652)

Return the sample data that the sample instance plays.

Note this returns a pointer to an internal structure, _not_ the *note
ALLEGRO_SAMPLE: #allegro_sample. that you may have passed to *note
al_set_sample: #al_set_sample.  However, the sample buffer of the
returned ALLEGRO_SAMPLE will be the same as the one that was used to
create the sample (passed to *note al_create_sample:
#al_create_sample.).  You can use *note al_get_sample_data:
#al_get_sample_data. on the return value to retrieve and compare it.

See also: *note al_set_sample: #al_set_sample.


File: refman.info,  Node: al_set_sample,  Next: al_set_sample_instance_channel_matrix,  Prev: al_get_sample,  Up: Sample instances

29.4.27 al_set_sample
---------------------

bool al_set_sample(ALLEGRO_SAMPLE_INSTANCE *spl, ALLEGRO_SAMPLE *data)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L587)

Change 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 NULL, the sample is detached from its parent (if any).

If data is not NULL, 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.

Returns true on success, false on failure.  On failure, the sample will
be stopped and detached from its parent.

See also: *note al_get_sample: #al_get_sample.


File: refman.info,  Node: al_set_sample_instance_channel_matrix,  Prev: al_set_sample,  Up: Sample instances

29.4.28 al_set_sample_instance_channel_matrix
---------------------------------------------

bool al_set_sample_instance_channel_matrix(ALLEGRO_SAMPLE_INSTANCE *spl, const float *matrix)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_instance.c#L662)

Set the matrix used to mix the channels coming from this instance into
the mixer it is attached to.  Normally Allegro derives the values of
this matrix from the gain and pan settings, as well as the channel
configurations of this instance and the mixer it is attached to, but
this allows you override that default value.  Note that if you do set
gain or pan of this instance or the mixer it is attached to, you’ll need
to call this function again.

The matrix has mixer channel rows and sample channel columns, and is row
major.  For example, if you have a stereo sample instance and want to
mix it to a 5.1 mixer you could use this code:

float matrix[] = {
    0.5, 0.0, /* Half left to front left */
    0.0, 0.5, /* Half right to front right */
    0.5, 0.0, /* Half left to rear left */
    0.0, 0.5, /* Half right to rear right */
    0.1, 0.1, /* Mix left and right for center */
    0.1, 0.1, /* Mix left and right for center */
};

al_set_sample_instance_channel_matrix(instance, matrix);

Returns true on success, false on failure (e.g. if this is not attached
to a mixer).

Since: 5.2.3

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: Audio streams,  Next: Advanced audio file I/O,  Prev: Sample instances,  Up: Audio addon

29.5 Audio streams
==================

* Menu:

* ALLEGRO_AUDIO_STREAM::
* al_create_audio_stream::
* al_load_audio_stream::
* al_load_audio_stream_f::
* al_destroy_audio_stream::
* al_get_audio_stream_event_source::
* al_drain_audio_stream::
* al_rewind_audio_stream::
* al_get_audio_stream_frequency::
* al_get_audio_stream_channels::
* al_get_audio_stream_depth::
* al_get_audio_stream_length::
* al_get_audio_stream_speed::
* al_set_audio_stream_speed::
* al_get_audio_stream_gain::
* al_set_audio_stream_gain::
* al_get_audio_stream_pan::
* al_set_audio_stream_pan::
* al_get_audio_stream_playing::
* al_set_audio_stream_playing::
* al_get_audio_stream_playmode::
* al_set_audio_stream_playmode::
* al_get_audio_stream_attached::
* al_detach_audio_stream::
* al_get_audio_stream_played_samples::
* al_get_audio_stream_fragment::
* al_set_audio_stream_fragment::
* al_get_audio_stream_fragments::
* al_get_available_audio_stream_fragments::
* al_seek_audio_stream_secs::
* al_get_audio_stream_position_secs::
* al_get_audio_stream_length_secs::
* al_set_audio_stream_loop_secs::
* al_set_audio_stream_channel_matrix::


File: refman.info,  Node: ALLEGRO_AUDIO_STREAM,  Next: al_create_audio_stream,  Up: Audio streams

29.5.1 ALLEGRO_AUDIO_STREAM
---------------------------

typedef struct ALLEGRO_AUDIO_STREAM ALLEGRO_AUDIO_STREAM;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L166)

An ALLEGRO_AUDIO_STREAM object 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 *note ALLEGRO_SAMPLE_INSTANCE: #allegro_sample_instance.
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 *note ALLEGRO_MIXER: #allegro_mixer, which,
eventually, reaches an *note ALLEGRO_VOICE: #allegro_voice. 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 *note al_get_available_audio_stream_fragments:
#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
*note al_get_audio_stream_event_source:
#al_get_audio_stream_event_source.  An *note
ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT:
#allegro_event_audio_stream_fragment. event is generated whenever a new
fragment is ready.  When you receive an event, use *note
al_get_audio_stream_fragment: #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 *note al_create_audio_stream:
#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 *note al_drain_audio_stream:
#al_drain_audio_stream. when you’re finished with supplying data to the
stream.

If the stream is created by *note al_load_audio_stream:
#al_load_audio_stream. or *note al_play_audio_stream:
#al_play_audio_stream. then it will also generate an *note
ALLEGRO_EVENT_AUDIO_STREAM_FINISHED:
#allegro_event_audio_stream_finished. event if it reaches the end of the
file and is not set to loop.


File: refman.info,  Node: al_create_audio_stream,  Next: al_load_audio_stream,  Prev: ALLEGRO_AUDIO_STREAM,  Up: Audio streams

29.5.2 al_create_audio_stream
-----------------------------

ALLEGRO_AUDIO_STREAM *al_create_audio_stream(size_t fragment_count,
   unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth,
   ALLEGRO_CHANNEL_CONF chan_conf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L49)

Creates an *note ALLEGRO_AUDIO_STREAM: #allegro_audio_stream.  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.

Parameters:

   • fragment_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.

   • frag_samples - The size of a fragment in samples.  See note and
     explanation below.

   • freq - The frequency, in Hertz.

   • depth - Must be one of the values listed for *note
     ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth.

   • chan_conf - Must be one of the values listed for *note
     ALLEGRO_CHANNEL_CONF: #allegro_channel_conf.

A sample that is referred to by the _frag_samples_ parameter refers to a
sequence channel intensities.  E.g.  if you’re making a stereo stream
with the _frag_samples_ set to 4, then the layout of the data in the
fragment will be:

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 _fragment_count_, _frag_samples_ and _freq_ directly
influences the audio delay.  The delay in seconds can be expressed as:

delay = fragment_count * frag_samples / freq

This is only the delay due to Allegro’s streaming, there may be
additional delay caused by sound drivers and/or hardware.

     _Note:_ If you know the fragment size in bytes, you can get the
     size in samples like this:

     sample_size = al_get_channel_count(chan_conf) * al_get_audio_depth_size(depth);
     samples = bytes_per_fragment / sample_size;

     The size of the complete buffer is:

     buffer_size = bytes_per_fragment * fragment_count

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


File: refman.info,  Node: al_load_audio_stream,  Next: al_load_audio_stream_f,  Prev: al_create_audio_stream,  Up: Audio streams

29.5.3 al_load_audio_stream
---------------------------

ALLEGRO_AUDIO_STREAM *al_load_audio_stream(const char *filename,
   size_t buffer_count, unsigned int samples)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L357)

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 _buffer_count_ buffers with
_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 *note
ALLEGRO_AUDIO_STREAM: #allegro_audio_stream. for more details.

Returns the stream on success, NULL on failure.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_load_audio_stream_f: #al_load_audio_stream_f, *note
al_register_audio_stream_loader: #al_register_audio_stream_loader, *note
al_init_acodec_addon: #al_init_acodec_addon.


File: refman.info,  Node: al_load_audio_stream_f,  Next: al_destroy_audio_stream,  Prev: al_load_audio_stream,  Up: Audio streams

29.5.4 al_load_audio_stream_f
-----------------------------

ALLEGRO_AUDIO_STREAM *al_load_audio_stream_f(ALLEGRO_FILE* fp, const char *ident,
   size_t buffer_count, unsigned int samples)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L388)

Loads an audio file from *note ALLEGRO_FILE: #allegro_file. 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 _buffer_count_ buffers with
_samples_ samples.

The file type is determined by the passed ‘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 *note
ALLEGRO_AUDIO_STREAM: #allegro_audio_stream. for more details.

Returns the stream on success, NULL 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.

     _Note:_ the allegro_audio library does not support any audio file
     formats by default.  You must use the allegro_acodec addon, or
     register your own format handler.
See also: *note al_load_audio_stream: #al_load_audio_stream, *note
al_register_audio_stream_loader_f: #al_register_audio_stream_loader_f,
*note al_init_acodec_addon: #al_init_acodec_addon.


File: refman.info,  Node: al_destroy_audio_stream,  Next: al_get_audio_stream_event_source,  Prev: al_load_audio_stream_f,  Up: Audio streams

29.5.5 al_destroy_audio_stream
------------------------------

void al_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L145)

Destroy an audio stream which was created with *note
al_create_audio_stream: #al_create_audio_stream. or *note
al_load_audio_stream: #al_load_audio_stream.

     _Note:_ If the stream is still attached to a mixer or voice, *note
     al_detach_audio_stream: #al_detach_audio_stream. is automatically
     called on it first.
See also: *note al_drain_audio_stream: #al_drain_audio_stream.


File: refman.info,  Node: al_get_audio_stream_event_source,  Next: al_drain_audio_stream,  Prev: al_destroy_audio_stream,  Up: Audio streams

29.5.6 al_get_audio_stream_event_source
---------------------------------------

ALLEGRO_EVENT_SOURCE *al_get_audio_stream_event_source(
   ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L911)

Retrieve the associated event source.

See *note al_get_audio_stream_fragment: #al_get_audio_stream_fragment.
for a description of the *note ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT:
#allegro_event_audio_stream_fragment. event that audio streams emit.


File: refman.info,  Node: al_drain_audio_stream,  Next: al_rewind_audio_stream,  Prev: al_get_audio_stream_event_source,  Up: Audio streams

29.5.7 al_drain_audio_stream
----------------------------

void al_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L165)

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.

See also: *note al_destroy_audio_stream: #al_destroy_audio_stream.


File: refman.info,  Node: al_rewind_audio_stream,  Next: al_get_audio_stream_frequency,  Prev: al_drain_audio_stream,  Up: Audio streams

29.5.8 al_rewind_audio_stream
-----------------------------

bool al_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L819)

Set the streaming file playing position to the beginning.  Returns true
on success.  Currently this can only be called on streams created with
*note al_load_audio_stream: #al_load_audio_stream, *note
al_play_audio_stream: #al_play_audio_stream, *note
al_load_audio_stream_f: #al_load_audio_stream_f. or *note
al_play_audio_stream_f: #al_play_audio_stream_f.


File: refman.info,  Node: al_get_audio_stream_frequency,  Next: al_get_audio_stream_channels,  Prev: al_rewind_audio_stream,  Up: Audio streams

29.5.9 al_get_audio_stream_frequency
------------------------------------

unsigned int al_get_audio_stream_frequency(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L184)

Return the stream frequency (in Hz).


File: refman.info,  Node: al_get_audio_stream_channels,  Next: al_get_audio_stream_depth,  Prev: al_get_audio_stream_frequency,  Up: Audio streams

29.5.10 al_get_audio_stream_channels
------------------------------------

ALLEGRO_CHANNEL_CONF al_get_audio_stream_channels(
   const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L258)

Return the stream channel configuration.

See also: *note ALLEGRO_CHANNEL_CONF: #allegro_channel_conf.


File: refman.info,  Node: al_get_audio_stream_depth,  Next: al_get_audio_stream_length,  Prev: al_get_audio_stream_channels,  Up: Audio streams

29.5.11 al_get_audio_stream_depth
---------------------------------

ALLEGRO_AUDIO_DEPTH al_get_audio_stream_depth(
   const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L269)

Return the stream audio depth.

See also: *note ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth.


File: refman.info,  Node: al_get_audio_stream_length,  Next: al_get_audio_stream_speed,  Prev: al_get_audio_stream_depth,  Up: Audio streams

29.5.12 al_get_audio_stream_length
----------------------------------

unsigned int al_get_audio_stream_length(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L194)

Return the stream length in samples.


File: refman.info,  Node: al_get_audio_stream_speed,  Next: al_set_audio_stream_speed,  Prev: al_get_audio_stream_length,  Up: Audio streams

29.5.13 al_get_audio_stream_speed
---------------------------------

float al_get_audio_stream_speed(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L228)

Return the relative playback speed of the stream.

See also: *note al_set_audio_stream_speed: #al_set_audio_stream_speed.


File: refman.info,  Node: al_set_audio_stream_speed,  Next: al_get_audio_stream_gain,  Prev: al_get_audio_stream_speed,  Up: Audio streams

29.5.14 al_set_audio_stream_speed
---------------------------------

bool al_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L360)

Set 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.

See also: *note al_get_audio_stream_speed: #al_get_audio_stream_speed.


File: refman.info,  Node: al_get_audio_stream_gain,  Next: al_set_audio_stream_gain,  Prev: al_set_audio_stream_speed,  Up: Audio streams

29.5.15 al_get_audio_stream_gain
--------------------------------

float al_get_audio_stream_gain(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L238)

Return the playback gain of the stream.

See also: *note al_set_audio_stream_gain: #al_set_audio_stream_gain.


File: refman.info,  Node: al_set_audio_stream_gain,  Next: al_get_audio_stream_pan,  Prev: al_get_audio_stream_gain,  Up: Audio streams

29.5.16 al_set_audio_stream_gain
--------------------------------

bool al_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L397)

Set the playback gain of the stream.

Returns true on success, false on failure.  Will fail if the audio
stream is attached directly to a voice.

See also: *note al_get_audio_stream_gain: #al_get_audio_stream_gain.


File: refman.info,  Node: al_get_audio_stream_pan,  Next: al_set_audio_stream_pan,  Prev: al_set_audio_stream_gain,  Up: Audio streams

29.5.17 al_get_audio_stream_pan
-------------------------------

float al_get_audio_stream_pan(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L248)

Get the pan value of the stream.

See also: *note al_set_audio_stream_pan: #al_set_audio_stream_pan.


File: refman.info,  Node: al_set_audio_stream_pan,  Next: al_get_audio_stream_playing,  Prev: al_get_audio_stream_pan,  Up: Audio streams

29.5.18 al_set_audio_stream_pan
-------------------------------

bool al_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L427)

Set 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 *note
ALLEGRO_AUDIO_PAN_NONE: #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.

Returns true on success, false on failure.  Will fail if the audio
stream is attached directly to a voice.

See also: *note al_get_audio_stream_pan: #al_get_audio_stream_pan, *note
ALLEGRO_AUDIO_PAN_NONE: #allegro_audio_pan_none.


File: refman.info,  Node: al_get_audio_stream_playing,  Next: al_set_audio_stream_playing,  Prev: al_set_audio_stream_pan,  Up: Audio streams

29.5.19 al_get_audio_stream_playing
-----------------------------------

bool al_get_audio_stream_playing(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L291)

Return true if the stream is playing.

See also: *note al_set_audio_stream_playing:
#al_set_audio_stream_playing.


File: refman.info,  Node: al_set_audio_stream_playing,  Next: al_get_audio_stream_playmode,  Prev: al_get_audio_stream_playing,  Up: Audio streams

29.5.20 al_set_audio_stream_playing
-----------------------------------

bool al_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L540)

Change whether the stream is playing.

Returns true on success, false on failure.

See also: *note al_get_audio_stream_playing:
#al_get_audio_stream_playing.


File: refman.info,  Node: al_get_audio_stream_playmode,  Next: al_set_audio_stream_playmode,  Prev: al_set_audio_stream_playing,  Up: Audio streams

29.5.21 al_get_audio_stream_playmode
------------------------------------

ALLEGRO_PLAYMODE al_get_audio_stream_playmode(
   const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L280)

Return the playback mode of the stream.

See also: *note ALLEGRO_PLAYMODE: #allegro_playmode, *note
al_set_audio_stream_playmode: #al_set_audio_stream_playmode.


File: refman.info,  Node: al_set_audio_stream_playmode,  Next: al_get_audio_stream_attached,  Prev: al_get_audio_stream_playmode,  Up: Audio streams

29.5.22 al_set_audio_stream_playmode
------------------------------------

bool al_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream,
   ALLEGRO_PLAYMODE val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L461)

Set the playback mode of the stream.

Returns true on success, false on failure.

See also: *note ALLEGRO_PLAYMODE: #allegro_playmode, *note
al_get_audio_stream_playmode: #al_get_audio_stream_playmode.


File: refman.info,  Node: al_get_audio_stream_attached,  Next: al_detach_audio_stream,  Prev: al_set_audio_stream_playmode,  Up: Audio streams

29.5.23 al_get_audio_stream_attached
------------------------------------

bool al_get_audio_stream_attached(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L301)

Return whether the stream is attached to something.

See also: *note al_attach_audio_stream_to_mixer:
#al_attach_audio_stream_to_mixer, *note al_attach_audio_stream_to_voice:
#al_attach_audio_stream_to_voice, *note al_detach_audio_stream:
#al_detach_audio_stream.


File: refman.info,  Node: al_detach_audio_stream,  Next: al_get_audio_stream_played_samples,  Prev: al_get_audio_stream_attached,  Up: Audio streams

29.5.24 al_detach_audio_stream
------------------------------

bool al_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L576)

Detach the stream from whatever it’s attached to, if anything.

See also: *note al_attach_audio_stream_to_mixer:
#al_attach_audio_stream_to_mixer, *note al_attach_audio_stream_to_voice:
#al_attach_audio_stream_to_voice, *note al_get_audio_stream_attached:
#al_get_audio_stream_attached.


File: refman.info,  Node: al_get_audio_stream_played_samples,  Next: al_get_audio_stream_fragment,  Prev: al_detach_audio_stream,  Up: Audio streams

29.5.25 al_get_audio_stream_played_samples
------------------------------------------

uint64_t al_get_audio_stream_played_samples(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L310)

Get the number of samples consumed by the parent since the audio stream
was started.

Since: 5.1.8


File: refman.info,  Node: al_get_audio_stream_fragment,  Next: al_set_audio_stream_fragment,  Prev: al_get_audio_stream_played_samples,  Up: Audio streams

29.5.26 al_get_audio_stream_fragment
------------------------------------

void *al_get_audio_stream_fragment(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L331)

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 *note
al_create_audio_stream: #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 *note
al_set_audio_stream_fragment: #al_set_audio_stream_fragment.

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

     _Note:_ If you listen to events from the stream, an *note
     ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT:
     #allegro_event_audio_stream_fragment. event will be generated
     whenever a new fragment is ready.  However, getting an event is
     _not_ a guarantee that *note al_get_audio_stream_fragment:
     #al_get_audio_stream_fragment. will not return NULL, so you still
     must check for it.
See also: *note al_set_audio_stream_fragment:
#al_set_audio_stream_fragment, *note al_get_audio_stream_event_source:
#al_get_audio_stream_event_source, *note al_get_audio_stream_frequency:
#al_get_audio_stream_frequency, *note al_get_audio_stream_channels:
#al_get_audio_stream_channels, *note al_get_audio_stream_depth:
#al_get_audio_stream_depth, *note al_get_audio_stream_length:
#al_get_audio_stream_length.


File: refman.info,  Node: al_set_audio_stream_fragment,  Next: al_get_audio_stream_fragments,  Prev: al_get_audio_stream_fragment,  Up: Audio streams

29.5.27 al_set_audio_stream_fragment
------------------------------------

bool al_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L588)

This function needs to be called for every successful call of *note
al_get_audio_stream_fragment: #al_get_audio_stream_fragment. to indicate
that the buffer (pointed to by ‘val’) is filled with new data.

See also: *note al_get_audio_stream_fragment:
#al_get_audio_stream_fragment.


File: refman.info,  Node: al_get_audio_stream_fragments,  Next: al_get_available_audio_stream_fragments,  Prev: al_set_audio_stream_fragment,  Up: Audio streams

29.5.28 al_get_audio_stream_fragments
-------------------------------------

unsigned int al_get_audio_stream_fragments(const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L204)

Returns the number of fragments this stream uses.  This is the same
value as passed to *note al_create_audio_stream:
#al_create_audio_stream. when a new stream is created.

See also: *note al_get_available_audio_stream_fragments:
#al_get_available_audio_stream_fragments.


File: refman.info,  Node: al_get_available_audio_stream_fragments,  Next: al_seek_audio_stream_secs,  Prev: al_get_audio_stream_fragments,  Up: Audio streams

29.5.29 al_get_available_audio_stream_fragments
-----------------------------------------------

unsigned int al_get_available_audio_stream_fragments(
   const ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L214)

Returns the number of available fragments in the stream, that is,
fragments which are not currently filled with data for playback.

See also: *note al_get_audio_stream_fragment:
#al_get_audio_stream_fragment, *note al_get_audio_stream_fragments:
#al_get_audio_stream_fragments.


File: refman.info,  Node: al_seek_audio_stream_secs,  Next: al_get_audio_stream_position_secs,  Prev: al_get_available_audio_stream_fragments,  Up: Audio streams

29.5.30 al_seek_audio_stream_secs
---------------------------------

bool al_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double time)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L837)

Set the streaming file playing position to time.  Returns true on
success.  Currently this can only be called on streams created with
*note al_load_audio_stream: #al_load_audio_stream, *note
al_play_audio_stream: #al_play_audio_stream, *note
al_load_audio_stream_f: #al_load_audio_stream_f. or *note
al_play_audio_stream_f: #al_play_audio_stream_f.

See also: *note al_get_audio_stream_position_secs:
#al_get_audio_stream_position_secs, *note
al_get_audio_stream_length_secs: #al_get_audio_stream_length_secs.


File: refman.info,  Node: al_get_audio_stream_position_secs,  Next: al_get_audio_stream_length_secs,  Prev: al_seek_audio_stream_secs,  Up: Audio streams

29.5.31 al_get_audio_stream_position_secs
-----------------------------------------

double al_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L855)

Return the position of the stream in seconds.  Currently this can only
be called on streams created with *note al_load_audio_stream:
#al_load_audio_stream, *note al_play_audio_stream:
#al_play_audio_stream, *note al_load_audio_stream_f:
#al_load_audio_stream_f. or *note al_play_audio_stream_f:
#al_play_audio_stream_f.

See also: *note al_get_audio_stream_length_secs:
#al_get_audio_stream_length_secs.


File: refman.info,  Node: al_get_audio_stream_length_secs,  Next: al_set_audio_stream_loop_secs,  Prev: al_get_audio_stream_position_secs,  Up: Audio streams

29.5.32 al_get_audio_stream_length_secs
---------------------------------------

double al_get_audio_stream_length_secs(ALLEGRO_AUDIO_STREAM *stream)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L872)

Return the length of the stream in seconds, if known.  Otherwise returns
zero.

Currently this can only be called on streams created with *note
al_load_audio_stream: #al_load_audio_stream, *note al_play_audio_stream:
#al_play_audio_stream, *note al_load_audio_stream_f:
#al_load_audio_stream_f. or *note al_play_audio_stream_f:
#al_play_audio_stream_f.

See also: *note al_get_audio_stream_position_secs:
#al_get_audio_stream_position_secs.


File: refman.info,  Node: al_set_audio_stream_loop_secs,  Next: al_set_audio_stream_channel_matrix,  Prev: al_get_audio_stream_length_secs,  Up: Audio streams

29.5.33 al_set_audio_stream_loop_secs
-------------------------------------

bool al_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream,
   double start, double end)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_stream.c#L889)

Sets the loop points for the stream in seconds.  Currently this can only
be called on streams created with *note al_load_audio_stream:
#al_load_audio_stream, *note al_play_audio_stream:
#al_play_audio_stream, *note al_load_audio_stream_f:
#al_load_audio_stream_f. or *note al_play_audio_stream_f:
#al_play_audio_stream_f.


File: refman.info,  Node: al_set_audio_stream_channel_matrix,  Prev: al_set_audio_stream_loop_secs,  Up: Audio streams

29.5.34 al_set_audio_stream_channel_matrix
------------------------------------------

Source Code

Like *note al_set_sample_instance_channel_matrix:
#al_set_sample_instance_channel_matrix. but for streams.

Since: 5.2.3

     _*note Unstable API: #unstable-api.:_ New API.


File: refman.info,  Node: Advanced audio file I/O,  Next: Audio recording,  Prev: Audio streams,  Up: Audio addon

29.6 Advanced audio file I/O
============================

* Menu:

* al_register_sample_loader::
* al_register_sample_loader_f::
* al_register_sample_saver::
* al_register_sample_saver_f::
* al_register_audio_stream_loader::
* al_register_audio_stream_loader_f::
* al_register_sample_identifier::
* al_identify_sample::
* al_identify_sample_f::


File: refman.info,  Node: al_register_sample_loader,  Next: al_register_sample_loader_f,  Up: Advanced audio file I/O

29.6.1 al_register_sample_loader
--------------------------------

bool al_register_sample_loader(const char *ext,
   ALLEGRO_SAMPLE *(*loader)(const char *filename))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L115)

Register a handler for *note al_load_sample: #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 (‘.’) character.  It will
be matched case-insensitively.

The ‘loader’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_sample_loader_f:
#al_register_sample_loader_f, *note al_register_sample_saver:
#al_register_sample_saver.


File: refman.info,  Node: al_register_sample_loader_f,  Next: al_register_sample_saver,  Prev: al_register_sample_loader,  Up: Advanced audio file I/O

29.6.2 al_register_sample_loader_f
----------------------------------

bool al_register_sample_loader_f(const char *ext,
   ALLEGRO_SAMPLE *(*loader)(ALLEGRO_FILE* fp))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L142)

Register a handler for *note al_load_sample_f: #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 (‘.’) character.  It will
be matched case-insensitively.

The ‘loader’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_sample_loader: #al_register_sample_loader.


File: refman.info,  Node: al_register_sample_saver,  Next: al_register_sample_saver_f,  Prev: al_register_sample_loader_f,  Up: Advanced audio file I/O

29.6.3 al_register_sample_saver
-------------------------------

bool al_register_sample_saver(const char *ext,
   bool (*saver)(const char *filename, ALLEGRO_SAMPLE *spl))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L169)

Register a handler for *note al_save_sample: #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 (‘.’) character.  It will
be matched case-insensitively.

The ‘saver’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_sample_saver_f: #al_register_sample_saver_f,
*note al_register_sample_loader: #al_register_sample_loader.


File: refman.info,  Node: al_register_sample_saver_f,  Next: al_register_audio_stream_loader,  Prev: al_register_sample_saver,  Up: Advanced audio file I/O

29.6.4 al_register_sample_saver_f
---------------------------------

bool al_register_sample_saver_f(const char *ext,
   bool (*saver)(ALLEGRO_FILE* fp, ALLEGRO_SAMPLE *spl))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L196)

Register a handler for *note al_save_sample_f: #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 (‘.’) character.  It will
be matched case-insensitively.

The ‘saver’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_sample_saver: #al_register_sample_saver.


File: refman.info,  Node: al_register_audio_stream_loader,  Next: al_register_audio_stream_loader_f,  Prev: al_register_sample_saver_f,  Up: Advanced audio file I/O

29.6.5 al_register_audio_stream_loader
--------------------------------------

bool al_register_audio_stream_loader(const char *ext,
   ALLEGRO_AUDIO_STREAM *(*stream_loader)(const char *filename,
      size_t buffer_count, unsigned int samples))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L223)

Register a handler for *note al_load_audio_stream:
#al_load_audio_stream. and *note al_play_audio_stream:
#al_play_audio_stream.  The given function will be used to open streams
from files with the given extension.

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

The ‘stream_loader’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_audio_stream_loader_f:
#al_register_audio_stream_loader_f.


File: refman.info,  Node: al_register_audio_stream_loader_f,  Next: al_register_sample_identifier,  Prev: al_register_audio_stream_loader,  Up: Advanced audio file I/O

29.6.6 al_register_audio_stream_loader_f
----------------------------------------

bool al_register_audio_stream_loader_f(const char *ext,
   ALLEGRO_AUDIO_STREAM *(*stream_loader)(ALLEGRO_FILE* fp,
      size_t buffer_count, unsigned int samples))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L251)

Register a handler for *note al_load_audio_stream_f:
#al_load_audio_stream_f. and *note al_play_audio_stream_f:
#al_play_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 (‘.’) character.  It will
be matched case-insensitively.

The ‘stream_loader’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_register_audio_stream_loader:
#al_register_audio_stream_loader.


File: refman.info,  Node: al_register_sample_identifier,  Next: al_identify_sample,  Prev: al_register_audio_stream_loader_f,  Up: Advanced audio file I/O

29.6.7 al_register_sample_identifier
------------------------------------

bool al_register_sample_identifier(const char *ext,
   bool (*identifier)(ALLEGRO_FILE* fp))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L279)

Register an identify handler for *note al_identify_sample:
#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 *note ALLEGRO_FILE: #allegro_file. 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 NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

Since: 5.2.8

See also: *note al_identify_bitmap: #al_identify_bitmap.


File: refman.info,  Node: al_identify_sample,  Next: al_identify_sample_f,  Prev: al_register_sample_identifier,  Up: Advanced audio file I/O

29.6.8 al_identify_sample
-------------------------

char const *al_identify_sample(char const *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L516)

This works exactly as *note al_identify_sample_f: #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.

Since: 5.2.8

See also: *note al_init_acodec_addon: #al_init_acodec_addon, *note
al_identify_sample_f: #al_identify_sample_f, *note
al_register_sample_identifier: #al_register_sample_identifier.


File: refman.info,  Node: al_identify_sample_f,  Prev: al_identify_sample,  Up: Advanced audio file I/O

29.6.9 al_identify_sample_f
---------------------------

char const *al_identify_sample_f(ALLEGRO_FILE *fp)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio_io.c#L505)

Tries to guess the audio file type of the open ALLEGRO_FILE by reading
the first few bytes.  By default Allegro cannot recognize any file
types, but calling *note al_init_acodec_addon: #al_init_acodec_addon.
will add detection of the types it can read.  You can also use *note
al_register_sample_identifier: #al_register_sample_identifier. to add
identification for custom file types.

Returns a pointer to a static string with a file extension for the type,
including the leading dot.  For example “.wav” or “.ogg”.  Returns NULL
if the audio type cannot be determined.

Since: 5.2.8

See also: *note al_init_acodec_addon: #al_init_acodec_addon, *note
al_identify_sample: #al_identify_sample, *note
al_register_sample_identifier: #al_register_sample_identifier.


File: refman.info,  Node: Audio recording,  Next: Audio devices,  Prev: Advanced audio file I/O,  Up: Audio addon

29.7 Audio recording
====================

Allegro’s audio recording routines give you real-time access to raw,
uncompressed audio input streams.  Since Allegro hides all of the
platform specific implementation details with its own buffering, it will
add a small amount of latency.  However, for most applications that
small overhead will not adversely affect performance.

Recording is supported by the ALSA, AudioQueue, DirectSound8, and
PulseAudio drivers.  Enumerating or choosing other recording devices is
not yet supported.

* Menu:

* ALLEGRO_AUDIO_RECORDER::
* ALLEGRO_AUDIO_RECORDER_EVENT::
* al_create_audio_recorder::
* al_start_audio_recorder::
* al_stop_audio_recorder::
* al_is_audio_recorder_recording::
* al_get_audio_recorder_event::
* al_get_audio_recorder_event_source::
* al_destroy_audio_recorder::


File: refman.info,  Node: ALLEGRO_AUDIO_RECORDER,  Next: ALLEGRO_AUDIO_RECORDER_EVENT,  Up: Audio recording

29.7.1 ALLEGRO_AUDIO_RECORDER
-----------------------------

typedef struct ALLEGRO_AUDIO_RECORDER ALLEGRO_AUDIO_RECORDER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L186)

An opaque datatype that represents a recording device.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: ALLEGRO_AUDIO_RECORDER_EVENT,  Next: al_create_audio_recorder,  Prev: ALLEGRO_AUDIO_RECORDER,  Up: Audio recording

29.7.2 ALLEGRO_AUDIO_RECORDER_EVENT
-----------------------------------

typedef struct ALLEGRO_AUDIO_RECORDER_EVENT ALLEGRO_AUDIO_RECORDER_EVENT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L58)

Structure that holds the audio recorder event data.  Every event type
will contain:

   • .source: pointer to the audio recorder

The following will be available depending on the event type:

   • .buffer: pointer to buffer containing the audio samples
   • .samples: number of samples (not bytes) that are available

Since 5.1.1

See also: *note al_get_audio_recorder_event:
#al_get_audio_recorder_event.

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_create_audio_recorder,  Next: al_start_audio_recorder,  Prev: ALLEGRO_AUDIO_RECORDER_EVENT,  Up: Audio recording

29.7.3 al_create_audio_recorder
-------------------------------

ALLEGRO_AUDIO_RECORDER *al_create_audio_recorder(size_t fragment_count,
   unsigned int samples, unsigned int frequency,
   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L18)

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
fragment_count to hold a few seconds of audio.

frequency is the number of samples per second to record.  Common values
are:

   • 8000 - telephone quality speech
   • 11025
   • 22050
   • 44100 - CD quality music (if 16-bit, stereo)

For maximum compatibility, use a depth of ALLEGRO_AUDIO_DEPTH_UINT8 or
ALLEGRO_AUDIO_DEPTH_INT16, and a single (mono) channel.

The recorder will not record until you start it with *note
al_start_audio_recorder: #al_start_audio_recorder.

On failure, returns NULL.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_start_audio_recorder,  Next: al_stop_audio_recorder,  Prev: al_create_audio_recorder,  Up: Audio recording

29.7.4 al_start_audio_recorder
------------------------------

bool al_start_audio_recorder(ALLEGRO_AUDIO_RECORDER *r)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L89)

Begin recording into the fragment buffer.  Once a complete fragment has
been captured (as specified in *note al_create_audio_recorder:
#al_create_audio_recorder.), an *note
ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT:
#allegro_event_audio_recorder_fragment. event will be triggered.

Returns true if it was able to begin recording.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_stop_audio_recorder,  Next: al_is_audio_recorder_recording,  Prev: al_start_audio_recorder,  Up: Audio recording

29.7.5 al_stop_audio_recorder
-----------------------------

void al_stop_audio_recorder(ALLEGRO_AUDIO_RECORDER *r)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L103)

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 *note al_destroy_audio_recorder:
#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.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_is_audio_recorder_recording,  Next: al_get_audio_recorder_event,  Prev: al_stop_audio_recorder,  Up: Audio recording

29.7.6 al_is_audio_recorder_recording
-------------------------------------

bool al_is_audio_recorder_recording(ALLEGRO_AUDIO_RECORDER *r)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L115)

Returns true if the audio recorder is currently capturing data and
generating events.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_get_audio_recorder_event,  Next: al_get_audio_recorder_event_source,  Prev: al_is_audio_recorder_recording,  Up: Audio recording

29.7.7 al_get_audio_recorder_event
----------------------------------

ALLEGRO_AUDIO_RECORDER_EVENT *al_get_audio_recorder_event(ALLEGRO_EVENT *event)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L128)

Returns the event as an *note ALLEGRO_AUDIO_RECORDER_EVENT:
#allegro_audio_recorder_event.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_get_audio_recorder_event_source,  Next: al_destroy_audio_recorder,  Prev: al_get_audio_recorder_event,  Up: Audio recording

29.7.8 al_get_audio_recorder_event_source
-----------------------------------------

ALLEGRO_EVENT_SOURCE *al_get_audio_recorder_event_source(ALLEGRO_AUDIO_RECORDER *r)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L136)

Returns the event source for the recorder that generates the various
recording events.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_destroy_audio_recorder,  Prev: al_get_audio_recorder_event_source,  Up: Audio recording

29.7.9 al_destroy_audio_recorder
--------------------------------

void al_destroy_audio_recorder(ALLEGRO_AUDIO_RECORDER *r)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/recorder.c#L143)

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.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: Audio devices,  Next: Voices,  Prev: Audio recording,  Up: Audio addon

29.8 Audio devices
==================

* Menu:

* ALLEGRO_AUDIO_DEVICE::
* al_get_num_audio_output_devices::
* al_get_audio_output_device::
* al_get_audio_device_name::


File: refman.info,  Node: ALLEGRO_AUDIO_DEVICE,  Next: al_get_num_audio_output_devices,  Up: Audio devices

29.8.1 ALLEGRO_AUDIO_DEVICE
---------------------------

typedef struct ALLEGRO_AUDIO_DEVICE ALLEGRO_AUDIO_DEVICE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L180)

An opaque datatype that represents an audio device.


File: refman.info,  Node: al_get_num_audio_output_devices,  Next: al_get_audio_output_device,  Prev: ALLEGRO_AUDIO_DEVICE,  Up: Audio devices

29.8.2 al_get_num_audio_output_devices
--------------------------------------

int al_get_num_audio_output_devices()

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L201)

Get the number of available audio output devices on the system.

Since: 5.2.8

return -1 for unsupported drivers.


File: refman.info,  Node: al_get_audio_output_device,  Next: al_get_audio_device_name,  Prev: al_get_num_audio_output_devices,  Up: Audio devices

29.8.3 al_get_audio_output_device
---------------------------------

const ALLEGRO_AUDIO_DEVICE* al_get_audio_output_device(int index)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L218)

Get the output audio device of the specified index.

Since: 5.2.8


File: refman.info,  Node: al_get_audio_device_name,  Prev: al_get_audio_output_device,  Up: Audio devices

29.8.4 al_get_audio_device_name
-------------------------------

const char* al_get_audio_device_name(const ALLEGRO_AUDIO_DEVICE * device)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L238)

Get the user friendly display name of the device.

Since: 5.2.8


File: refman.info,  Node: Voices,  Next: Mixers,  Prev: Audio devices,  Up: Audio addon

29.9 Voices
===========

* Menu:

* ALLEGRO_VOICE::
* al_create_voice::
* al_destroy_voice::
* al_detach_voice::
* al_attach_audio_stream_to_voice::
* al_attach_mixer_to_voice::
* al_attach_sample_instance_to_voice::
* al_get_voice_frequency::
* al_get_voice_channels::
* al_get_voice_depth::
* al_get_voice_playing::
* al_set_voice_playing::
* al_get_voice_position::
* al_set_voice_position::


File: refman.info,  Node: ALLEGRO_VOICE,  Next: al_create_voice,  Up: Voices

29.9.1 ALLEGRO_VOICE
--------------------

typedef struct ALLEGRO_VOICE ALLEGRO_VOICE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L176)

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.

See also: *note ALLEGRO_MIXER: #allegro_mixer, *note ALLEGRO_SAMPLE:
#allegro_sample, *note ALLEGRO_AUDIO_STREAM: #allegro_audio_stream.


File: refman.info,  Node: al_create_voice,  Next: al_destroy_voice,  Prev: ALLEGRO_VOICE,  Up: Voices

29.9.2 al_create_voice
----------------------

ALLEGRO_VOICE *al_create_voice(unsigned int freq,
   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L65)

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.

Reasonable default arguments are:

al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2)

See also: *note al_destroy_voice: #al_destroy_voice.


File: refman.info,  Node: al_destroy_voice,  Next: al_detach_voice,  Prev: al_create_voice,  Up: Voices

29.9.3 al_destroy_voice
-----------------------

void al_destroy_voice(ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L106)

Destroys the voice and deallocates it from the digital driver.  Does
nothing if the voice is NULL.

See also: *note al_create_voice: #al_create_voice.


File: refman.info,  Node: al_detach_voice,  Next: al_attach_audio_stream_to_voice,  Prev: al_destroy_voice,  Up: Voices

29.9.4 al_detach_voice
----------------------

void al_detach_voice(ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L370)

Detaches the mixer, sample instance or audio stream from the voice.

See also: *note al_attach_mixer_to_voice: #al_attach_mixer_to_voice,
*note al_attach_sample_instance_to_voice:
#al_attach_sample_instance_to_voice, *note
al_attach_audio_stream_to_voice: #al_attach_audio_stream_to_voice.


File: refman.info,  Node: al_attach_audio_stream_to_voice,  Next: al_attach_mixer_to_voice,  Prev: al_detach_voice,  Up: Voices

29.9.5 al_attach_audio_stream_to_voice
--------------------------------------

bool al_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream,
   ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L251)

Attaches an audio stream to a voice.  The same rules as *note
al_attach_sample_instance_to_voice: #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.

See also: *note al_detach_voice: #al_detach_voice.


File: refman.info,  Node: al_attach_mixer_to_voice,  Next: al_attach_sample_instance_to_voice,  Prev: al_attach_audio_stream_to_voice,  Up: Voices

29.9.6 al_attach_mixer_to_voice
-------------------------------

bool al_attach_mixer_to_voice(ALLEGRO_MIXER *mixer, ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L319)

Attaches a mixer to a voice.  It must have the same frequency and
channel configuration, but the depth may be different.

Returns true on success, false on failure.

See also: *note al_detach_voice: #al_detach_voice.


File: refman.info,  Node: al_attach_sample_instance_to_voice,  Next: al_get_voice_frequency,  Prev: al_attach_mixer_to_voice,  Up: Voices

29.9.7 al_attach_sample_instance_to_voice
-----------------------------------------

bool al_attach_sample_instance_to_voice(ALLEGRO_SAMPLE_INSTANCE *spl,
   ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L126)

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.

Returns true on success, false on failure.

See also: *note al_detach_voice: #al_detach_voice.


File: refman.info,  Node: al_get_voice_frequency,  Next: al_get_voice_channels,  Prev: al_attach_sample_instance_to_voice,  Up: Voices

29.9.8 al_get_voice_frequency
-----------------------------

unsigned int al_get_voice_frequency(const ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L404)

Return the frequency of the voice (in Hz), e.g. 44100.


File: refman.info,  Node: al_get_voice_channels,  Next: al_get_voice_depth,  Prev: al_get_voice_frequency,  Up: Voices

29.9.9 al_get_voice_channels
----------------------------

ALLEGRO_CHANNEL_CONF al_get_voice_channels(const ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L432)

Return the channel configuration of the voice.

See also: *note ALLEGRO_CHANNEL_CONF: #allegro_channel_conf.


File: refman.info,  Node: al_get_voice_depth,  Next: al_get_voice_playing,  Prev: al_get_voice_channels,  Up: Voices

29.9.10 al_get_voice_depth
--------------------------

ALLEGRO_AUDIO_DEPTH al_get_voice_depth(const ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L442)

Return the audio depth of the voice.

See also: *note ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth.


File: refman.info,  Node: al_get_voice_playing,  Next: al_set_voice_playing,  Prev: al_get_voice_depth,  Up: Voices

29.9.11 al_get_voice_playing
----------------------------

bool al_get_voice_playing(const ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L452)

Return true if the voice is currently playing.

See also: *note al_set_voice_playing: #al_set_voice_playing.


File: refman.info,  Node: al_set_voice_playing,  Next: al_get_voice_position,  Prev: al_get_voice_playing,  Up: Voices

29.9.12 al_set_voice_playing
----------------------------

bool al_set_voice_playing(ALLEGRO_VOICE *voice, bool val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L489)

Change 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.

Returns true on success, false on failure.

See also: *note al_get_voice_playing: #al_get_voice_playing.


File: refman.info,  Node: al_get_voice_position,  Next: al_set_voice_position,  Prev: al_set_voice_playing,  Up: Voices

29.9.13 al_get_voice_position
-----------------------------

unsigned int al_get_voice_position(const ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L414)

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.

See also: *note al_set_voice_position: #al_set_voice_position.


File: refman.info,  Node: al_set_voice_position,  Prev: al_get_voice_position,  Up: Voices

29.9.14 al_set_voice_position
-----------------------------

bool al_set_voice_position(ALLEGRO_VOICE *voice, unsigned int val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_voice.c#L470)

Set the voice position.  This can only work if the voice has a
non-streaming object attached to it, e.g. a sample instance.

Returns true on success, false on failure.

See also: *note al_get_voice_position: #al_get_voice_position.


File: refman.info,  Node: Mixers,  Next: Miscelaneous,  Prev: Voices,  Up: Audio addon

29.10 Mixers
============

* Menu:

* ALLEGRO_MIXER::
* ALLEGRO_MIXER_QUALITY::
* al_create_mixer::
* al_destroy_mixer::
* al_get_default_mixer::
* al_set_default_mixer::
* al_restore_default_mixer::
* al_get_default_voice::
* al_set_default_voice::
* al_attach_mixer_to_mixer::
* al_attach_sample_instance_to_mixer::
* al_attach_audio_stream_to_mixer::
* al_get_mixer_frequency::
* al_set_mixer_frequency::
* al_get_mixer_channels::
* al_get_mixer_depth::
* al_get_mixer_gain::
* al_set_mixer_gain::
* al_get_mixer_quality::
* al_set_mixer_quality::
* al_get_mixer_playing::
* al_set_mixer_playing::
* al_get_mixer_attached::
* al_detach_mixer::
* al_set_mixer_postprocess_callback::


File: refman.info,  Node: ALLEGRO_MIXER,  Next: ALLEGRO_MIXER_QUALITY,  Up: Mixers

29.10.1 ALLEGRO_MIXER
---------------------

typedef struct ALLEGRO_MIXER ALLEGRO_MIXER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L171)

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
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).


File: refman.info,  Node: ALLEGRO_MIXER_QUALITY,  Next: al_create_mixer,  Prev: ALLEGRO_MIXER,  Up: Mixers

29.10.2 ALLEGRO_MIXER_QUALITY
-----------------------------

enum ALLEGRO_MIXER_QUALITY

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L132)

   • ALLEGRO_MIXER_QUALITY_POINT - point sampling
   • ALLEGRO_MIXER_QUALITY_LINEAR - linear interpolation
   • ALLEGRO_MIXER_QUALITY_CUBIC - cubic interpolation (since: 5.0.8,
     5.1.4)


File: refman.info,  Node: al_create_mixer,  Next: al_destroy_mixer,  Prev: ALLEGRO_MIXER_QUALITY,  Up: Mixers

29.10.3 al_create_mixer
-----------------------

ALLEGRO_MIXER *al_create_mixer(unsigned int freq,
   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L630)

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 ALLEGRO_AUDIO_DEPTH_FLOAT32 and
ALLEGRO_AUDIO_DEPTH_INT16 (not yet complete).

To actually produce any output, the mixer will have to be attached to a
voice using *note al_attach_mixer_to_voice: #al_attach_mixer_to_voice.

Reasonable default arguments are:

al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2)

Returns true on success, false on error.

See also: *note al_destroy_mixer: #al_destroy_mixer, *note
ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth, *note ALLEGRO_CHANNEL_CONF:
#allegro_channel_conf.


File: refman.info,  Node: al_destroy_mixer,  Next: al_get_default_mixer,  Prev: al_create_mixer,  Up: Mixers

29.10.4 al_destroy_mixer
------------------------

void al_destroy_mixer(ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L699)

Destroys the mixer.

See also: *note al_create_mixer: #al_create_mixer.


File: refman.info,  Node: al_get_default_mixer,  Next: al_set_default_mixer,  Prev: al_destroy_mixer,  Up: Mixers

29.10.5 al_get_default_mixer
----------------------------

ALLEGRO_MIXER *al_get_default_mixer(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L260)

Return the default mixer, or NULL 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 *note al_play_sample: #al_play_sample.

See also: *note al_reserve_samples: #al_reserve_samples, *note
al_play_sample: #al_play_sample, *note al_set_default_mixer:
#al_set_default_mixer, *note al_restore_default_mixer:
#al_restore_default_mixer.


File: refman.info,  Node: al_set_default_mixer,  Next: al_restore_default_mixer,  Prev: al_get_default_mixer,  Up: Mixers

29.10.6 al_set_default_mixer
----------------------------

bool al_set_default_mixer(ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L268)

Sets the default mixer.  All samples started with *note al_play_sample:
#al_play_sample. will be stopped and all sample instances returned by
*note al_lock_sample_id: #al_lock_sample_id. will be invalidated.  If
you are using your own mixer, this should be called before *note
al_reserve_samples: #al_reserve_samples.

Returns true on success, false on error.

See also: *note al_reserve_samples: #al_reserve_samples, *note
al_play_sample: #al_play_sample, *note al_get_default_mixer:
#al_get_default_mixer, *note al_restore_default_mixer:
#al_restore_default_mixer.


File: refman.info,  Node: al_restore_default_mixer,  Next: al_get_default_voice,  Prev: al_set_default_mixer,  Up: Mixers

29.10.7 al_restore_default_mixer
--------------------------------

bool al_restore_default_mixer(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L309)

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 *note al_set_default_voice:
#al_set_default_voice. or created before, it will also be created.  All
samples started with *note al_play_sample: #al_play_sample. will be
stopped and all sample instances returned by *note al_lock_sample_id:
#al_lock_sample_id. will be invalidated.

Returns true on success, false on error.

See also: *note al_get_default_mixer: #al_get_default_mixer, *note
al_set_default_mixer: #al_set_default_mixer, *note al_reserve_samples:
#al_reserve_samples.


File: refman.info,  Node: al_get_default_voice,  Next: al_set_default_voice,  Prev: al_restore_default_mixer,  Up: Mixers

29.10.8 al_get_default_voice
----------------------------

ALLEGRO_VOICE *al_get_default_voice(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L323)

Returns the default voice or NULL if there is none.

Since: 5.1.13

See also: *note al_get_default_mixer: #al_get_default_mixer.


File: refman.info,  Node: al_set_default_voice,  Next: al_attach_mixer_to_mixer,  Prev: al_get_default_voice,  Up: Mixers

29.10.9 al_set_default_voice
----------------------------

void al_set_default_voice(ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_sample.c#L331)

You can call this before calling al_restore_default_mixer to provide the
voice which should be used.  Any previous voice will be destroyed.  You
can also pass NULL to destroy the current default voice.

Since: 5.1.13

See also: *note al_get_default_mixer: #al_get_default_mixer.


File: refman.info,  Node: al_attach_mixer_to_mixer,  Next: al_attach_sample_instance_to_mixer,  Prev: al_set_default_voice,  Up: Mixers

29.10.10 al_attach_mixer_to_mixer
---------------------------------

bool al_attach_mixer_to_mixer(ALLEGRO_MIXER *stream, ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L821)

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.

Returns true on success, false on error.

It is invalid to attach a mixer to itself.

See also: *note al_detach_mixer: #al_detach_mixer.


File: refman.info,  Node: al_attach_sample_instance_to_mixer,  Next: al_attach_audio_stream_to_mixer,  Prev: al_attach_mixer_to_mixer,  Up: Mixers

29.10.11 al_attach_sample_instance_to_mixer
-------------------------------------------

bool al_attach_sample_instance_to_mixer(ALLEGRO_SAMPLE_INSTANCE *spl,
   ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L711)

Attach a sample instance to a mixer.  The instance must not already be
attached to anything.

Returns true on success, false on failure.

See also: *note al_detach_sample_instance: #al_detach_sample_instance.


File: refman.info,  Node: al_attach_audio_stream_to_mixer,  Next: al_get_mixer_frequency,  Prev: al_attach_sample_instance_to_mixer,  Up: Mixers

29.10.12 al_attach_audio_stream_to_mixer
----------------------------------------

bool al_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L810)

Attach an audio stream to a mixer.  The stream must not already be
attached to anything.

Returns true on success, false on failure.

See also: *note al_detach_audio_stream: #al_detach_audio_stream.


File: refman.info,  Node: al_get_mixer_frequency,  Next: al_set_mixer_frequency,  Prev: al_attach_audio_stream_to_mixer,  Up: Mixers

29.10.13 al_get_mixer_frequency
-------------------------------

unsigned int al_get_mixer_frequency(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L870)

Return the mixer frequency (in Hz).

See also: *note al_set_mixer_frequency: #al_set_mixer_frequency.


File: refman.info,  Node: al_set_mixer_frequency,  Next: al_get_mixer_channels,  Prev: al_get_mixer_frequency,  Up: Mixers

29.10.14 al_set_mixer_frequency
-------------------------------

bool al_set_mixer_frequency(ALLEGRO_MIXER *mixer, unsigned int val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L940)

Set the mixer frequency (in Hz).  This will only work if the mixer is
not attached to anything.

Returns true on success, false on failure.

See also: *note al_get_mixer_frequency: #al_get_mixer_frequency.


File: refman.info,  Node: al_get_mixer_channels,  Next: al_get_mixer_depth,  Prev: al_set_mixer_frequency,  Up: Mixers

29.10.15 al_get_mixer_channels
------------------------------

ALLEGRO_CHANNEL_CONF al_get_mixer_channels(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L880)

Return the mixer channel configuration.

See also: *note ALLEGRO_CHANNEL_CONF: #allegro_channel_conf.


File: refman.info,  Node: al_get_mixer_depth,  Next: al_get_mixer_gain,  Prev: al_get_mixer_channels,  Up: Mixers

29.10.16 al_get_mixer_depth
---------------------------

ALLEGRO_AUDIO_DEPTH al_get_mixer_depth(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L890)

Return the mixer audio depth.

See also: *note ALLEGRO_AUDIO_DEPTH: #allegro_audio_depth.


File: refman.info,  Node: al_get_mixer_gain,  Next: al_set_mixer_gain,  Prev: al_get_mixer_depth,  Up: Mixers

29.10.17 al_get_mixer_gain
--------------------------

float al_get_mixer_gain(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L910)

Return the mixer gain (amplification factor).  The default is 1.0.

Since: 5.0.6, 5.1.0

See also: *note al_set_mixer_gain: #al_set_mixer_gain.


File: refman.info,  Node: al_set_mixer_gain,  Next: al_get_mixer_quality,  Prev: al_get_mixer_gain,  Up: Mixers

29.10.18 al_set_mixer_gain
--------------------------

bool al_set_mixer_gain(ALLEGRO_MIXER *mixer, float new_gain)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L988)

Set the mixer gain (amplification factor).

Returns true on success, false on failure.

Since: 5.0.6, 5.1.0

See also: *note al_get_mixer_gain: #al_get_mixer_gain.


File: refman.info,  Node: al_get_mixer_quality,  Next: al_set_mixer_quality,  Prev: al_set_mixer_gain,  Up: Mixers

29.10.19 al_get_mixer_quality
-----------------------------

ALLEGRO_MIXER_QUALITY al_get_mixer_quality(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L900)

Return the mixer quality.

See also: *note ALLEGRO_MIXER_QUALITY: #allegro_mixer_quality, *note
al_set_mixer_quality: #al_set_mixer_quality.


File: refman.info,  Node: al_set_mixer_quality,  Next: al_get_mixer_playing,  Prev: al_get_mixer_quality,  Up: Mixers

29.10.20 al_set_mixer_quality
-----------------------------

bool al_set_mixer_quality(ALLEGRO_MIXER *mixer, ALLEGRO_MIXER_QUALITY new_quality)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L960)

Set the mixer quality.  This can only succeed if the mixer does not have
anything attached to it.

Returns true on success, false on failure.

See also: *note ALLEGRO_MIXER_QUALITY: #allegro_mixer_quality, *note
al_get_mixer_quality: #al_get_mixer_quality.


File: refman.info,  Node: al_get_mixer_playing,  Next: al_set_mixer_playing,  Prev: al_set_mixer_quality,  Up: Mixers

29.10.21 al_get_mixer_playing
-----------------------------

bool al_get_mixer_playing(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L920)

Return true if the mixer is playing.

See also: *note al_set_mixer_playing: #al_set_mixer_playing.


File: refman.info,  Node: al_set_mixer_playing,  Next: al_get_mixer_attached,  Prev: al_get_mixer_playing,  Up: Mixers

29.10.22 al_set_mixer_playing
-----------------------------

bool al_set_mixer_playing(ALLEGRO_MIXER *mixer, bool val)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L1012)

Change whether the mixer is playing.

Returns true on success, false on failure.

See also: *note al_get_mixer_playing: #al_get_mixer_playing.


File: refman.info,  Node: al_get_mixer_attached,  Next: al_detach_mixer,  Prev: al_set_mixer_playing,  Up: Mixers

29.10.23 al_get_mixer_attached
------------------------------

bool al_get_mixer_attached(const ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L930)

Return true if the mixer is attached to something.

See also: *note al_attach_sample_instance_to_mixer:
#al_attach_sample_instance_to_mixer, *note
al_attach_audio_stream_to_mixer: #al_attach_audio_stream_to_mixer, *note
al_attach_mixer_to_mixer: #al_attach_mixer_to_mixer, *note
al_detach_mixer: #al_detach_mixer.


File: refman.info,  Node: al_detach_mixer,  Next: al_set_mixer_postprocess_callback,  Prev: al_get_mixer_attached,  Up: Mixers

29.10.24 al_detach_mixer
------------------------

bool al_detach_mixer(ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L1023)

Detach the mixer from whatever it is attached to, if anything.

See also: *note al_attach_mixer_to_mixer: #al_attach_mixer_to_mixer.


File: refman.info,  Node: al_set_mixer_postprocess_callback,  Prev: al_detach_mixer,  Up: Mixers

29.10.25 al_set_mixer_postprocess_callback
------------------------------------------

bool al_set_mixer_postprocess_callback(ALLEGRO_MIXER *mixer,
   void (*pp_callback)(void *buf, unsigned int samples, void *data),
   void *pp_callback_userdata)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/kcm_mixer.c#L851)

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.

     _Note:_ The callback is called from a dedicated audio thread.


File: refman.info,  Node: Miscelaneous,  Prev: Mixers,  Up: Audio addon

29.11 Miscelaneous
==================

* Menu:

* ALLEGRO_AUDIO_DEPTH::
* ALLEGRO_AUDIO_PAN_NONE::
* ALLEGRO_CHANNEL_CONF::
* ALLEGRO_PLAYMODE::
* ALLEGRO_AUDIO_EVENT_TYPE::
* al_get_allegro_audio_version::
* al_get_audio_depth_size::
* al_get_channel_count::
* al_fill_silence::


File: refman.info,  Node: ALLEGRO_AUDIO_DEPTH,  Next: ALLEGRO_AUDIO_PAN_NONE,  Up: Miscelaneous

29.11.1 ALLEGRO_AUDIO_DEPTH
---------------------------

enum ALLEGRO_AUDIO_DEPTH

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L71)

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.

   • ALLEGRO_AUDIO_DEPTH_INT8
   • ALLEGRO_AUDIO_DEPTH_INT16
   • ALLEGRO_AUDIO_DEPTH_INT24
   • ALLEGRO_AUDIO_DEPTH_FLOAT32
   • ALLEGRO_AUDIO_DEPTH_UNSIGNED

For convenience:

   • ALLEGRO_AUDIO_DEPTH_UINT8
   • ALLEGRO_AUDIO_DEPTH_UINT16
   • ALLEGRO_AUDIO_DEPTH_UINT24


File: refman.info,  Node: ALLEGRO_AUDIO_PAN_NONE,  Next: ALLEGRO_CHANNEL_CONF,  Prev: ALLEGRO_AUDIO_DEPTH,  Up: Miscelaneous

29.11.2 ALLEGRO_AUDIO_PAN_NONE
------------------------------

#define ALLEGRO_AUDIO_PAN_NONE      (-1000.0f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L142)

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.

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.)


File: refman.info,  Node: ALLEGRO_CHANNEL_CONF,  Next: ALLEGRO_PLAYMODE,  Prev: ALLEGRO_AUDIO_PAN_NONE,  Up: Miscelaneous

29.11.3 ALLEGRO_CHANNEL_CONF
----------------------------

enum ALLEGRO_CHANNEL_CONF

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L96)

Speaker configuration (mono, stereo, 2.1, etc).

   • ALLEGRO_CHANNEL_CONF_1
   • ALLEGRO_CHANNEL_CONF_2
   • ALLEGRO_CHANNEL_CONF_3
   • ALLEGRO_CHANNEL_CONF_4
   • ALLEGRO_CHANNEL_CONF_5_1
   • ALLEGRO_CHANNEL_CONF_6_1
   • ALLEGRO_CHANNEL_CONF_7_1


File: refman.info,  Node: ALLEGRO_PLAYMODE,  Next: ALLEGRO_AUDIO_EVENT_TYPE,  Prev: ALLEGRO_CHANNEL_CONF,  Up: Miscelaneous

29.11.4 ALLEGRO_PLAYMODE
------------------------

enum ALLEGRO_PLAYMODE

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L118)

Sample and stream playback mode.

   • ALLEGRO_PLAYMODE_ONCE - the sample/stream is played from start to
     finish an then it stops.
   • 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.
   • ALLEGRO_PLAYMODE_LOOP_ONCE - just like ALLEGRO_PLAYMODE_ONCE, but
     respects the loop end point.
   • 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.


File: refman.info,  Node: ALLEGRO_AUDIO_EVENT_TYPE,  Next: al_get_allegro_audio_version,  Prev: ALLEGRO_PLAYMODE,  Up: Miscelaneous

29.11.5 ALLEGRO_AUDIO_EVENT_TYPE
--------------------------------

enum ALLEGRO_AUDIO_EVENT_TYPE

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/allegro5/allegro_audio.h#L43)

Events sent by *note al_get_audio_stream_event_source:
#al_get_audio_stream_event_source. or *note
al_get_audio_recorder_event_source: #al_get_audio_recorder_event_source.

* Menu:

* ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT::
* ALLEGRO_EVENT_AUDIO_STREAM_FINISHED::
* ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT::


File: refman.info,  Node: ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT,  Next: ALLEGRO_EVENT_AUDIO_STREAM_FINISHED,  Up: ALLEGRO_AUDIO_EVENT_TYPE

29.11.5.1 ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT
.............................................

Sent when a stream fragment is ready to be filled in.  See *note
al_get_audio_stream_fragment: #al_get_audio_stream_fragment.


File: refman.info,  Node: ALLEGRO_EVENT_AUDIO_STREAM_FINISHED,  Next: ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT,  Prev: ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT,  Up: ALLEGRO_AUDIO_EVENT_TYPE

29.11.5.2 ALLEGRO_EVENT_AUDIO_STREAM_FINISHED
.............................................

Sent when a stream is finished.


File: refman.info,  Node: ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT,  Prev: ALLEGRO_EVENT_AUDIO_STREAM_FINISHED,  Up: ALLEGRO_AUDIO_EVENT_TYPE

29.11.5.3 ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT
...............................................

Sent after a user-specified number of samples have been recorded.
Convert this to *note ALLEGRO_AUDIO_RECORDER_EVENT:
#allegro_audio_recorder_event. via *note al_get_audio_recorder_event:
#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.

Since: 5.1.1

     _*note Unstable API: #unstable-api.:_ The API may need a slight
     redesign.


File: refman.info,  Node: al_get_allegro_audio_version,  Next: al_get_audio_depth_size,  Prev: ALLEGRO_AUDIO_EVENT_TYPE,  Up: Miscelaneous

29.11.6 al_get_allegro_audio_version
------------------------------------

uint32_t al_get_allegro_audio_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L463)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: al_get_audio_depth_size,  Next: al_get_channel_count,  Prev: al_get_allegro_audio_version,  Up: Miscelaneous

29.11.7 al_get_audio_depth_size
-------------------------------

size_t al_get_audio_depth_size(ALLEGRO_AUDIO_DEPTH depth)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L65)

Return the size of a sample, in bytes, for the given format.  The format
is one of the values listed under *note ALLEGRO_AUDIO_DEPTH:
#allegro_audio_depth.


File: refman.info,  Node: al_get_channel_count,  Next: al_fill_silence,  Prev: al_get_audio_depth_size,  Up: Miscelaneous

29.11.8 al_get_channel_count
----------------------------

size_t al_get_channel_count(ALLEGRO_CHANNEL_CONF conf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L57)

Return the number of channels for the given channel configuration, which
is one of the values listed under *note ALLEGRO_CHANNEL_CONF:
#allegro_channel_conf.


File: refman.info,  Node: al_fill_silence,  Prev: al_get_channel_count,  Up: Miscelaneous

29.11.9 al_fill_silence
-----------------------

void al_fill_silence(void *buf, unsigned int samples,
   ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/audio/audio.c#L127)

Fill 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.

Since: 5.1.8


File: refman.info,  Node: Audio codecs addon,  Next: Color addon,  Prev: Audio addon,  Up: Top

30 Audio codecs addon
*********************

These functions are declared in the following header file.  Link with
allegro_acodec.

 #include <allegro5/allegro_acodec.h>

* Menu:

* al_init_acodec_addon::
* al_is_acodec_addon_initialized::
* al_get_allegro_acodec_version::


File: refman.info,  Node: al_init_acodec_addon,  Next: al_is_acodec_addon_initialized,  Up: Audio codecs addon

30.1 al_init_acodec_addon
=========================

bool al_init_acodec_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/acodec/acodec.c#L21)

This function registers all the known audio file type handlers for *note
al_load_sample: #al_load_sample, *note al_save_sample: #al_save_sample,
*note al_load_audio_stream: #al_load_audio_stream, etc.

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

_Limitations:_

   • Saving is only supported for wav files.

   • 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.

   • 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 *note
     al_load_sample: #al_load_sample./*note al_load_sample_f:
     #al_load_sample_f. and must be streamed with *note
     al_load_audio_stream: #al_load_audio_stream. or *note
     al_load_audio_stream_f: #al_load_audio_stream_f.

   • .voc file streaming is unimplemented.

Return true on success.


File: refman.info,  Node: al_is_acodec_addon_initialized,  Next: al_get_allegro_acodec_version,  Prev: al_init_acodec_addon,  Up: Audio codecs addon

30.2 al_is_acodec_addon_initialized
===================================

bool al_is_acodec_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/acodec/acodec.c#L83)

Returns true if the acodec addon is initialized, otherwise returns
false.

Since: 5.2.6


File: refman.info,  Node: al_get_allegro_acodec_version,  Prev: al_is_acodec_addon_initialized,  Up: Audio codecs addon

30.3 al_get_allegro_acodec_version
==================================

uint32_t al_get_allegro_acodec_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/acodec/acodec.c#L13)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: Color addon,  Next: Font addons,  Prev: Audio codecs addon,  Up: Top

31 Color addon
**************

These functions are declared in the following header file.  Link with
allegro_color.

 #include <allegro5/allegro_color.h>

When converting between certain color spaces, RGB colors are implicitly
assumed to mean sRGB.

sRGB is a standard which maps RGB colors to absolute colors.  sRGB is
very close to RGB values on a monitor which has a gamma value of 2.2.
For example when the red component of a color is 0.5, the monitor will
use a brightness of pow(0.5, 2.2) or about 22% - and not 50%.  The
reason is that human eyes can distinguish better between dark colors
than between bright colors, and so if a pixel of the monitor is lit up
to 22% of its maximum power it already will appear at half brightness to
a human eye.

sRGB improves upon simple gamma correction by taking differences between
the three color channels into account as well.  In general, most
monitors nowadays try to be close to the sRGB specification.  And so if
in an Allegro game you display something with color

al_map_rgb_f(0.5, 0.5, 0,5)

then it will appear at about half brightness (even though the actual
brightness output of the monitor will be less than half).

* Menu:

* al_color_cmyk::
* al_color_cmyk_to_rgb::
* al_color_hsl::
* al_color_hsl_to_rgb::
* al_color_hsv::
* al_color_hsv_to_rgb::
* al_color_html::
* al_color_html_to_rgb::
* al_color_rgb_to_html::
* al_color_name::
* al_color_name_to_rgb::
* al_color_rgb_to_cmyk::
* al_color_rgb_to_hsl::
* al_color_rgb_to_hsv::
* al_color_rgb_to_name::
* al_color_rgb_to_xyz::
* al_color_xyz::
* al_color_xyz_to_rgb::
* al_color_rgb_to_xyy::
* al_color_xyy::
* al_color_xyy_to_rgb::
* al_color_rgb_to_lab::
* al_color_lab::
* al_color_lab_to_rgb::
* al_color_rgb_to_lch::
* al_color_lch::
* al_color_lch_to_rgb::
* al_color_distance_ciede2000::
* al_color_rgb_to_yuv::
* al_color_yuv::
* al_color_yuv_to_rgb::
* al_get_allegro_color_version::
* al_is_color_valid::
* al_color_rgb_to_oklab::
* al_color_oklab::
* al_color_oklab_to_rgb::
* al_color_rgb_to_linear::
* al_color_linear::
* al_color_linear_to_rgb::


File: refman.info,  Node: al_color_cmyk,  Next: al_color_cmyk_to_rgb,  Up: Color addon

31.1 al_color_cmyk
==================

ALLEGRO_COLOR al_color_cmyk(float c, float m, float y, float k)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L480)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from CMYK
values (cyan, magenta, yellow, black).

See also: *note al_color_cmyk_to_rgb: #al_color_cmyk_to_rgb, *note
al_color_rgb_to_cmyk: #al_color_rgb_to_cmyk.


File: refman.info,  Node: al_color_cmyk_to_rgb,  Next: al_color_hsl,  Prev: al_color_cmyk,  Up: Color addon

31.2 al_color_cmyk_to_rgb
=========================

void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow,
    float key, float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L446)

Convert CMYK values to RGB values.

See also: *note al_color_cmyk: #al_color_cmyk, *note
al_color_rgb_to_cmyk: #al_color_rgb_to_cmyk.


File: refman.info,  Node: al_color_hsl,  Next: al_color_hsl_to_rgb,  Prev: al_color_cmyk_to_rgb,  Up: Color addon

31.3 al_color_hsl
=================

ALLEGRO_COLOR al_color_hsl(float h, float s, float l)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L436)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from HSL (hue,
saturation, lightness) values.

Parameters:

   • hue - Color hue angle in the range 0..360
   • saturation - Color saturation in the range 0..1
   • lightness - Color lightness in the range 0..1

See also: *note al_color_hsl_to_rgb: #al_color_hsl_to_rgb, *note
al_color_hsv: #al_color_hsv.


File: refman.info,  Node: al_color_hsl_to_rgb,  Next: al_color_hsv,  Prev: al_color_hsl,  Up: Color addon

31.4 al_color_hsl_to_rgb
========================

void al_color_hsl_to_rgb(float hue, float saturation, float lightness,
   float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L367)

Convert values in HSL color model to RGB color model.

Parameters:

   • hue - Color hue angle in the range 0..360
   • saturation - Color saturation in the range 0..1
   • lightness - Color lightness in the range 0..1
   • red, green, blue - returned RGB values in the range 0..1

See also: *note al_color_rgb_to_hsl: #al_color_rgb_to_hsl, *note
al_color_hsl: #al_color_hsl, *note al_color_hsv_to_rgb:
#al_color_hsv_to_rgb.


File: refman.info,  Node: al_color_hsv,  Next: al_color_hsv_to_rgb,  Prev: al_color_hsl_to_rgb,  Up: Color addon

31.5 al_color_hsv
=================

ALLEGRO_COLOR al_color_hsv(float h, float s, float v)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L339)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from HSV (hue,
saturation, value) values.

Parameters:

   • hue - Color hue angle in the range 0..360
   • saturation - Color saturation in the range 0..1
   • value - Color value in the range 0..1

See also: *note al_color_hsv_to_rgb: #al_color_hsv_to_rgb, *note
al_color_hsl: #al_color_hsl.


File: refman.info,  Node: al_color_hsv_to_rgb,  Next: al_color_html,  Prev: al_color_hsv,  Up: Color addon

31.6 al_color_hsv_to_rgb
========================

void al_color_hsv_to_rgb(float hue, float saturation, float value,
   float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L266)

Convert values in HSV color model to RGB color model.

Parameters:

   • hue - Color hue angle in the range 0..360
   • saturation - Color saturation in the range 0..1
   • value - Color value in the range 0..1
   • red, green, blue - returned RGB values in the range 0..1

See also: *note al_color_rgb_to_hsv: #al_color_rgb_to_hsv, *note
al_color_hsv: #al_color_hsv, *note al_color_hsl_to_rgb:
#al_color_hsl_to_rgb.


File: refman.info,  Node: al_color_html,  Next: al_color_html_to_rgb,  Prev: al_color_hsv_to_rgb,  Up: Color addon

31.7 al_color_html
==================

ALLEGRO_COLOR al_color_html(char const *string)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L568)

Interprets an HTML-style hex number (e.g. #00faff) as a color.  The
accepted format is the same as *note al_color_html_to_rgb:
#al_color_html_to_rgb.

Returns the interpreted color, or ‘al_map_rgba(0, 0, 0, 0)’ if the
string could not be parsed.

     _Note_: the behaviour on invalid strings is different from Allegro
     5.0.x.
See also: *note al_color_html_to_rgb: #al_color_html_to_rgb, *note
al_color_rgb_to_html: #al_color_rgb_to_html.


File: refman.info,  Node: al_color_html_to_rgb,  Next: al_color_rgb_to_html,  Prev: al_color_html,  Up: Color addon

31.8 al_color_html_to_rgb
=========================

bool al_color_html_to_rgb(char const *string,
   float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L538)

Interprets an HTML-style hex number (e.g. #00faff) as a color.  The only
accepted formats are “#RRGGBB” and “RRGGBB” where R, G, B are
hexadecimal digits [0-9A-Fa-f].

Returns true on success, false on failure.  On failure all components
are set to zero.

     _Note_: the behaviour on invalid strings is different from Allegro
     5.0.x.
See also: *note al_color_html: #al_color_html, *note
al_color_rgb_to_html: #al_color_rgb_to_html.


File: refman.info,  Node: al_color_rgb_to_html,  Next: al_color_name,  Prev: al_color_html_to_rgb,  Up: Color addon

31.9 al_color_rgb_to_html
=========================

void al_color_rgb_to_html(float red, float green, float blue,
    char *string)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L528)

Create an HTML-style string representation of an *note ALLEGRO_COLOR:
#allegro_color, e.g. #00faff.

Parameters:

   • red, green, blue - The color components in the range 0..1.
   • string - A pointer to a buffer of at least 8 bytes, into which the
     result will be written (including the NUL terminator).

Example:

char html[8];
al_color_rgb_to_html(1, 0, 0, html);

Now html will contain “#ff0000”.

See also: *note al_color_html: #al_color_html, *note
al_color_html_to_rgb: #al_color_html_to_rgb.


File: refman.info,  Node: al_color_name,  Next: al_color_name_to_rgb,  Prev: al_color_rgb_to_html,  Up: Color addon

31.10 al_color_name
===================

ALLEGRO_COLOR al_color_name(char const *name)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L254)

Return an *note ALLEGRO_COLOR: #allegro_color. with the given name.  If
the color is not found then black is returned.

See *note al_color_name_to_rgb: #al_color_name_to_rgb. for the list of
names.


File: refman.info,  Node: al_color_name_to_rgb,  Next: al_color_rgb_to_cmyk,  Prev: al_color_name,  Up: Color addon

31.11 al_color_name_to_rgb
==========================

bool al_color_name_to_rgb(char const *name, float *r, float *g, float *b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L210)

Parameters:

   • name - The (lowercase) name of the color.
   • r, g, b - If one of the recognized color names below is passed, the
     corresponding RGB values in the range 0..1 are written.

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: <https://www.w3.org/TR/css-color-4/>

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

Returns: true if a name from the list above was passed, else false.

See also: *note al_color_name: #al_color_name.


File: refman.info,  Node: al_color_rgb_to_cmyk,  Next: al_color_rgb_to_hsl,  Prev: al_color_name_to_rgb,  Up: Color addon

31.12 al_color_rgb_to_cmyk
==========================

void al_color_rgb_to_cmyk(float red, float green, float blue,
   float *cyan, float *magenta, float *yellow, float *key)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L458)

Each RGB color can be represented in CMYK with a K component of 0 with
the following formula:

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.

See also: *note al_color_cmyk: #al_color_cmyk, *note
al_color_cmyk_to_rgb: #al_color_cmyk_to_rgb.


File: refman.info,  Node: al_color_rgb_to_hsl,  Next: al_color_rgb_to_hsv,  Prev: al_color_rgb_to_cmyk,  Up: Color addon

31.13 al_color_rgb_to_hsl
=========================

void al_color_rgb_to_hsl(float red, float green, float blue,
   float *hue, float *saturation, float *lightness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L389)

Given an RGB triplet with components in the range 0..1, return the hue
in degrees from 0..360 and saturation and lightness in the range 0..1.

See also: *note al_color_hsl_to_rgb: #al_color_hsl_to_rgb, *note
al_color_hsl: #al_color_hsl.


File: refman.info,  Node: al_color_rgb_to_hsv,  Next: al_color_rgb_to_name,  Prev: al_color_rgb_to_hsl,  Up: Color addon

31.14 al_color_rgb_to_hsv
=========================

void al_color_rgb_to_hsv(float red, float green, float blue,
   float *hue, float *saturation, float *value)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L294)

Given an RGB triplet with components in the range 0..1, return the hue
in degrees from 0..360 and saturation and value in the range 0..1.

See also: *note al_color_hsv_to_rgb: #al_color_hsv_to_rgb, *note
al_color_hsv: #al_color_hsv.


File: refman.info,  Node: al_color_rgb_to_name,  Next: al_color_rgb_to_xyz,  Prev: al_color_rgb_to_hsv,  Up: Color addon

31.15 al_color_rgb_to_name
==========================

char const *al_color_rgb_to_name(float r, float g, float b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L229)

Given an RGB triplet with components in the range 0..1, find a color
name describing it approximately.

See also: *note al_color_name_to_rgb: #al_color_name_to_rgb, *note
al_color_name: #al_color_name.


File: refman.info,  Node: al_color_rgb_to_xyz,  Next: al_color_xyz,  Prev: al_color_rgb_to_name,  Up: Color addon

31.16 al_color_rgb_to_xyz
=========================

void al_color_rgb_to_xyz(float red, float green, float blue,
   float *x, float *y, float *z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L653)

Convert RGB values to XYZ color space.

Since: 5.2.3

See also: *note al_color_xyz: #al_color_xyz, *note al_color_xyz_to_rgb:
#al_color_xyz_to_rgb.


File: refman.info,  Node: al_color_xyz,  Next: al_color_xyz_to_rgb,  Prev: al_color_rgb_to_xyz,  Up: Color addon

31.17 al_color_xyz
==================

ALLEGRO_COLOR al_color_xyz(float x, float y, float z)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L667)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from XYZ
values.  The CIE 1931 XYZ color space consists of three components in
the range 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.

     _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 0..1 range.  You can check for that case with *note
     al_is_color_valid: #al_is_color_valid.
Since: 5.2.3

See also: *note al_color_xyz_to_rgb: #al_color_xyz_to_rgb, *note
al_color_rgb_to_xyz: #al_color_rgb_to_xyz.


File: refman.info,  Node: al_color_xyz_to_rgb,  Next: al_color_rgb_to_xyy,  Prev: al_color_xyz,  Up: Color addon

31.18 al_color_xyz_to_rgb
=========================

void al_color_xyz_to_rgb(float x, float y, float z,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L639)

Convert XYZ color values to RGB color space.

Since: 5.2.3

See also: *note al_color_xyz: #al_color_xyz, *note al_color_rgb_to_xyz:
#al_color_rgb_to_xyz.


File: refman.info,  Node: al_color_rgb_to_xyy,  Next: al_color_xyy,  Prev: al_color_xyz_to_rgb,  Up: Color addon

31.19 al_color_rgb_to_xyy
=========================

void al_color_rgb_to_xyy(float red, float green, float blue,
   float *x, float *y, float *y2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L771)

Convert RGB values to xyY color space.

Since: 5.2.3

See also: *note al_color_xyy: #al_color_xyy, *note al_color_xyy_to_rgb:
#al_color_xyy_to_rgb.


File: refman.info,  Node: al_color_xyy,  Next: al_color_xyy_to_rgb,  Prev: al_color_rgb_to_xyy,  Up: Color addon

31.20 al_color_xyy
==================

ALLEGRO_COLOR al_color_xyy(float x, float y, float y2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L783)

Return an *note ALLEGRO_COLOR: #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:

x = X / (X + Y + Z)
y = Y / (X + Y + Z)

Since: 5.2.3

See also: *note al_color_xyy_to_rgb: #al_color_xyy_to_rgb, *note
al_color_rgb_to_xyy: #al_color_rgb_to_xyy.


File: refman.info,  Node: al_color_xyy_to_rgb,  Next: al_color_rgb_to_lab,  Prev: al_color_xyy,  Up: Color addon

31.21 al_color_xyy_to_rgb
=========================

void al_color_xyy_to_rgb(float x, float y, float y2,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L760)

Convert xyY color values to RGB color space.

Since: 5.2.3

See also: *note al_color_xyy: #al_color_xyy, *note al_color_rgb_to_xyy:
#al_color_rgb_to_xyy.


File: refman.info,  Node: al_color_rgb_to_lab,  Next: al_color_lab,  Prev: al_color_xyy_to_rgb,  Up: Color addon

31.22 al_color_rgb_to_lab
=========================

void al_color_rgb_to_lab(float red, float green, float blue,
   float *l, float *a, float *b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L701)

Convert RGB values to L*a*b* color space.

Since: 5.2.3

See also: *note al_color_lab: #al_color_lab, *note al_color_lab_to_rgb:
#al_color_lab_to_rgb.


File: refman.info,  Node: al_color_lab,  Next: al_color_lab_to_rgb,  Prev: al_color_rgb_to_lab,  Up: Color addon

31.23 al_color_lab
==================

ALLEGRO_COLOR al_color_lab(float l, float a, float b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L717)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from CIE L*a*b*
values.  The L* component corresponds to luminance from 0..1.  The a*
and b* components are in the range -1..+1.

     _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 0..1 range.  You can check for that case with *note
     al_is_color_valid: #al_is_color_valid.
     _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.
Since: 5.2.3

See also: *note al_color_lab_to_rgb: #al_color_lab_to_rgb, *note
al_color_rgb_to_lab: #al_color_rgb_to_lab.


File: refman.info,  Node: al_color_lab_to_rgb,  Next: al_color_rgb_to_lch,  Prev: al_color_lab,  Up: Color addon

31.24 al_color_lab_to_rgb
=========================

void al_color_lab_to_rgb(float l, float a, float b,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L689)

Convert CIE L*a*b* color values to RGB color space.

Since: 5.2.3

See also: *note al_color_lab: #al_color_lab, *note al_color_rgb_to_lab:
#al_color_rgb_to_lab.


File: refman.info,  Node: al_color_rgb_to_lch,  Next: al_color_lch,  Prev: al_color_lab_to_rgb,  Up: Color addon

31.25 al_color_rgb_to_lch
=========================

void al_color_rgb_to_lch(float red, float green, float blue,
   float *l, float *c, float *h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L738)

Convert RGB values to CIE LCH color space.

Since: 5.2.3

See also: *note al_color_lch: #al_color_lch, *note al_color_lch_to_rgb:
#al_color_lch_to_rgb.


File: refman.info,  Node: al_color_lch,  Next: al_color_lch_to_rgb,  Prev: al_color_rgb_to_lch,  Up: Color addon

31.26 al_color_lch
==================

ALLEGRO_COLOR al_color_lch(float l, float c, float h)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L750)

Return an *note ALLEGRO_COLOR: #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:

C = sqrt(a * a + b * b)
H = atan2(b, a)

Since: 5.2.3

See also: *note al_color_lch_to_rgb: #al_color_lch_to_rgb, *note
al_color_rgb_to_lch: #al_color_rgb_to_lch.


File: refman.info,  Node: al_color_lch_to_rgb,  Next: al_color_distance_ciede2000,  Prev: al_color_lch,  Up: Color addon

31.27 al_color_lch_to_rgb
=========================

void al_color_lch_to_rgb(float l, float c, float h,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L727)

Convert CIE LCH color values to RGB color space.

Since: 5.2.3

See also: *note al_color_lch: #al_color_lch, *note al_color_rgb_to_lch:
#al_color_rgb_to_lch.


File: refman.info,  Node: al_color_distance_ciede2000,  Next: al_color_rgb_to_yuv,  Prev: al_color_lch_to_rgb,  Up: Color addon

31.28 al_color_distance_ciede2000
=================================

double al_color_distance_ciede2000(ALLEGRO_COLOR color1,
      ALLEGRO_COLOR color2) {

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L793)

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.

     Note: This function uses *note al_color_lab: #al_color_lab.
     internally which defines the L component to be in the range 0..1
     (and not 0..100 as is sometimes seen).
Since: 5.2.3


File: refman.info,  Node: al_color_rgb_to_yuv,  Next: al_color_yuv,  Prev: al_color_distance_ciede2000,  Up: Color addon

31.29 al_color_rgb_to_yuv
=========================

void al_color_rgb_to_yuv(float red, float green, float blue,
   float *y, float *u, float *v)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L504)

Convert RGB values to YUV color space.

See also: *note al_color_yuv: #al_color_yuv, *note al_color_yuv_to_rgb:
#al_color_yuv_to_rgb.


File: refman.info,  Node: al_color_yuv,  Next: al_color_yuv_to_rgb,  Prev: al_color_rgb_to_yuv,  Up: Color addon

31.30 al_color_yuv
==================

ALLEGRO_COLOR al_color_yuv(float y, float u, float v)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L518)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from YUV
values.

See also: *note al_color_yuv_to_rgb: #al_color_yuv_to_rgb, *note
al_color_rgb_to_yuv: #al_color_rgb_to_yuv.


File: refman.info,  Node: al_color_yuv_to_rgb,  Next: al_get_allegro_color_version,  Prev: al_color_yuv,  Up: Color addon

31.31 al_color_yuv_to_rgb
=========================

void al_color_yuv_to_rgb(float y, float u, float v,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L490)

Convert YUV color values to RGB color space.

See also: *note al_color_yuv: #al_color_yuv, *note al_color_rgb_to_yuv:
#al_color_rgb_to_yuv.


File: refman.info,  Node: al_get_allegro_color_version,  Next: al_is_color_valid,  Prev: al_color_yuv_to_rgb,  Up: Color addon

31.32 al_get_allegro_color_version
==================================

uint32_t al_get_allegro_color_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L581)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: al_is_color_valid,  Next: al_color_rgb_to_oklab,  Prev: al_get_allegro_color_version,  Up: Color addon

31.33 al_is_color_valid
=======================

Source Code

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 0..1 range.

Since: 5.2.3


File: refman.info,  Node: al_color_rgb_to_oklab,  Next: al_color_oklab,  Prev: al_is_color_valid,  Up: Color addon

31.34 al_color_rgb_to_oklab
===========================

void al_color_rgb_to_oklab(float red, float green, float blue,
   float *ol, float *oa, float *ob)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L874)

Convert RGB values to the Oklab color space.

Since: 5.2.8

See also: *note al_color_oklab: #al_color_oklab, *note
al_color_oklab_to_rgb: #al_color_oklab_to_rgb.


File: refman.info,  Node: al_color_oklab,  Next: al_color_oklab_to_rgb,  Prev: al_color_rgb_to_oklab,  Up: Color addon

31.35 al_color_oklab
====================

ALLEGRO_COLOR al_color_oklab(float l, float a, float b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L894)

Return an *note ALLEGRO_COLOR: #allegro_color. structure from Oklab
values.  The L component corresponds to luminance from 0..1.  The a and
b components are in the range -1..+1.

     _Note:_

     The Oklab color space can represent more colors than are visible in
     sRGB and therefore conversion may result in RGB values outside of
     the 0..1 range.  You can check for that case with *note
     al_is_color_valid: #al_is_color_valid.
Since: 5.2.8

See also: *note al_color_oklab_to_rgb: #al_color_oklab_to_rgb, *note
al_color_rgb_to_oklab: #al_color_rgb_to_oklab.


File: refman.info,  Node: al_color_oklab_to_rgb,  Next: al_color_rgb_to_linear,  Prev: al_color_oklab,  Up: Color addon

31.36 al_color_oklab_to_rgb
===========================

void al_color_oklab_to_rgb(float ol, float oa, float ob,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L853)

Convert Oklab color values to RGB.

Since: 5.2.8

See also: *note al_color_oklab: #al_color_oklab, *note
al_color_rgb_to_oklab: #al_color_rgb_to_oklab.


File: refman.info,  Node: al_color_rgb_to_linear,  Next: al_color_linear,  Prev: al_color_oklab_to_rgb,  Up: Color addon

31.37 al_color_rgb_to_linear
============================

void al_color_rgb_to_linear(float red, float green, float blue,
   float *r, float *g, float *b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L618)

Convert gamma corrected sRGB values (i.e. normal RGB) to linear sRGB
space.

Since: 5.2.8

See also: *note al_color_linear: #al_color_linear, *note
al_color_linear_to_rgb: #al_color_linear_to_rgb.


File: refman.info,  Node: al_color_linear,  Next: al_color_linear_to_rgb,  Prev: al_color_rgb_to_linear,  Up: Color addon

31.38 al_color_linear
=====================

ALLEGRO_COLOR al_color_linear(float r, float g, float b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L629)

Return an *note ALLEGRO_COLOR: #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 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:

ALLEGRO_COLOR gray = al_color_linear(0.216, 0.216, 0.216);
char html[8];
al_color_rgb_to_html(gray.r, gray.g, gray.b, html); // "#808080"

Since: 5.2.8

See also: *note al_color_linear_to_rgb: #al_color_linear_to_rgb, *note
al_color_rgb_to_linear: #al_color_rgb_to_linear.


File: refman.info,  Node: al_color_linear_to_rgb,  Prev: al_color_linear,  Up: Color addon

31.39 al_color_linear_to_rgb
============================

void al_color_linear_to_rgb(float r, float g, float b,
    float *red, float *green, float *blue)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/color/color.c#L607)

Convert linear sRGB color values to gamma corrected (i.e. normal) RGB
values.

Since: 5.2.8

See also: [al_color_linera], *note al_color_rgb_to_linear:
#al_color_rgb_to_linear.


File: refman.info,  Node: Font addons,  Next: Image I/O addon,  Prev: Color addon,  Up: Top

32 Font addons
**************

These functions are declared in the following header file.  Link with
allegro_font.

 #include <allegro5/allegro_font.h>

* Menu:

* General font routines::
* Per glyph text handling::
* Multiline text drawing::
* Bitmap fonts::
* TTF fonts::


File: refman.info,  Node: General font routines,  Next: Per glyph text handling,  Up: Font addons

32.1 General font routines
==========================

* Menu:

* ALLEGRO_FONT::
* ALLEGRO_GLYPH::
* al_init_font_addon::
* al_is_font_addon_initialized::
* al_shutdown_font_addon::
* al_load_font::
* al_destroy_font::
* al_register_font_loader::
* al_get_font_line_height::
* al_get_font_ascent::
* al_get_font_descent::
* al_get_text_width::
* al_get_ustr_width::
* al_draw_text::
* al_draw_ustr::
* al_draw_justified_text::
* al_draw_justified_ustr::
* al_draw_textf::
* al_draw_justified_textf::
* al_get_text_dimensions::
* al_get_ustr_dimensions::
* al_get_allegro_font_version::
* al_get_font_ranges::
* al_set_fallback_font::
* al_get_fallback_font::


File: refman.info,  Node: ALLEGRO_FONT,  Next: ALLEGRO_GLYPH,  Up: General font routines

32.1.1 ALLEGRO_FONT
-------------------

typedef struct ALLEGRO_FONT ALLEGRO_FONT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/allegro5/allegro_font.h#L48)

A handle identifying any kind of font.  Usually you will create it with
*note al_load_font: #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 *note
al_load_bitmap: #al_load_bitmap. and a font in Allegro’s bitmap font
format will be created from it with *note al_grab_font_from_bitmap:
#al_grab_font_from_bitmap.


File: refman.info,  Node: ALLEGRO_GLYPH,  Next: al_init_font_addon,  Prev: ALLEGRO_FONT,  Up: General font routines

32.1.2 ALLEGRO_GLYPH
--------------------

typedef struct ALLEGRO_GLYPH ALLEGRO_GLYPH;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/allegro5/allegro_font.h#L53)

A structure containing the properties of a character in a font.

typedef struct ALLEGRO_GLYPH {
   ALLEGRO_BITMAP *bitmap;   // the bitmap the character is on
   int x;                    // the x position of the glyph on bitmap
   int y;                    // the y position of the glyph on bitmap
   int w;                    // the width of the glyph in pixels
   int h;                    // the height of the glyph in pixels
   int kerning;              // pixels of kerning (see below)
   int offset_x;             // x offset to draw the glyph at
   int offset_y;             // y offset to draw the glyph at
   int advance;              // number of pixels to advance after this character
} ALLEGRO_GLYPH;

bitmap may be a sub-bitmap in the case of color fonts.  Bitmap can also
be NULL in which case nothing should be drawn (sometimes true for
whitespace characters in TTF fonts).

kerning should be added to the x position you draw to if you want your
text kerned and depends on which codepoints *note al_get_glyph:
#al_get_glyph. was called with.

Glyphs are tightly packed onto the bitmap, so you need to add offset_x
and offset_y to your draw position for the text to look right.

advance is the number of pixels to add to your x position to advance to
the next character in a string and includes kerning.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This API is new and subject
     to refinement.
See also: *note al_get_glyph: #al_get_glyph.


File: refman.info,  Node: al_init_font_addon,  Next: al_is_font_addon_initialized,  Prev: ALLEGRO_GLYPH,  Up: General font routines

32.1.3 al_init_font_addon
-------------------------

bool al_init_font_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/font.c#L367)

Initialise the font addon.

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

Similarly, if you wish to load truetype-fonts, do not forget to also
call *note al_init_ttf_addon: #al_init_ttf_addon.

Returns true on success, false on failure.  On the 5.0 branch, this
function has no return value.  You may wish to avoid checking the return
value if your code needs to be compatible with Allegro 5.0.  Currently,
the function will never return false.

See also: *note al_init_image_addon: #al_init_image_addon, *note
al_init_ttf_addon: #al_init_ttf_addon, *note al_shutdown_font_addon:
#al_shutdown_font_addon.


File: refman.info,  Node: al_is_font_addon_initialized,  Next: al_shutdown_font_addon,  Prev: al_init_font_addon,  Up: General font routines

32.1.4 al_is_font_addon_initialized
-----------------------------------

bool al_is_font_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/font.c#L393)

Returns true if the font addon is initialized, otherwise returns false.

Since: 5.2.6

See also: *note al_init_font_addon: #al_init_font_addon, *note
al_shutdown_font_addon: #al_shutdown_font_addon.


File: refman.info,  Node: al_shutdown_font_addon,  Next: al_load_font,  Prev: al_is_font_addon_initialized,  Up: General font routines

32.1.5 al_shutdown_font_addon
-----------------------------

void al_shutdown_font_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/font.c#L402)

Shut down the font addon.  This is done automatically at program exit,
but can be called any time the user wishes as well.

See also: *note al_init_font_addon: #al_init_font_addon.


File: refman.info,  Node: al_load_font,  Next: al_destroy_font,  Prev: al_shutdown_font_addon,  Up: General font routines

32.1.6 al_load_font
-------------------

ALLEGRO_FONT *al_load_font(char const *filename, int size, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/font.c#L450)

Loads a font from disk.  This will use *note al_load_bitmap_font_flags:
#al_load_bitmap_font_flags. if you pass the name of a known bitmap
format, or else *note al_load_ttf_font: #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 *note bitmap
flags: #al_set_new_bitmap_flags. at the time the font is loaded.

See also: *note al_destroy_font: #al_destroy_font, *note
al_init_font_addon: #al_init_font_addon, *note al_register_font_loader:
#al_register_font_loader, *note al_load_bitmap_font_flags:
#al_load_bitmap_font_flags, *note al_load_ttf_font: #al_load_ttf_font.


File: refman.info,  Node: al_destroy_font,  Next: al_register_font_loader,  Prev: al_load_font,  Up: General font routines

32.1.7 al_destroy_font
----------------------

void al_destroy_font(ALLEGRO_FONT *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L357)

Frees the memory being used by a font structure.  Does nothing if passed
NULL.

See also: *note al_load_font: #al_load_font.


File: refman.info,  Node: al_register_font_loader,  Next: al_get_font_line_height,  Prev: al_destroy_font,  Up: General font routines

32.1.8 al_register_font_loader
------------------------------

bool al_register_font_loader(char const *extension,
   ALLEGRO_FONT *(*load_font)(char const *filename, int size, int flags))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/font.c#L426)

Informs Allegro of a new font file type, telling it how to load files of
this format.

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

The ‘load_font’ argument may be NULL to unregister an entry.

Returns true on success, false on error.  Returns false if unregistering
an entry that doesn’t exist.

See also: *note al_init_font_addon: #al_init_font_addon.


File: refman.info,  Node: al_get_font_line_height,  Next: al_get_font_ascent,  Prev: al_register_font_loader,  Up: General font routines

32.1.9 al_get_font_line_height
------------------------------

int al_get_font_line_height(const ALLEGRO_FONT *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L297)

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.

X------------------------
    /\         |        |
   /  \        |        |
  /____\       ascent   |
 /      \      |        |
/        \     |        height
----------------        |
               |        |
               descent  |
               |        |
-------------------------

See also: *note al_get_text_width: #al_get_text_width, *note
al_get_text_dimensions: #al_get_text_dimensions.


File: refman.info,  Node: al_get_font_ascent,  Next: al_get_font_descent,  Prev: al_get_font_line_height,  Up: General font routines

32.1.10 al_get_font_ascent
--------------------------

int al_get_font_ascent(const ALLEGRO_FONT *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L307)

Returns the ascent of the specified font.

See also: *note al_get_font_descent: #al_get_font_descent, *note
al_get_font_line_height: #al_get_font_line_height.


File: refman.info,  Node: al_get_font_descent,  Next: al_get_text_width,  Prev: al_get_font_ascent,  Up: General font routines

32.1.11 al_get_font_descent
---------------------------

int al_get_font_descent(const ALLEGRO_FONT *f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L317)

Returns the descent of the specified font.

See also: *note al_get_font_ascent: #al_get_font_ascent, *note
al_get_font_line_height: #al_get_font_line_height.


File: refman.info,  Node: al_get_text_width,  Next: al_get_ustr_width,  Prev: al_get_font_descent,  Up: General font routines

32.1.12 al_get_text_width
-------------------------

int al_get_text_width(const ALLEGRO_FONT *f, const char *str)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L281)

Calculates the length of a string in a particular font, in pixels.

See also: *note al_get_ustr_width: #al_get_ustr_width, *note
al_get_font_line_height: #al_get_font_line_height, *note
al_get_text_dimensions: #al_get_text_dimensions.


File: refman.info,  Node: al_get_ustr_width,  Next: al_draw_text,  Prev: al_get_text_width,  Up: General font routines

32.1.13 al_get_ustr_width
-------------------------

int al_get_ustr_width(const ALLEGRO_FONT *f, ALLEGRO_USTR const *ustr)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L269)

Like *note al_get_text_width: #al_get_text_width. but expects an
ALLEGRO_USTR.

See also: *note al_get_text_width: #al_get_text_width, *note
al_get_ustr_dimensions: #al_get_ustr_dimensions.


File: refman.info,  Node: al_draw_text,  Next: al_draw_ustr,  Prev: al_get_ustr_width,  Up: General font routines

32.1.14 al_draw_text
--------------------

void al_draw_text(const ALLEGRO_FONT *font,
   ALLEGRO_COLOR color, float x, float y, int flags,
   char const *text) 

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L102)

Writes the NUL-terminated string ‘text’ onto the target bitmap at
position ‘x’, ‘y’, using the specified ‘font’.

The ‘flags’ parameter can be 0 or one of the following flags:

   • ALLEGRO_ALIGN_LEFT - Draw the text left-aligned (same as 0).
   • ALLEGRO_ALIGN_CENTRE - Draw the text centered around the given
     position.
   • ALLEGRO_ALIGN_RIGHT - Draw the text right-aligned to the given
     position.

It can also be combined with this flag:

   • ALLEGRO_ALIGN_INTEGER - Always draw text aligned to an integer
     pixel position.  This was formerly the default behaviour.  Since:
     5.0.8, 5.1.4

This function does not support newline characters (‘\n’), but you can
use *note al_draw_multiline_text: #al_draw_multiline_text. for multi
line text output.

See also: *note al_draw_ustr: #al_draw_ustr, *note al_draw_textf:
#al_draw_textf, *note al_draw_justified_text: #al_draw_justified_text,
*note al_draw_multiline_text: #al_draw_multiline_text.


File: refman.info,  Node: al_draw_ustr,  Next: al_draw_justified_text,  Prev: al_draw_text,  Up: General font routines

32.1.15 al_draw_ustr
--------------------

void al_draw_ustr(const ALLEGRO_FONT *font,
   ALLEGRO_COLOR color, float x, float y, int flags,
   const ALLEGRO_USTR *ustr) 

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L75)

Like *note al_draw_text: #al_draw_text, except the text is passed as an
ALLEGRO_USTR instead of a NUL-terminated char array.

See also: *note al_draw_text: #al_draw_text, *note
al_draw_justified_ustr: #al_draw_justified_ustr, *note
al_draw_multiline_ustr: #al_draw_multiline_ustr.


File: refman.info,  Node: al_draw_justified_text,  Next: al_draw_justified_ustr,  Prev: al_draw_ustr,  Up: General font routines

32.1.16 al_draw_justified_text
------------------------------

void al_draw_justified_text(const ALLEGRO_FONT *font,
   ALLEGRO_COLOR color, float x1, float x2,
   float y, float diff, int flags, const char *text)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L200)

Like *note al_draw_text: #al_draw_text, but justifies the string to the
region x1-x2.

The ‘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 ‘flags’ parameter can be 0 or one of the following flags:

   • ALLEGRO_ALIGN_INTEGER - Draw text aligned to integer pixel
     positions.  Since: 5.0.8, 5.1.5

See also: *note al_draw_justified_textf: #al_draw_justified_textf, *note
al_draw_justified_ustr: #al_draw_justified_ustr.


File: refman.info,  Node: al_draw_justified_ustr,  Next: al_draw_textf,  Prev: al_draw_justified_text,  Up: General font routines

32.1.17 al_draw_justified_ustr
------------------------------

void al_draw_justified_ustr(const ALLEGRO_FONT *font,
   ALLEGRO_COLOR color, float x1, float x2,
   float y, float diff, int flags, const ALLEGRO_USTR *ustr)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L115)

Like *note al_draw_justified_text: #al_draw_justified_text, except the
text is passed as an ALLEGRO_USTR instead of a NUL-terminated char
array.

See also: *note al_draw_justified_text: #al_draw_justified_text, *note
al_draw_justified_textf: #al_draw_justified_textf.


File: refman.info,  Node: al_draw_textf,  Next: al_draw_justified_textf,  Prev: al_draw_justified_ustr,  Up: General font routines

32.1.18 al_draw_textf
---------------------

void al_draw_textf(const ALLEGRO_FONT *font, ALLEGRO_COLOR color,
   float x, float y, int flags,
   const char *format, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L213)

Formatted text output, using a printf() style format string.  All
parameters have the same meaning as with *note al_draw_text:
#al_draw_text. otherwise.

See also: *note al_draw_text: #al_draw_text, *note al_draw_ustr:
#al_draw_ustr.


File: refman.info,  Node: al_draw_justified_textf,  Next: al_get_text_dimensions,  Prev: al_draw_textf,  Up: General font routines

32.1.19 al_draw_justified_textf
-------------------------------

void al_draw_justified_textf(const ALLEGRO_FONT *f,
   ALLEGRO_COLOR color, float x1, float x2, float y,
   float diff, int flags, const char *format, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L246)

Formatted text output, using a printf() style format string.  All
parameters have the same meaning as with *note al_draw_justified_text:
#al_draw_justified_text. otherwise.

See also: *note al_draw_justified_text: #al_draw_justified_text, *note
al_draw_justified_ustr: #al_draw_justified_ustr.


File: refman.info,  Node: al_get_text_dimensions,  Next: al_get_ustr_dimensions,  Prev: al_draw_justified_textf,  Up: General font routines

32.1.20 al_get_text_dimensions
------------------------------

void al_get_text_dimensions(const ALLEGRO_FONT *f,
   char const *text,
   int *bbx, int *bby, int *bbw, int *bbh)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L341)

Sometimes, the *note al_get_text_width: #al_get_text_width. and *note
al_get_font_line_height: #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):

   • x, y - Offset to upper left corner of bounding box.
   • w, h - Dimensions of bounding box.

Note that glyphs may go to the left and upwards of the X, in which case
x and y will have negative values.

See also: *note al_get_text_width: #al_get_text_width, *note
al_get_font_line_height: #al_get_font_line_height, *note
al_get_ustr_dimensions: #al_get_ustr_dimensions.


File: refman.info,  Node: al_get_ustr_dimensions,  Next: al_get_allegro_font_version,  Prev: al_get_text_dimensions,  Up: General font routines

32.1.21 al_get_ustr_dimensions
------------------------------

void al_get_ustr_dimensions(const ALLEGRO_FONT *f,
   ALLEGRO_USTR const *ustr,
   int *bbx, int *bby, int *bbw, int *bbh)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L327)

Like *note al_get_text_dimensions: #al_get_text_dimensions, except the
text is passed as an ALLEGRO_USTR instead of a NUL-terminated char
array.

See also: *note al_get_text_dimensions: #al_get_text_dimensions.


File: refman.info,  Node: al_get_allegro_font_version,  Next: al_get_font_ranges,  Prev: al_get_ustr_dimensions,  Up: General font routines

32.1.22 al_get_allegro_font_version
-----------------------------------

uint32_t al_get_allegro_font_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/font.c#L497)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: al_get_font_ranges,  Next: al_set_fallback_font,  Prev: al_get_allegro_font_version,  Up: General font routines

32.1.23 al_get_font_ranges
--------------------------

int al_get_font_ranges(ALLEGRO_FONT *f, int ranges_count, int *ranges)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L370)

Gets information about all glyphs contained in a font, as a list of
ranges.  Ranges have the same format as with *note
al_grab_font_from_bitmap: #al_grab_font_from_bitmap.

‘ranges_count’ is the maximum number of ranges that will be returned.

‘ranges’ should be an array with room for ‘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.

Returns the number of ranges contained in the font (even if it is bigger
than ‘ranges_count’).

Since: 5.1.4

See also: *note al_grab_font_from_bitmap: #al_grab_font_from_bitmap.


File: refman.info,  Node: al_set_fallback_font,  Next: al_get_fallback_font,  Prev: al_get_font_ranges,  Up: General font routines

32.1.24 al_set_fallback_font
----------------------------

void al_set_fallback_font(ALLEGRO_FONT *font, ALLEGRO_FONT *fallback)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L695)

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 NULL to remove a fallback font again.

Since: 5.1.12

See also: *note al_get_fallback_font: #al_get_fallback_font, *note
al_draw_glyph: #al_draw_glyph, *note al_draw_text: #al_draw_text.


File: refman.info,  Node: al_get_fallback_font,  Prev: al_set_fallback_font,  Up: General font routines

32.1.25 al_get_fallback_font
----------------------------

ALLEGRO_FONT *al_get_fallback_font(ALLEGRO_FONT *font)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L702)

Retrieves the fallback font for this font or NULL.

Since: 5.1.12

See also: *note al_set_fallback_font: #al_set_fallback_font.


File: refman.info,  Node: Per glyph text handling,  Next: Multiline text drawing,  Prev: General font routines,  Up: Font addons

32.2 Per glyph text handling
============================

For some applications Allegro’s text drawing functions may not be
sufficient.  For example, you would like to give a different color to
every letter in a word, or use different a font for a drop cap.

That is why Allegro supports drawing and getting the dimensions of the
individual glyphs of a font.  A glyph is a particular visual
representation of a letter, character or symbol in a specific font.

And it’s also possible to get the kerning to use between two glyphs.
These per glyph functions have less overhead than Allegro’s per string
text drawing and dimensioning functions.  So, with these functions you
can write your own efficient and precise custom text drawing functions.

* Menu:

* al_draw_glyph::
* al_get_glyph_width::
* al_get_glyph_dimensions::
* al_get_glyph_advance::


File: refman.info,  Node: al_draw_glyph,  Next: al_get_glyph_width,  Up: Per glyph text handling

32.2.1 al_draw_glyph
--------------------

void al_draw_glyph(const ALLEGRO_FONT *f, ALLEGRO_COLOR color, float x, float y,
   int codepoint)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L377)

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
*note al_get_glyph_advance: #al_get_glyph_advance. to determine the
position of each glyph.  For drawing strings in other directions, such
as top to down, use *note al_get_glyph_dimensions:
#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 *note
al_hold_bitmap_drawing: #al_hold_bitmap_drawing. with true as the
parameter, before drawing the glyphs, and then call *note
al_hold_bitmap_drawing: #al_hold_bitmap_drawing. again with false as a
parameter when done drawing the glyphs to further enhance performance.

Since: 5.1.12

See also: *note al_get_glyph_width: #al_get_glyph_width, *note
al_get_glyph_dimensions: #al_get_glyph_dimensions, *note
al_get_glyph_advance: #al_get_glyph_advance.


File: refman.info,  Node: al_get_glyph_width,  Next: al_get_glyph_dimensions,  Prev: al_draw_glyph,  Up: Per glyph text handling

32.2.2 al_get_glyph_width
-------------------------

int al_get_glyph_width(const ALLEGRO_FONT *f, int codepoint)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L385)

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.

Since: 5.1.12

See also: *note al_draw_glyph: #al_draw_glyph, *note
al_get_glyph_dimensions: #al_get_glyph_dimensions, *note
al_get_glyph_advance: #al_get_glyph_advance.


File: refman.info,  Node: al_get_glyph_dimensions,  Next: al_get_glyph_advance,  Prev: al_get_glyph_width,  Up: Per glyph text handling

32.2.3 al_get_glyph_dimensions
------------------------------

bool al_get_glyph_dimensions(const ALLEGRO_FONT *f,
   int codepoint, int *bbx, int *bby, int *bbw, int *bbh)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L392)

Sometimes, the *note al_get_glyph_width: #al_get_glyph_width. or *note
al_get_glyph_advance: #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):

   • bbx, bby - Offset to upper left corner of bounding box.
   • bbw, bbh - Dimensions of bounding box.

These values are the same as *note al_get_text_dimensions:
#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 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 bbx + bbw space between the glyphs in the x
direction for a compact placement.

In the figure below is an example of what bbx and bby may be like for a
‘2’ glyph, and a ‘g’ glyph of the same font compared to the result of
al_get_glyph_width().

   al_get_glyph_width()     al_get_glyph_width()
          __|___                   __|__
         /      \                 /     \  
     bbx    bbw                 bbx   bbw    
    <-->+<------>+           <-->+<----->+   X baseline
    ^   |        |           ^   |       |   
bby |   |        |       bby |   |       |   
    v   |        |           |   |       |   
    +---+--------+           |   |       |
    ^   | *****  |           |   |       |
    |   |*    ** |           v   |       |
bbh |   |    **  |       bbh +---+-------+
    |   |  **    |           ^   | ***** |
    v   |********|           |   |*     *|
    +---+--------+           |   | ***** |
                             |   |      *|
                             |   | *    *|
                             v   |  **** |
                             +---+-------+

Since: 5.1.12

See also: *note al_draw_glyph: #al_draw_glyph, *note al_get_glyph_width:
#al_get_glyph_width, *note al_get_glyph_advance: #al_get_glyph_advance.


File: refman.info,  Node: al_get_glyph_advance,  Prev: al_get_glyph_dimensions,  Up: Per glyph text handling

32.2.4 al_get_glyph_advance
---------------------------

int al_get_glyph_advance(const ALLEGRO_FONT *f, int codepoint1, int codepoint2)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L400)

This function returns by how much the x position should be advanced for
left to right text drawing when the glyph that corresponds to codepoint1
has been drawn, and the glyph that corresponds to codepoint2 will be the
next to be drawn.  This takes into consideration the horizontal advance
width of the glyph that corresponds with codepoint1 as well as the
kerning between the glyphs of codepoint1 and 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 ALLEGRO_NO_KERNING as codepoint1 then al_get_glyph_advance
will return 0.  this can be useful when drawing the first character of a
string in a loop.

Pass ALLEGRO_NO_KERNING as codepoint2 to get the horizontal advance
width of the glyph that corresponds to 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 codepoint1 is not present
in the ‘font’.  If the glyph of codepoint2 is not present in the font,
the horizontal advance width of the glyph that corresponds to 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 *note al_get_glyph_advance: #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 *note
al_get_glyph_advance: #al_get_glyph_advance. returns for style or
effect.

In the figure below is an example of what the result of
al_get_glyph_advance may be like for two glypphs ‘A’ and ‘l’ of the same
font that has kerning for the “Al” pair, without and with the
ALLEGRO_NO_KERNING flag.

al_get_glyph_advance(font, 'A', 'l')
     ___|___                  
    /       \  
    -------------            
        /\   -|  
       /  \   |
      /____\  |
     /      \ |
    /        \ \_             
    -------------
    
    
al_get_glyph_advance(font, 'A', ALLEGRO_NO_KERNING)
     ____|____
    /         \  
    ---------------
        /\     -|  
       /  \     |
      /____\    |
     /      \   |
    /        \   \_             
    ---------------

Since: 5.1.12

See also: *note al_draw_glyph: #al_draw_glyph, *note al_get_glyph_width:
#al_get_glyph_width, *note al_get_glyph_dimensions:
#al_get_glyph_dimensions.


File: refman.info,  Node: Multiline text drawing,  Next: Bitmap fonts,  Prev: Per glyph text handling,  Up: Font addons

32.3 Multiline text drawing
===========================

* Menu:

* al_draw_multiline_text::
* al_draw_multiline_ustr::
* al_draw_multiline_textf::
* al_do_multiline_text::
* al_do_multiline_ustr::


File: refman.info,  Node: al_draw_multiline_text,  Next: al_draw_multiline_ustr,  Up: Multiline text drawing

32.3.1 al_draw_multiline_text
-----------------------------

void al_draw_multiline_text(const ALLEGRO_FONT *font,
     ALLEGRO_COLOR color, float x, float y, float max_width, float line_height,
     int flags, const char *text)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L656)

Like *note al_draw_text: #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 ‘line_height’ parameter and drawn each
as if *note al_draw_text: #al_draw_text. was called on them.

A newline ‘\n’ in the ‘text’ will cause a “hard” line break after its
occurrence in the string.  The text after a hard break is placed on a
new line.  Carriage return ‘\r’ 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 ‘max_width’ parameter controls the maximum desired width of the
lines.  This function will try to introduce a “soft” line break after
the longest possible series of words that will fit in ‘max_length’ when
drawn with the given ‘font’.  A “soft” line break can occur either on a
space or tab (‘\t’) character.

However, it is possible that ‘max_width’ is too small, or the words in
‘text’ are too long to fit ‘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 ‘max_width’
to be visible, then use *note al_set_clipping_rectangle:
#al_set_clipping_rectangle. to clip it off and hide it.

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

The ‘flags’ ALLEGRO_ALIGN_LEFT, ALLEGRO_ALIGN_CENTRE,
ALLEGRO_ALIGN_RIGHT and 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 *note al_do_multiline_text: #al_do_multiline_text.

Since: 5.1.9

See also: *note al_do_multiline_text: #al_do_multiline_text, *note
al_draw_multiline_ustr: #al_draw_multiline_ustr, *note
al_draw_multiline_textf: #al_draw_multiline_textf.


File: refman.info,  Node: al_draw_multiline_ustr,  Next: al_draw_multiline_textf,  Prev: al_draw_multiline_text,  Up: Multiline text drawing

32.3.2 al_draw_multiline_ustr
-----------------------------

void al_draw_multiline_ustr(const ALLEGRO_FONT *font,
     ALLEGRO_COLOR color, float x, float y, float max_width, float line_height,
     int flags, const ALLEGRO_USTR *ustr)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L629)

Like *note al_draw_multiline_text: #al_draw_multiline_text, except the
text is passed as an ALLEGRO_USTR instead of a NUL-terminated char
array.

Since: 5.1.9

See also: *note al_draw_multiline_text: #al_draw_multiline_text, *note
al_draw_multiline_textf: #al_draw_multiline_textf, *note
al_do_multiline_text: #al_do_multiline_text.


File: refman.info,  Node: al_draw_multiline_textf,  Next: al_do_multiline_text,  Prev: al_draw_multiline_ustr,  Up: Multiline text drawing

32.3.3 al_draw_multiline_textf
------------------------------

void al_draw_multiline_textf(const ALLEGRO_FONT *font,
     ALLEGRO_COLOR color, float x, float y, float max_width, float line_height,
     int flags, const char *format, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L672)

Formatted text output, using a printf() style format string.  All
parameters have the same meaning as with *note al_draw_multiline_text:
#al_draw_multiline_text. otherwise.

Since: 5.1.9

See also: *note al_draw_multiline_text: #al_draw_multiline_text, *note
al_draw_multiline_ustr: #al_draw_multiline_ustr, *note
al_do_multiline_text: #al_do_multiline_text.


File: refman.info,  Node: al_do_multiline_text,  Next: al_do_multiline_ustr,  Prev: al_draw_multiline_textf,  Up: Multiline text drawing

32.3.4 al_do_multiline_text
---------------------------

void al_do_multiline_text(const ALLEGRO_FONT *font,
   float max_width, const char *text,
   bool (*cb)(int line_num, const char *line, int size, void *extra),
   void *extra)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L582)

This function processes the ‘text’ and splits it into lines as *note
al_draw_multiline_text: #al_draw_multiline_text. would, and then calls
the callback ‘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 *note al_draw_multiline_text:
#al_draw_multiline_text. for an explanation of the splitting algorithm.

For every line that this function splits ‘text’ into the callback ‘cb’
will be called once with the following parameters:

   • ‘line_num’ - the number of the line starting from zero and counting
     up
   • ‘line’ - a pointer to the beginning character of the line (see
     below)
   • ‘size’ - the size of the line (0 for empty lines)
   • ‘extra’ - the same pointer that was passed to al_do_multiline_text

Note that ‘line’ is _not_ guaranteed to be a NUL-terminated string, but
will merely point to a character within ‘text’ or to an empty string in
case of an empty line.  If you need a NUL-terminated string, you will
have to copy ‘line’ to a buffer and NUL-terminate it yourself.  You will
also have to make your own copy if you need the contents of ‘line’ after
‘cb’ has returned, as ‘line’ is _not_ guaranteed to be valid after that.

If the callback ‘cb’ returns false, al_do_multiline_text will stop
immediately, otherwise it will continue on to the next line.

Since: 5.1.9

See also: *note al_draw_multiline_text: #al_draw_multiline_text.


File: refman.info,  Node: al_do_multiline_ustr,  Prev: al_do_multiline_text,  Up: Multiline text drawing

32.3.5 al_do_multiline_ustr
---------------------------

void al_do_multiline_ustr(const ALLEGRO_FONT *font, float max_width,
   const ALLEGRO_USTR *ustr,
   bool (*cb)(int line_num, const ALLEGRO_USTR * line, void *extra),
   void *extra)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L516)

Like *note al_do_multiline_text: #al_do_multiline_text, but using
ALLEGRO_USTR instead of a NUL-terminated char array for text.

Since: 5.1.9

See also: *note al_draw_multiline_ustr: #al_draw_multiline_ustr.


File: refman.info,  Node: Bitmap fonts,  Next: TTF fonts,  Prev: Multiline text drawing,  Up: Font addons

32.4 Bitmap fonts
=================

* Menu:

* al_grab_font_from_bitmap::
* al_load_bitmap_font::
* al_load_bitmap_font_flags::
* al_create_builtin_font::


File: refman.info,  Node: al_grab_font_from_bitmap,  Next: al_load_bitmap_font,  Up: Bitmap fonts

32.4.1 al_grab_font_from_bitmap
-------------------------------

ALLEGRO_FONT *al_grab_font_from_bitmap(ALLEGRO_BITMAP *bmp,
   int ranges_n, const int ranges[])

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/fontbmp.c#L206)

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.

Parameters:

   • bmp: The bitmap with the glyphs drawn onto it
   • n: Number of unicode ranges in the bitmap.
   • ranges: ‘n’ pairs of first and last unicode point to map glyphs to
     for each range.

The bitmap format is as in the following example, which contains three
glyphs for 1, 2 and 3.

.............
. 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 *note al_draw_bitmap:
#al_draw_bitmap, so usually you will want the rectangles filled with
full transparency and the glyphs drawn in opaque white.

Examples:

int ranges[] = {32, 126};
al_grab_font_from_bitmap(bitmap, 1, ranges)

int ranges[] = {
    0x0020, 0x007F,  /* ASCII */
    0x00A1, 0x00FF,  /* Latin 1 */
    0x0100, 0x017F,  /* Extended-A */
    0x20AC, 0x20AC}; /* Euro */
al_grab_font_from_bitmap(bitmap, 4, ranges)

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.)

See also: *note al_load_bitmap: #al_load_bitmap, *note
al_grab_font_from_bitmap: #al_grab_font_from_bitmap.


File: refman.info,  Node: al_load_bitmap_font,  Next: al_load_bitmap_font_flags,  Prev: al_grab_font_from_bitmap,  Up: Bitmap fonts

32.4.2 al_load_bitmap_font
--------------------------

ALLEGRO_FONT *al_load_bitmap_font(const char *fname)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/fontbmp.c#L181)

Load a bitmap font from a file.  This is done by first calling *note
al_load_bitmap_flags: #al_load_bitmap_flags. and then *note
al_grab_font_from_bitmap: #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 *note
al_convert_mask_to_alpha: #al_convert_mask_to_alpha. on it before
passing it to *note al_grab_font_from_bitmap: #al_grab_font_from_bitmap.

See also: *note al_load_bitmap_font_flags: #al_load_bitmap_font_flags,
*note al_load_font: #al_load_font, *note al_load_bitmap_flags:
#al_load_bitmap_flags.


File: refman.info,  Node: al_load_bitmap_font_flags,  Next: al_create_builtin_font,  Prev: al_load_bitmap_font,  Up: Bitmap fonts

32.4.3 al_load_bitmap_font_flags
--------------------------------

ALLEGRO_FONT *al_load_bitmap_font_flags(const char *fname, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/fontbmp.c#L197)

Like *note al_load_bitmap_font: #al_load_bitmap_font. but additionally
takes a flags parameter which is a bitfield containing a combination of
the following:

ALLEGRO_NO_PREMULTIPLIED_ALPHA

     The same meaning as for *note al_load_bitmap_flags:
     #al_load_bitmap_flags.

See also: *note al_load_bitmap_font: #al_load_bitmap_font, *note
al_load_bitmap_flags: #al_load_bitmap_flags.


File: refman.info,  Node: al_create_builtin_font,  Prev: al_load_bitmap_font_flags,  Up: Bitmap fonts

32.4.4 al_create_builtin_font
-----------------------------

ALLEGRO_FONT *al_create_builtin_font(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/stdfont.c#L447)

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:

0x0020 to 0x007F (ASCII)
0x00A1 to 0x00FF (Latin 1)
0x0100 to 0x017F (Extended A)
0x20AC to 0x20AC (euro currency symbol)

Returns NULL on an error.

The font memory must be freed the same way as for any other font, using
*note al_destroy_font: #al_destroy_font.

Since: 5.0.8, 5.1.3

See also: *note al_load_bitmap_font: #al_load_bitmap_font, *note
al_destroy_font: #al_destroy_font.


File: refman.info,  Node: TTF fonts,  Prev: Bitmap fonts,  Up: Font addons

32.5 TTF fonts
==============

These functions are declared in the following header file.  Link with
allegro_ttf.

 #include <allegro5/allegro_ttf.h>

* Menu:

* al_init_ttf_addon::
* al_is_ttf_addon_initialized::
* al_shutdown_ttf_addon::
* al_load_ttf_font::
* al_load_ttf_font_f::
* al_load_ttf_font_stretch::
* al_load_ttf_font_stretch_f::
* al_get_allegro_ttf_version::
* al_get_glyph::


File: refman.info,  Node: al_init_ttf_addon,  Next: al_is_ttf_addon_initialized,  Up: TTF fonts

32.5.1 al_init_ttf_addon
------------------------

bool al_init_ttf_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L1135)

Call this after *note al_init_font_addon: #al_init_font_addon. to make
*note al_load_font: #al_load_font. recognize “.ttf” and other formats
supported by *note al_load_ttf_font: #al_load_ttf_font.

Returns true on success, false on failure.


File: refman.info,  Node: al_is_ttf_addon_initialized,  Next: al_shutdown_ttf_addon,  Prev: al_init_ttf_addon,  Up: TTF fonts

32.5.2 al_is_ttf_addon_initialized
----------------------------------

bool al_is_ttf_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L1172)

Returns true if the TTF addon is initialized, otherwise returns false.

Since: 5.2.6

See also: *note al_init_ttf_addon: #al_init_ttf_addon, *note
al_shutdown_ttf_addon: #al_shutdown_ttf_addon.


File: refman.info,  Node: al_shutdown_ttf_addon,  Next: al_load_ttf_font,  Prev: al_is_ttf_addon_initialized,  Up: TTF fonts

32.5.3 al_shutdown_ttf_addon
----------------------------

void al_shutdown_ttf_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L1180)

Unloads the ttf addon again.  You normally don’t need to call this.


File: refman.info,  Node: al_load_ttf_font,  Next: al_load_ttf_font_f,  Prev: al_shutdown_ttf_addon,  Up: TTF fonts

32.5.4 al_load_ttf_font
-----------------------

ALLEGRO_FONT *al_load_ttf_font(char const *filename, int size, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L1008)

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

_TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF, and
others_

The ‘size’ parameter determines the size the font will be rendered at,
specified in pixels.  The standard font size is measured in _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.

     _Note:_ If you want to display text at multiple sizes, load the
     font multiple times with different size parameters.
The following flags are supported:

   • ALLEGRO_TTF_NO_KERNING - Do not use any kerning even if the font
     file supports it.

   • ALLEGRO_TTF_MONOCHROME - Load as a monochrome font (which means no
     anti-aliasing of the font is done).

   • ALLEGRO_TTF_NO_AUTOHINT - Disable the Auto Hinter which is enabled
     by default in newer versions of FreeType.  Since: 5.0.6, 5.1.2

See also: *note al_init_ttf_addon: #al_init_ttf_addon, *note
al_load_ttf_font_f: #al_load_ttf_font_f.


File: refman.info,  Node: al_load_ttf_font_f,  Next: al_load_ttf_font_stretch,  Prev: al_load_ttf_font,  Up: TTF fonts

32.5.5 al_load_ttf_font_f
-------------------------

ALLEGRO_FONT *al_load_ttf_font_f(ALLEGRO_FILE *file,
    char const *filename, int size, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L859)

Like *note al_load_ttf_font: #al_load_ttf_font, but the font is read
from the file handle.  The filename is only used to find possible
additional files next to a font file.

     _Note:_ The file handle is owned by the returned ALLEGRO_FONT
     object and must not be freed by the caller, as FreeType expects to
     be able to read from it at a later time.


File: refman.info,  Node: al_load_ttf_font_stretch,  Next: al_load_ttf_font_stretch_f,  Prev: al_load_ttf_font_f,  Up: TTF fonts

32.5.6 al_load_ttf_font_stretch
-------------------------------

ALLEGRO_FONT *al_load_ttf_font_stretch(char const *filename, int w, int h,
   int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L1016)

Like *note al_load_ttf_font: #al_load_ttf_font, except it takes separate
width and height 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 *note al_load_ttf_font: #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.

Returns ‘NULL’ if the height is positive while width is negative, or if
the height is negative while the width is positive.

Since: 5.0.6, 5.1.0

See also: *note al_load_ttf_font: #al_load_ttf_font, *note
al_load_ttf_font_stretch_f: #al_load_ttf_font_stretch_f.


File: refman.info,  Node: al_load_ttf_font_stretch_f,  Next: al_get_allegro_ttf_version,  Prev: al_load_ttf_font_stretch,  Up: TTF fonts

32.5.7 al_load_ttf_font_stretch_f
---------------------------------

ALLEGRO_FONT *al_load_ttf_font_stretch_f(ALLEGRO_FILE *file,
    char const *filename, int w, int h, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L868)

Like *note al_load_ttf_font_stretch: #al_load_ttf_font_stretch, but the
font is read from the file handle.  The filename is only used to find
possible additional files next to a font file.

     _Note:_ The file handle is owned by the returned ALLEGRO_FONT
     object and must not be freed by the caller, as FreeType expects to
     be able to read from it at a later time.
Since: 5.0.6, 5.1.0

See also: *note al_load_ttf_font_stretch: #al_load_ttf_font_stretch.


File: refman.info,  Node: al_get_allegro_ttf_version,  Next: al_get_glyph,  Prev: al_load_ttf_font_stretch_f,  Up: TTF fonts

32.5.8 al_get_allegro_ttf_version
---------------------------------

uint32_t al_get_allegro_ttf_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/ttf/ttf.c#L1197)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: al_get_glyph,  Prev: al_get_allegro_ttf_version,  Up: TTF fonts

32.5.9 al_get_glyph
-------------------

bool al_get_glyph(const ALLEGRO_FONT *f, int prev_codepoint, int codepoint, ALLEGRO_GLYPH *glyph)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/font/text.c#L407)

Gets all the information about a glyph, including the bitmap, needed to
draw it yourself.  prev_codepoint is the codepoint in the string before
the one you want to draw and is used for kerning.  codepoint is the
character you want to get info about.  You should clear the ‘glyph’
structure to 0 with memset before passing it to this function for future
compatibility.

Since: 5.2.1

     _*note Unstable API: #unstable-api.:_ This API is new and subject
     to refinement.
See also: *note ALLEGRO_GLYPH: #allegro_glyph.


File: refman.info,  Node: Image I/O addon,  Next: Main addon,  Prev: Font addons,  Up: Top

33 Image I/O addon
******************

These functions are declared in the following header file.  Link with
allegro_image.

 #include <allegro5/allegro_image.h>

Some of the format handlers define configuration options for specifying
things like compression level or gamma handling.  Refer to *note
al_get_system_config: #al_get_system_config. for their documentation.

* Menu:

* al_init_image_addon::
* al_is_image_addon_initialized::
* al_shutdown_image_addon::
* al_get_allegro_image_version::


File: refman.info,  Node: al_init_image_addon,  Next: al_is_image_addon_initialized,  Up: Image I/O addon

33.1 al_init_image_addon
========================

bool al_init_image_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/image/iio.c#L14)

Initializes the image addon.  This registers bitmap format handlers for
*note al_load_bitmap: #al_load_bitmap, *note al_load_bitmap_f:
#al_load_bitmap_f, *note al_save_bitmap: #al_save_bitmap, *note
al_save_bitmap_f: #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.


File: refman.info,  Node: al_is_image_addon_initialized,  Next: al_shutdown_image_addon,  Prev: al_init_image_addon,  Up: Image I/O addon

33.2 al_is_image_addon_initialized
==================================

bool al_is_image_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/image/iio.c#L169)

Returns true if the image addon is initialized, otherwise returns false.

Since: 5.2.6


File: refman.info,  Node: al_shutdown_image_addon,  Next: al_get_allegro_image_version,  Prev: al_is_image_addon_initialized,  Up: Image I/O addon

33.3 al_shutdown_image_addon
============================

void al_shutdown_image_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/image/iio.c#L177)

Shut down the image addon.  This is done automatically at program exit,
but can be called any time the user wishes as well.


File: refman.info,  Node: al_get_allegro_image_version,  Prev: al_shutdown_image_addon,  Up: Image I/O addon

33.4 al_get_allegro_image_version
=================================

uint32_t al_get_allegro_image_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/image/iio.c#L185)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: Main addon,  Next: Memfile interface,  Prev: Image I/O addon,  Up: Top

34 Main addon
*************

The ‘main’ addon has no public API, but contains functionality to enable
programs using Allegro to build and run without platform-specific
changes.

On platforms that require this functionality (e.g. OSX) this addon
contains a C ‘main’ function that invokes *note al_run_main:
#al_run_main. with the user’s own ‘main’ function, where the user’s
‘main’ function has had its name mangled to something else.  The file
that defines the user ‘main’ function must include the header file
‘allegro5/allegro.h’; that header performs the name mangling using some
macros.

If the user ‘main’ function is defined in C++, then it must have the
following signature for this addon to work:

int main(int argc, char **argv)

This addon does nothing on platforms that don’t require its
functionality, but you should keep it in mind in case you need to port
to platforms that do require it.

Link with allegro_main.


File: refman.info,  Node: Memfile interface,  Next: Native dialogs support,  Prev: Main addon,  Up: Top

35 Memfile interface
********************

The memfile interface allows you to treat a fixed block of contiguous
memory as a file that can be used with Allegro’s I/O functions.

These functions are declared in the following header file.  Link with
allegro_memfile.

 #include <allegro5/allegro_memfile.h>

* Menu:

* al_open_memfile::
* al_get_allegro_memfile_version::


File: refman.info,  Node: al_open_memfile,  Next: al_get_allegro_memfile_version,  Up: Memfile interface

35.1 al_open_memfile
====================

ALLEGRO_FILE *al_open_memfile(void *mem, int64_t size, const char *mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/memfile/memfile.c#L169)

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 “r” (readable) and “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 *note al_fclose: #al_fclose.  After the file is
closed, you are responsible for freeing the memory (if needed).


File: refman.info,  Node: al_get_allegro_memfile_version,  Prev: al_open_memfile,  Up: Memfile interface

35.2 al_get_allegro_memfile_version
===================================

uint32_t al_get_allegro_memfile_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/memfile/memfile.c#L201)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: Native dialogs support,  Next: PhysicsFS integration,  Prev: Memfile interface,  Up: Top

36 Native dialogs support
*************************

These functions are declared in the following header file.  Link with
allegro_dialog.

 #include <allegro5/allegro_native_dialog.h>

* Menu:

* ALLEGRO_FILECHOOSER::
* ALLEGRO_TEXTLOG::
* al_init_native_dialog_addon::
* al_is_native_dialog_addon_initialized::
* al_shutdown_native_dialog_addon::
* al_create_native_file_dialog::
* al_show_native_file_dialog::
* al_get_native_file_dialog_count::
* al_get_native_file_dialog_path::
* al_destroy_native_file_dialog::
* al_show_native_message_box::
* al_open_native_text_log::
* al_close_native_text_log::
* al_append_native_text_log::
* al_get_native_text_log_event_source::
* al_get_allegro_native_dialog_version::
* Menus::


File: refman.info,  Node: ALLEGRO_FILECHOOSER,  Next: ALLEGRO_TEXTLOG,  Up: Native dialogs support

36.1 ALLEGRO_FILECHOOSER
========================

typedef struct ALLEGRO_FILECHOOSER ALLEGRO_FILECHOOSER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/allegro5/allegro_native_dialog.h#L38)

Opaque handle to a native file dialog.


File: refman.info,  Node: ALLEGRO_TEXTLOG,  Next: al_init_native_dialog_addon,  Prev: ALLEGRO_FILECHOOSER,  Up: Native dialogs support

36.2 ALLEGRO_TEXTLOG
====================

typedef struct ALLEGRO_TEXTLOG ALLEGRO_TEXTLOG;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/allegro5/allegro_native_dialog.h#L42)

Opaque handle to a text log window.


File: refman.info,  Node: al_init_native_dialog_addon,  Next: al_is_native_dialog_addon_initialized,  Prev: ALLEGRO_TEXTLOG,  Up: Native dialogs support

36.3 al_init_native_dialog_addon
================================

bool al_init_native_dialog_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L15)

Initialise the native dialog addon.

Returns true on success, false on error.

Since: 5.0.9, 5.1.0

     _Note:_ Prior to Allegro 5.1.0 native dialog functions could be
     called without explicit initialisation, but that is now deprecated.
     Future functionality may require explicit initialisation.  An
     exception is *note al_show_native_message_box:
     #al_show_native_message_box, which may be useful to show an error
     message if Allegro fails to initialise.
See also: *note al_shutdown_native_dialog_addon:
#al_shutdown_native_dialog_addon.


File: refman.info,  Node: al_is_native_dialog_addon_initialized,  Next: al_shutdown_native_dialog_addon,  Prev: al_init_native_dialog_addon,  Up: Native dialogs support

36.4 al_is_native_dialog_addon_initialized
==========================================

bool al_is_native_dialog_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L32)

Returns true if the native dialog addon is initialized, otherwise
returns false.

Since: 5.2.6


File: refman.info,  Node: al_shutdown_native_dialog_addon,  Next: al_create_native_file_dialog,  Prev: al_is_native_dialog_addon_initialized,  Up: Native dialogs support

36.5 al_shutdown_native_dialog_addon
====================================

void al_shutdown_native_dialog_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L39)

Shut down the native dialog addon.

Since: 5.0.9, 5.1.5

See also: *note al_init_native_dialog_addon:
#al_init_native_dialog_addon.


File: refman.info,  Node: al_create_native_file_dialog,  Next: al_show_native_file_dialog,  Prev: al_shutdown_native_dialog_addon,  Up: Native dialogs support

36.6 al_create_native_file_dialog
=================================

ALLEGRO_FILECHOOSER *al_create_native_file_dialog(
   char const *initial_path,
   char const *title,
   char const *patterns,
   int mode)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L50)

Creates a new native file dialog.  You should only have one such dialog
opened at a time.

Parameters:

   • ‘initial_path’: The initial search path and filename.  Can be NULL.
     To start with a blank file name the string should end with a
     directory separator (this should be the common case).

   • ‘title’: Title of the dialog.

   • ‘patterns’: A list of semi-colon separated patterns to match.  This
     should not contain any whitespace characters.  If a pattern
     contains the ‘/’ character, then it is treated as a MIME type (e.g.
     ‘image/png’).  Not all platforms support file patterns.  If the
     native dialog does not provide support, this parameter is ignored.

   • ‘mode’: 0, or a combination of the following flags:

ALLEGRO_FILECHOOSER_FILE_MUST_EXIST

     If supported by the native dialog, it will not allow entering new
     names, but just allow existing files to be selected.  Else it is
     ignored.
ALLEGRO_FILECHOOSER_SAVE

     If the native dialog system has a different dialog for saving (for
     example one which allows creating new directories), it is used.
     Else it is ignored.
ALLEGRO_FILECHOOSER_FOLDER

     If there is support for a separate dialog to select a folder
     instead of a file, it will be used.
ALLEGRO_FILECHOOSER_PICTURES

     If a different dialog is available for selecting pictures, it is
     used.  Else it is ignored.
ALLEGRO_FILECHOOSER_SHOW_HIDDEN

     If the platform supports it, also hidden files will be shown.
ALLEGRO_FILECHOOSER_MULTIPLE

     If supported, allow selecting multiple files.

Returns:

A handle to the dialog which you can pass to *note
al_show_native_file_dialog: #al_show_native_file_dialog. to display it,
and from which you then can query the results using *note
al_get_native_file_dialog_count: #al_get_native_file_dialog_count. and
*note al_get_native_file_dialog_path: #al_get_native_file_dialog_path.
When you are done, call *note al_destroy_native_file_dialog:
#al_destroy_native_file_dialog. on it.

If a dialog window could not be created then this function returns NULL.


File: refman.info,  Node: al_show_native_file_dialog,  Next: al_get_native_file_dialog_count,  Prev: al_create_native_file_dialog,  Up: Native dialogs support

36.7 al_show_native_file_dialog
===============================

bool al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
   ALLEGRO_FILECHOOSER *dialog)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L74)

Show the dialog window.  The display may be NULL, otherwise the given
display is treated as the parent if possible.

This function blocks the calling thread until it returns, so you may
want to spawn a thread with *note al_create_thread: #al_create_thread.
and call it from inside that thread.

Returns true on success, false on failure.


File: refman.info,  Node: al_get_native_file_dialog_count,  Next: al_get_native_file_dialog_path,  Prev: al_show_native_file_dialog,  Up: Native dialogs support

36.8 al_get_native_file_dialog_count
====================================

int al_get_native_file_dialog_count(const ALLEGRO_FILECHOOSER *dialog)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L83)

Returns the number of files selected, or 0 if the dialog was cancelled.


File: refman.info,  Node: al_get_native_file_dialog_path,  Next: al_destroy_native_file_dialog,  Prev: al_get_native_file_dialog_count,  Up: Native dialogs support

36.9 al_get_native_file_dialog_path
===================================

const char *al_get_native_file_dialog_path(
   const ALLEGRO_FILECHOOSER *dialog, size_t i)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L91)

Returns one of the selected paths with index ‘i’.  The index should
range from ‘0’ to the return value of *note
al_get_native_file_dialog_count: #al_get_native_file_dialog_count. ‘-1’.


File: refman.info,  Node: al_destroy_native_file_dialog,  Next: al_show_native_message_box,  Prev: al_get_native_file_dialog_path,  Up: Native dialogs support

36.10 al_destroy_native_file_dialog
===================================

void al_destroy_native_file_dialog(ALLEGRO_FILECHOOSER *dialog)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L102)

Frees up all resources used by the file dialog.


File: refman.info,  Node: al_show_native_message_box,  Next: al_open_native_text_log,  Prev: al_destroy_native_file_dialog,  Up: Native dialogs support

36.11 al_show_native_message_box
================================

int al_show_native_message_box(ALLEGRO_DISPLAY *display,
   char const *title, char const *heading, char const *text,
   char const *buttons, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L124)

Show a native GUI message box.  This can be used for example to display
an error message if creation of an initial display fails.  The display
may be NULL, otherwise the given display is treated as the parent if
possible.

The message box will have a single “OK” button and use the style
informative dialog boxes usually have on the native system.  If the
‘buttons’ parameter is not NULL, you can instead specify the button text
in a string, with buttons separated by a vertical bar (|).

     _Note:_ ‘buttons’ parameter is currently unimplemented on Windows.
The flags available are:

ALLEGRO_MESSAGEBOX_WARN

     The message is a warning.  This may cause a different icon (or
     other effects).
ALLEGRO_MESSAGEBOX_ERROR

     The message is an error.
ALLEGRO_MESSAGEBOX_QUESTION

     The message is a question.
ALLEGRO_MESSAGEBOX_OK_CANCEL

     Display a cancel button alongside the “OK” button.  Ignored if
     ‘buttons’ is not NULL.
ALLEGRO_MESSAGEBOX_YES_NO

     Display Yes/No buttons instead of the “OK” button.  Ignored if
     ‘buttons’ is not NULL.

*note al_show_native_message_box: #al_show_native_message_box. may be
called without Allegro being installed.  This is useful to report an
error during initialisation of Allegro itself.

Returns:

   • 0 if the dialog window was closed without activating a button.
   • 1 if the OK or Yes button was pressed.
   • 2 if the Cancel or No button was pressed.

If ‘buttons’ is not NULL, the number of the pressed button is returned,
starting with 1.

All of the remaining parameters must not be NULL.

If a message box could not be created then this returns 0, as if the
window was dismissed without activating a button.

Example:

int button = al_show_native_message_box(
  display,
  "Warning",
  "Are you sure?",
  "If you click yes then you are confirming that \"Yes\" "
  "is your response to the query which you have "
  "generated by the action you took to open this "
  "message box.",
  NULL,
  ALLEGRO_MESSAGEBOX_YES_NO
);


File: refman.info,  Node: al_open_native_text_log,  Next: al_close_native_text_log,  Prev: al_show_native_message_box,  Up: Native dialogs support

36.12 al_open_native_text_log
=============================

ALLEGRO_TEXTLOG *al_open_native_text_log(char const *title, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/textlog.c#L39)

Opens a window to which you can append log messages with *note
al_append_native_text_log: #al_append_native_text_log.  This can be
useful for debugging if you don’t want to depend on a console being
available.

Use *note al_close_native_text_log: #al_close_native_text_log. to close
the window again.

The flags available are:

ALLEGRO_TEXTLOG_NO_CLOSE

     Prevent the window from having a close button.  Otherwise, if the
     close button is pressed, an event is generated; see *note
     al_get_native_text_log_event_source:
     #al_get_native_text_log_event_source.
ALLEGRO_TEXTLOG_MONOSPACE

     Use a monospace font to display the text.

Returns NULL if there was an error opening the window, or if text log
windows are not implemented on the platform.

See also: *note al_append_native_text_log: #al_append_native_text_log,
*note al_close_native_text_log: #al_close_native_text_log.


File: refman.info,  Node: al_close_native_text_log,  Next: al_append_native_text_log,  Prev: al_open_native_text_log,  Up: Native dialogs support

36.13 al_close_native_text_log
==============================

void al_close_native_text_log(ALLEGRO_TEXTLOG *textlog)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/textlog.c#L92)

Closes a message log window opened with *note al_open_native_text_log:
#al_open_native_text_log. earlier.

Does nothing if passed NULL.

See also: *note al_open_native_text_log: #al_open_native_text_log.


File: refman.info,  Node: al_append_native_text_log,  Next: al_get_native_text_log_event_source,  Prev: al_close_native_text_log,  Up: Native dialogs support

36.14 al_append_native_text_log
===============================

void al_append_native_text_log(ALLEGRO_TEXTLOG *textlog,
   char const *format, ...)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/textlog.c#L135)

Appends a line of text to the message log window and scrolls to the
bottom (if the line would not be visible otherwise).  This works like
printf.  A line is continued until you add a newline character.

If the window is NULL then this function will fall back to calling
printf.  This makes it convenient to support logging to a window or a
terminal.


File: refman.info,  Node: al_get_native_text_log_event_source,  Next: al_get_allegro_native_dialog_version,  Prev: al_append_native_text_log,  Up: Native dialogs support

36.15 al_get_native_text_log_event_source
=========================================

ALLEGRO_EVENT_SOURCE *al_get_native_text_log_event_source(
   ALLEGRO_TEXTLOG *textlog)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/textlog.c#L164)

Get an event source for a text log window.  The possible events are:

ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE

     The window was requested to be closed, either by pressing the close
     button or pressing Escape on the keyboard.  The user.data1 field
     will hold a pointer to the *note ALLEGRO_TEXTLOG: #allegro_textlog.
     which generated the event.  The user.data2 field will be 1 if the
     event was generated as a result of a key press; otherwise it will
     be zero.


File: refman.info,  Node: al_get_allegro_native_dialog_version,  Next: Menus,  Prev: al_get_native_text_log_event_source,  Up: Native dialogs support

36.16 al_get_allegro_native_dialog_version
==========================================

uint32_t al_get_allegro_native_dialog_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/dialog.c#L162)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: Menus,  Prev: al_get_allegro_native_dialog_version,  Up: Native dialogs support

36.17 Menus
===========

Menus are implemented on Windows, X and OS X. Menus on X are implemented
with GTK, and have a special requirement: you must set the
ALLEGRO_GTK_TOPLEVEL display flag prior to creating the display which
will have menus attached.

A menu can be attached to a single display window or popped up as a
context menu.  If you wish to use the same menu on multiple displays or
use a sub-menu as a context menu, you must make a copy via *note
al_clone_menu: #al_clone_menu. or *note al_clone_menu_for_popup:
#al_clone_menu_for_popup.

Top level items in a non-popup menu must have at least one sub-item, or
the behavior is undefined.

Each menu item can be given an ID of any 16-bit integer greater than
zero.  When a user clicks on a menu item, an event will be generated
only if it has an ID. This ID should be unique per menu; if you
duplicate IDs, then there will be no way for you to determine exactly
which item generated the event.

There are many functions that take ‘pos’ as a parameter used for
locating a particular menu item.  In those cases, it represents one of
two things: an ID or a zero-based index.  Any value greater than zero
will always be treated as an ID. Anything else (including zero) will be
considered an index based on the absolute value.  In other words, 0 is
the first menu item, -1 is the second menu item, -2 is the third menu
item, and so on.

The event type is ‘ALLEGRO_EVENT_MENU_CLICK’.  It contains three fields:

event.user.data1 = id;
event.user.data2 = (intptr_t) display;
event.user.data3 = (intptr_t) menu;

The ‘display’ and ‘menu’ may be NULL if it was not possible to tell
exactly which item generated the event.

A basic example:

 #define FILE_EXIT_ID 1

ALLEGRO_MENU *menu = al_create_menu();
ALLEGRO_MENU *file_menu = al_create_menu();
al_append_menu_item(file_menu, "Exit", FILE_EXIT_ID, 0, NULL, NULL);
al_append_menu_item(menu, "File", 0, 0, NULL, file_menu);
al_set_display_menu(display, menu);

al_register_event_source(queue, al_get_default_menu_event_source());
al_wait_for_event(queue, &event);

if (event.type == ALLEGRO_EVENT_MENU_CLICK) {
   if (event.user.data1 == FILE_EXIT_ID) {
      exit_program();
   }
}

Because there is no “DISPLAY_DESTROYED” event, you must call
al_set_display_menu(display, NULL) before destroying any display with a
menu attached, to avoid leaking resources.

* Menu:

* ALLEGRO_MENU::
* ALLEGRO_MENU_INFO::
* al_create_menu::
* al_create_popup_menu::
* al_build_menu::
* al_append_menu_item::
* al_insert_menu_item::
* al_remove_menu_item::
* al_clone_menu::
* al_clone_menu_for_popup::
* al_destroy_menu::
* al_get_menu_item_caption::
* al_set_menu_item_caption::
* al_get_menu_item_flags::
* al_set_menu_item_flags::
* al_toggle_menu_item_flags::
* al_get_menu_item_icon::
* al_set_menu_item_icon::
* al_find_menu::
* al_find_menu_item::
* al_get_default_menu_event_source::
* al_enable_menu_event_source::
* al_disable_menu_event_source::
* al_get_display_menu::
* al_set_display_menu::
* al_popup_menu::
* al_remove_display_menu::


File: refman.info,  Node: ALLEGRO_MENU,  Next: ALLEGRO_MENU_INFO,  Up: Menus

36.17.1 ALLEGRO_MENU
--------------------

typedef struct ALLEGRO_MENU ALLEGRO_MENU;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/allegro5/allegro_native_dialog.h#L46)

An opaque data type that represents a menu that contains menu items.
Each of the menu items may optionally include a sub-menu.


File: refman.info,  Node: ALLEGRO_MENU_INFO,  Next: al_create_menu,  Prev: ALLEGRO_MENU,  Up: Menus

36.17.2 ALLEGRO_MENU_INFO
-------------------------

typedef struct ALLEGRO_MENU_INFO {

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/allegro5/allegro_native_dialog.h#L50)

A structure that defines how to create a complete menu system.  For
standard menu items, the following format is used:

   { caption, id, flags, icon }

For special items, these macros are helpful:

ALLEGRO_START_OF_MENU(caption, id)
ALLEGRO_MENU_SEPARATOR
ALLEGRO_END_OF_MENU

A well-defined menu will begin with ‘ALLEGRO_START_OF_MENU’, contain one
or more menu items, and end with ‘ALLEGRO_END_OF_MENU’.  A menu may
contain sub-menus.  An example:

ALLEGRO_MENU_INFO menu_info[] = {
   ALLEGRO_START_OF_MENU("&File", 1),
      { "&Open", 2, 0, NULL },
      ALLEGRO_START_OF_MENU("Open &Recent...", 3),
         { "Recent 1", 4, 0, NULL },
         { "Recent 2", 5, 0, NULL },
         ALLEGRO_END_OF_MENU,
      ALLEGRO_MENU_SEPARATOR,
      { "E&xit", 6, 0, NULL },
      ALLEGRO_END_OF_MENU,
   ALLEGRO_START_OF_MENU("&Help", 7),
      {"&About", 8, 0, NULL },
      ALLEGRO_END_OF_MENU,
   ALLEGRO_END_OF_MENU
};

ALLEGRO_MENU *menu = al_build_menu(menu_info);

If you prefer, you can build the menu without the structure by using
*note al_create_menu: #al_create_menu. and *note al_insert_menu_item:
#al_insert_menu_item.

See also: *note al_build_menu: #al_build_menu.


File: refman.info,  Node: al_create_menu,  Next: al_create_popup_menu,  Prev: ALLEGRO_MENU_INFO,  Up: Menus

36.17.3 al_create_menu
----------------------

ALLEGRO_MENU *al_create_menu(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L314)

Creates a menu container that can hold menu items.

Returns ‘NULL’ on failure.

Since: 5.1.0

See also: *note al_create_popup_menu: #al_create_popup_menu, *note
al_build_menu: #al_build_menu.


File: refman.info,  Node: al_create_popup_menu,  Next: al_build_menu,  Prev: al_create_menu,  Up: Menus

36.17.4 al_create_popup_menu
----------------------------

ALLEGRO_MENU *al_create_popup_menu(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L333)

Creates a menu container for popup menus.  Only the root (outermost)
menu should be created with this function.  Sub menus of popups should
be created with *note al_create_menu: #al_create_menu.

Returns ‘NULL’ on failure.

Since: 5.1.0

See also: *note al_create_menu: #al_create_menu, *note al_build_menu:
#al_build_menu.


File: refman.info,  Node: al_build_menu,  Next: al_append_menu_item,  Prev: al_create_popup_menu,  Up: Menus

36.17.5 al_build_menu
---------------------

ALLEGRO_MENU *al_build_menu(ALLEGRO_MENU_INFO *info)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L371)

Builds a menu based on the specifications of a sequence of
‘ALLEGRO_MENU_INFO’ elements.

Returns a pointer to the root ‘ALLEGRO_MENU’, or ‘NULL’ on failure.  To
gain access to the other menus and items, you will need to search for
them using *note al_find_menu_item: #al_find_menu_item.

Since: 5.1.0

See also: *note ALLEGRO_MENU_INFO: #allegro_menu_info, *note
al_create_menu: #al_create_menu, *note al_create_popup_menu:
#al_create_popup_menu.


File: refman.info,  Node: al_append_menu_item,  Next: al_insert_menu_item,  Prev: al_build_menu,  Up: Menus

36.17.6 al_append_menu_item
---------------------------

int al_append_menu_item(ALLEGRO_MENU *parent, char const *title, uint16_t id,
   int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L383)

Appends a menu item to the end of the menu.  See *note
al_insert_menu_item: #al_insert_menu_item. for more information.

Since: 5.1.0

See also: *note al_insert_menu_item: #al_insert_menu_item, *note
al_remove_menu_item: #al_remove_menu_item.


File: refman.info,  Node: al_insert_menu_item,  Next: al_remove_menu_item,  Prev: al_append_menu_item,  Up: Menus

36.17.7 al_insert_menu_item
---------------------------

int al_insert_menu_item(ALLEGRO_MENU *parent, int pos, char const *title,
   uint16_t id, int flags, ALLEGRO_BITMAP *icon, ALLEGRO_MENU *submenu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L395)

Inserts a menu item at the spot specified.  See the introductory text
for a detailed explanation of how the ‘pos’ parameter is interpreted.

The ‘parent’ menu can be a popup menu or a regular menu.  To underline
one character in the ‘title’, prefix it with an ampersand.

The ‘flags’ can be any combination of:

ALLEGRO_MENU_ITEM_DISABLED

     The item is “grayed out” and cannot be selected.
ALLEGRO_MENU_ITEM_CHECKBOX

     The item is a check box.  This flag can only be set at the time the
     menu is created.  If a check box is clicked, it will automatically
     be toggled.
ALLEGRO_MENU_ITEM_CHECKED

     The item is checked.  If set, ALLEGRO_MENU_ITEM_CHECKBOX will
     automatically be set as well.

The ‘icon’ is not yet supported.

The ‘submenu’ parameter indicates that this item contains a child menu.
The child menu must have previously been created with ‘al_create_menu’,
and not be associated with any other menu.

Returns ‘true’ on success.

Since: 5.1.0

See also: *note al_append_menu_item: #al_append_menu_item, *note
al_remove_menu_item: #al_remove_menu_item.


File: refman.info,  Node: al_remove_menu_item,  Next: al_clone_menu,  Prev: al_insert_menu_item,  Up: Menus

36.17.8 al_remove_menu_item
---------------------------

bool al_remove_menu_item(ALLEGRO_MENU *menu, int pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L462)

Removes the specified item from the menu and destroys it.  If the item
contains a sub-menu, it too is destroyed.  Any references to it are
invalidated.  If you want to preserve that sub-menu, you should first
make a copy with *note al_clone_menu: #al_clone_menu.

This is safe to call on a menu that is currently being displayed.

Returns ‘true’ if an item was removed.

Since: 5.1.0

See also: *note al_append_menu_item: #al_append_menu_item, *note
al_insert_menu_item: #al_insert_menu_item, *note al_destroy_menu:
#al_destroy_menu.


File: refman.info,  Node: al_clone_menu,  Next: al_clone_menu_for_popup,  Prev: al_remove_menu_item,  Up: Menus

36.17.9 al_clone_menu
---------------------

ALLEGRO_MENU *al_clone_menu(ALLEGRO_MENU *menu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L357)

Makes a copy of a menu so that it can be reused on another display.  The
menu being cloned can be anything: a regular menu, a popup menu, or a
sub-menu.

Returns the cloned menu.

Since: 5.1.0

See also: *note al_clone_menu_for_popup: #al_clone_menu_for_popup.


File: refman.info,  Node: al_clone_menu_for_popup,  Next: al_destroy_menu,  Prev: al_clone_menu,  Up: Menus

36.17.10 al_clone_menu_for_popup
--------------------------------

ALLEGRO_MENU *al_clone_menu_for_popup(ALLEGRO_MENU *menu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L364)

Exactly like *note al_clone_menu: #al_clone_menu, except that the copy
is for a popup menu.

Since: 5.1.0

See also: *note al_clone_menu: #al_clone_menu.


File: refman.info,  Node: al_destroy_menu,  Next: al_get_menu_item_caption,  Prev: al_clone_menu_for_popup,  Up: Menus

36.17.11 al_destroy_menu
------------------------

void al_destroy_menu(ALLEGRO_MENU *menu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L666)

Destroys an entire menu, including its sub-menus.  Any references to it
or a sub-menu are no longer valid.  It is safe to call this on a menu
that is currently being displayed.

Since: 5.1.0

See also: *note al_remove_menu_item: #al_remove_menu_item.


File: refman.info,  Node: al_get_menu_item_caption,  Next: al_set_menu_item_caption,  Prev: al_destroy_menu,  Up: Menus

36.17.12 al_get_menu_item_caption
---------------------------------

const char *al_get_menu_item_caption(ALLEGRO_MENU *menu, int pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L539)

Returns the caption associated with the menu item.  It is valid as long
as the caption is not modified.

Returns ‘NULL’ if the item was not found.

Since: 5.1.0

See also: *note al_set_menu_item_caption: #al_set_menu_item_caption.


File: refman.info,  Node: al_set_menu_item_caption,  Next: al_get_menu_item_flags,  Prev: al_get_menu_item_caption,  Up: Menus

36.17.13 al_set_menu_item_caption
---------------------------------

void al_set_menu_item_caption(ALLEGRO_MENU *menu, int pos, const char *caption)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L552)

Updates the menu item caption with the new ‘caption’.  This will
invalidate any previous calls to *note al_get_menu_item_caption:
#al_get_menu_item_caption.

Since: 5.1.0

See also: *note al_get_menu_item_caption: #al_get_menu_item_caption.


File: refman.info,  Node: al_get_menu_item_flags,  Next: al_set_menu_item_flags,  Prev: al_set_menu_item_caption,  Up: Menus

36.17.14 al_get_menu_item_flags
-------------------------------

int al_get_menu_item_flags(ALLEGRO_MENU *menu, int pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L569)

Returns the currently set flags.  See *note al_insert_menu_item:
#al_insert_menu_item. for a description of the available flags.

Returns -1 if the item was not found.

Since: 5.1.0

See also: *note al_set_menu_item_flags: #al_set_menu_item_flags, *note
al_toggle_menu_item_flags: #al_toggle_menu_item_flags.


File: refman.info,  Node: al_set_menu_item_flags,  Next: al_toggle_menu_item_flags,  Prev: al_get_menu_item_flags,  Up: Menus

36.17.15 al_set_menu_item_flags
-------------------------------

void al_set_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L581)

Updates the menu item’s flags.  See *note al_insert_menu_item:
#al_insert_menu_item. for a description of the available flags.

Since: 5.1.0

See also: *note al_get_menu_item_flags: #al_get_menu_item_flags, *note
al_toggle_menu_item_flags: #al_toggle_menu_item_flags.


File: refman.info,  Node: al_toggle_menu_item_flags,  Next: al_get_menu_item_icon,  Prev: al_set_menu_item_flags,  Up: Menus

36.17.16 al_toggle_menu_item_flags
----------------------------------

int al_toggle_menu_item_flags(ALLEGRO_MENU *menu, int pos, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L607)

Toggles the specified menu item’s flags.  See *note al_insert_menu_item:
#al_insert_menu_item. for a description of the available flags.

Returns a bitfield of only the specified flags that are set after the
toggle.  A flag that was not toggled will not be returned, even if it is
set.  Returns -1 if the id is invalid.

Since: 5.1.0

     _*note Unstable API: #unstable-api.:_ Redundant with
     ‘al_get/set_menu_item_flags’.
See also: *note al_get_menu_item_flags: #al_get_menu_item_flags, *note
al_set_menu_item_flags: #al_set_menu_item_flags.


File: refman.info,  Node: al_get_menu_item_icon,  Next: al_set_menu_item_icon,  Prev: al_toggle_menu_item_flags,  Up: Menus

36.17.17 al_get_menu_item_icon
------------------------------

ALLEGRO_BITMAP *al_get_menu_item_icon(ALLEGRO_MENU *menu, int pos)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L634)

Returns the icon associated with the menu.  It is safe to draw to the
returned bitmap, but you must call *note al_set_menu_item_icon:
#al_set_menu_item_icon. in order for the changes to be applied.

Returns ‘NULL’ if the item was not found or if it has no icon.

Since: 5.1.0

See also: *note al_set_menu_item_icon: #al_set_menu_item_icon.


File: refman.info,  Node: al_set_menu_item_icon,  Next: al_find_menu,  Prev: al_get_menu_item_icon,  Up: Menus

36.17.18 al_set_menu_item_icon
------------------------------

void al_set_menu_item_icon(ALLEGRO_MENU *menu, int pos, ALLEGRO_BITMAP *icon)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L647)

Sets the icon for the specified menu item.  The menu assumes ownership
of the ‘ALLEGRO_BITMAP’ and may invalidate the pointer, so you must
clone it if you wish to continue using it.

If a video bitmap is passed, it will automatically be converted to a
memory bitmap, so it is preferable to pass a memory bitmap.

Since: 5.1.0

See also: *note al_get_menu_item_icon: #al_get_menu_item_icon, *note
al_clone_bitmap: #al_clone_bitmap.


File: refman.info,  Node: al_find_menu,  Next: al_find_menu_item,  Prev: al_set_menu_item_icon,  Up: Menus

36.17.19 al_find_menu
---------------------

ALLEGRO_MENU *al_find_menu(ALLEGRO_MENU *haystack, uint16_t id)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L479)

Searches in the ‘haystack’ menu for any submenu with the given ‘id’.
(Note that this only represents a literal ID, and cannot be used as an
index.)

Returns the menu, if found.  Otherwise returns ‘NULL’.

Since: 5.1.0

See also: *note al_find_menu_item: #al_find_menu_item.


File: refman.info,  Node: al_find_menu_item,  Next: al_get_default_menu_event_source,  Prev: al_find_menu,  Up: Menus

36.17.20 al_find_menu_item
--------------------------

bool al_find_menu_item(ALLEGRO_MENU *haystack, uint16_t id, ALLEGRO_MENU **menu,
   int *index)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L489)

Searches in the ‘haystack’ menu for an item with the given ‘id’.  (Note
that this only represents a literal ID, and cannot be used as an index.)

If ‘menu’ and ‘index’ are not ‘NULL’, they will be set as the parent
menu containing the item and the zero-based (positive) index of the
item.  (If the menu item was not found, then their values are
undefined.)

Returns true if the menu item was found.

Since: 5.1.0

See also: *note al_find_menu: #al_find_menu.


File: refman.info,  Node: al_get_default_menu_event_source,  Next: al_enable_menu_event_source,  Prev: al_find_menu_item,  Up: Menus

36.17.21 al_get_default_menu_event_source
-----------------------------------------

ALLEGRO_EVENT_SOURCE *al_get_default_menu_event_source(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L709)

Returns the default event source used for menu clicks.  If a menu was
not given its own event source via *note al_enable_menu_event_source:
#al_enable_menu_event_source, then it will use this default source.

Since: 5.1.0

See also: *note al_register_event_source: #al_register_event_source,
*note al_enable_menu_event_source: #al_enable_menu_event_source, *note
al_disable_menu_event_source: #al_disable_menu_event_source.


File: refman.info,  Node: al_enable_menu_event_source,  Next: al_disable_menu_event_source,  Prev: al_get_default_menu_event_source,  Up: Menus

36.17.22 al_enable_menu_event_source
------------------------------------

ALLEGRO_EVENT_SOURCE *al_enable_menu_event_source(ALLEGRO_MENU *menu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L716)

Enables a unique event source for this menu.  It and all of its
sub-menus will use this event source.  (It is safe to call this multiple
times on the same menu.)

Returns the event source.

Since: 5.1.0

See also: *note al_register_event_source: #al_register_event_source,
*note al_get_default_menu_event_source:
#al_get_default_menu_event_source, *note al_disable_menu_event_source:
#al_disable_menu_event_source.


File: refman.info,  Node: al_disable_menu_event_source,  Next: al_get_display_menu,  Prev: al_enable_menu_event_source,  Up: Menus

36.17.23 al_disable_menu_event_source
-------------------------------------

void al_disable_menu_event_source(ALLEGRO_MENU *menu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L730)

Disables a unique event source for the menu, causing it to use the
default event source.

Since: 5.1.0

See also: *note al_get_default_menu_event_source:
#al_get_default_menu_event_source, *note al_enable_menu_event_source:
#al_enable_menu_event_source.


File: refman.info,  Node: al_get_display_menu,  Next: al_set_display_menu,  Prev: al_disable_menu_event_source,  Up: Menus

36.17.24 al_get_display_menu
----------------------------

ALLEGRO_MENU *al_get_display_menu(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L742)

Returns the menu associated with the ‘display’, or ‘NULL’ if it does not
have a menu.

Since: 5.1.0

See also: *note al_set_display_menu: #al_set_display_menu.


File: refman.info,  Node: al_set_display_menu,  Next: al_popup_menu,  Prev: al_get_display_menu,  Up: Menus

36.17.25 al_set_display_menu
----------------------------

bool al_set_display_menu(ALLEGRO_DISPLAY *display, ALLEGRO_MENU *menu)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L760)

Associates the ‘menu’ with the ‘display’ and shows it.  If there was a
previous menu associated with the display, it will be destroyed.  If you
don’t want that to happen, you should first remove the menu with *note
al_remove_display_menu: #al_remove_display_menu.

If the menu is already attached to a display, it will not be attached to
the new display.  If ‘menu’ is ‘NULL’, the current menu will still be
destroyed.

     _Note:_ Attaching a menu may cause the window as available to your
     application to be resized!  You should listen for a resize event,
     check how much space was lost, and resize the window accordingly if
     you want to maintain your window’s prior size.
Returns true if successful.

Since: 5.1.0

See also: *note al_create_menu: #al_create_menu, *note
al_remove_display_menu: #al_remove_display_menu.


File: refman.info,  Node: al_popup_menu,  Next: al_remove_display_menu,  Prev: al_set_display_menu,  Up: Menus

36.17.26 al_popup_menu
----------------------

bool al_popup_menu(ALLEGRO_MENU *popup, ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L843)

Displays a context menu next to the mouse cursor.  The menu must have
been created with *note al_create_popup_menu: #al_create_popup_menu.  It
generates events just like a regular display menu does.  It is possible
that the menu will be canceled without any selection being made.

The ‘display’ parameter indicates which window the menu is associated
with (when you process the menu click event), but does not actually
affect where the menu is located on the screen.

Returns ‘true’ if the context menu was displayed.

     _Note:_ On Linux this function will fail if any of the mouse keys
     are held down.  I.e.  it will only reliably work if you handle it
     in ‘ALLEGRO_MOUSE_BUTTON_UP’ events and even then only if that
     event corresponds to the final mouse button that was pressed.
Since: 5.1.0

See also: *note al_create_popup_menu: #al_create_popup_menu.


File: refman.info,  Node: al_remove_display_menu,  Prev: al_popup_menu,  Up: Menus

36.17.27 al_remove_display_menu
-------------------------------

ALLEGRO_MENU *al_remove_display_menu(ALLEGRO_DISPLAY *display)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/native_dialog/menu.c#L867)

Detaches the menu associated with the display and returns it.  The menu
can then be used on a different display.

If you simply want to destroy the active menu, you can call *note
al_set_display_menu: #al_set_display_menu. with a ‘NULL’ menu.

Since: 5.1.0

See also: *note al_set_display_menu: #al_set_display_menu.


File: refman.info,  Node: PhysicsFS integration,  Next: Primitives addon,  Prev: Native dialogs support,  Up: Top

37 PhysicsFS integration
************************

PhysicsFS is a library to provide abstract access to various archives.
See <http://icculus.org/physfs/> for more information.

This addon makes it possible to read and write files (on disk or inside
archives) using PhysicsFS, through Allegro’s file I/O API. For example,
that means you can use the Image I/O addon to load images from .zip
files.

You must set up PhysicsFS through its own API. When you want to open an
ALLEGRO_FILE using PhysicsFS, first call *note
al_set_physfs_file_interface: #al_set_physfs_file_interface, then *note
al_fopen: #al_fopen. or another function that calls *note al_fopen:
#al_fopen.

These functions are declared in the following header file.  Link with
allegro_physfs.

 #include <allegro5/allegro_physfs.h>

* Menu:

* al_set_physfs_file_interface::
* al_get_allegro_physfs_version::


File: refman.info,  Node: al_set_physfs_file_interface,  Next: al_get_allegro_physfs_version,  Up: PhysicsFS integration

37.1 al_set_physfs_file_interface
=================================

void al_set_physfs_file_interface(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/physfs/a5_physfs.c#L301)

This function sets _both_ the *note ALLEGRO_FILE_INTERFACE:
#allegro_file_interface. and *note ALLEGRO_FS_INTERFACE:
#allegro_fs_interface. for the calling thread.

Subsequent calls to *note al_fopen: #al_fopen. on the calling thread
will be handled by PHYSFS_open().  Operations on the files returned by
*note al_fopen: #al_fopen. will then be performed through PhysicsFS.
Calls to the Allegro filesystem functions, such as *note
al_read_directory: #al_read_directory. or *note al_create_fs_entry:
#al_create_fs_entry, on the calling thread will be diverted to
PhysicsFS.

To remember and restore another file I/O backend, you can use *note
al_store_state: #al_store_state./*note al_restore_state:
#al_restore_state.

     _Note:_ due to an oversight, this function differs from *note
     al_set_new_file_interface: #al_set_new_file_interface. and *note
     al_set_standard_file_interface: #al_set_standard_file_interface.
     which only alter the current *note ALLEGRO_FILE_INTERFACE:
     #allegro_file_interface.
     _Note:_ PhysFS does not support the text-mode reading and writing,
     which means that Windows-style newlines will not be preserved.
See also: *note al_set_new_file_interface: #al_set_new_file_interface.


File: refman.info,  Node: al_get_allegro_physfs_version,  Prev: al_set_physfs_file_interface,  Up: PhysicsFS integration

37.2 al_get_allegro_physfs_version
==================================

uint32_t al_get_allegro_physfs_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/physfs/a5_physfs.c#L310)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: Primitives addon,  Next: Shader routines,  Prev: PhysicsFS integration,  Up: Top

38 Primitives addon
*******************

These functions are declared in the following header file.  Link with
allegro_primitives.

 #include <allegro5/allegro_primitives.h>

* Menu:

* General::
* High level drawing routines::
* Low level drawing routines::
* Custom vertex declaration routines::
* Vertex buffer routines::
* Index buffer routines::
* Polygon routines::
* Structures and types::


File: refman.info,  Node: General,  Next: High level drawing routines,  Up: Primitives addon

38.1 General
============

* Menu:

* al_get_allegro_primitives_version::
* al_init_primitives_addon::
* al_is_primitives_addon_initialized::
* al_shutdown_primitives_addon::


File: refman.info,  Node: al_get_allegro_primitives_version,  Next: al_init_primitives_addon,  Up: General

38.1.1 al_get_allegro_primitives_version
----------------------------------------

uint32_t al_get_allegro_primitives_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L160)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.


File: refman.info,  Node: al_init_primitives_addon,  Next: al_is_primitives_addon_initialized,  Prev: al_get_allegro_primitives_version,  Up: General

38.1.2 al_init_primitives_addon
-------------------------------

bool al_init_primitives_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L48)

Initializes the primitives addon.

_Returns:_ True on success, false on failure.

See also: *note al_shutdown_primitives_addon:
#al_shutdown_primitives_addon.


File: refman.info,  Node: al_is_primitives_addon_initialized,  Next: al_shutdown_primitives_addon,  Prev: al_init_primitives_addon,  Up: General

38.1.3 al_is_primitives_addon_initialized
-----------------------------------------

bool al_is_primitives_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L62)

Returns true if the primitives addon is initialized, otherwise returns
false.

Since: 5.2.6

See also: *note al_init_primitives_addon: #al_init_primitives_addon,
*note al_shutdown_primitives_addon: #al_shutdown_primitives_addon.


File: refman.info,  Node: al_shutdown_primitives_addon,  Prev: al_is_primitives_addon_initialized,  Up: General

38.1.4 al_shutdown_primitives_addon
-----------------------------------

void al_shutdown_primitives_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L69)

Shut down the primitives addon.  This is done automatically at program
exit, but can be called any time the user wishes as well.

See also: *note al_init_primitives_addon: #al_init_primitives_addon.


File: refman.info,  Node: High level drawing routines,  Next: Low level drawing routines,  Prev: General,  Up: Primitives addon

38.2 High level drawing routines
================================

High level drawing routines encompass the most common usage of this
addon: to draw geometric primitives, both smooth (variations on the
circle theme) and piecewise linear.  Outlined primitives support the
concept of thickness with two distinct modes of output: hairline lines
and thick lines.  Hairline lines are specifically designed to be exactly
a pixel wide, and are commonly used for drawing outlined figures that
need to be a pixel wide.  Hairline thickness is designated as thickness
less than or equal to 0.  Unfortunately, the exact rasterization rules
for drawing these hairline lines vary from one video card to another,
and sometimes leave gaps where the lines meet.  If that matters to you,
then you should use thick lines.  In many cases, having a thickness of 1
will produce 1 pixel wide lines that look better than hairline lines.
Obviously, hairline lines cannot replicate thicknesses greater than 1.
Thick lines grow symmetrically around the generating shape as thickness
is increased.

* Menu:

* Pixel-precise output::
* al_draw_line::
* al_draw_triangle::
* al_draw_filled_triangle::
* al_draw_rectangle::
* al_draw_filled_rectangle::
* al_draw_rounded_rectangle::
* al_draw_filled_rounded_rectangle::
* al_calculate_arc::
* al_draw_pieslice::
* al_draw_filled_pieslice::
* al_draw_ellipse::
* al_draw_filled_ellipse::
* al_draw_circle::
* al_draw_filled_circle::
* al_draw_arc::
* al_draw_elliptical_arc::
* al_calculate_spline::
* al_draw_spline::
* al_calculate_ribbon::
* al_draw_ribbon::


File: refman.info,  Node: Pixel-precise output,  Next: al_draw_line,  Up: High level drawing routines

38.2.1 Pixel-precise output
---------------------------

While normally you should not be too concerned with which pixels are
displayed when the high level primitives are drawn, it is nevertheless
possible to control that precisely by carefully picking the coordinates
at which you draw those primitives.

To be able to do that, however, it is critical to understand how GPU
cards convert shapes to pixels.  Pixels are not the smallest unit that
can be addressed by the GPU. Because the GPU deals with floating point
coordinates, it can in fact assign different coordinates to different
parts of a single pixel.  To a GPU, thus, a screen is composed of a grid
of squares that have width and length of 1.  The top left corner of the
top left pixel is located at (0, 0).  Therefore, the center of that
pixel is at (0.5, 0.5).  The basic rule that determines which pixels are
associated with which shape is then as follows: a pixel is treated to
belong to a shape if the pixel’s center is located in that shape.  The
figure below illustrates the above concepts:

[Diagram showing a how pixel output is
calculated by the GPU given the mathematical description of several
shapes.]


_Diagram showing a how pixel output is calculated by the GPU given the
mathematical description of several shapes._
This figure depicts three shapes drawn at the top left of the screen: an
orange and green rectangles and a purple circle.  On the left are the
mathematical descriptions of pixels on the screen and the shapes to be
drawn.  On the right is the screen output.  Only a single pixel has its
center inside the circle, and therefore only a single pixel is drawn on
the screen.  Similarly, two pixels are drawn for the orange rectangle.
Since there are no pixels that have their centers inside the green
rectangle, the output image has no green pixels.

Here is a more practical example.  The image below shows the output of
this code:

/* blue vertical line */
al_draw_line(0.5, 0, 0.5, 6, color_blue, 1);
/* red horizontal line */
al_draw_line(2, 1, 6, 1, color_red, 2);
/* green filled rectangle */
al_draw_filled_rectangle(3, 4, 5, 5, color_green);
/* purple outlined rectangle */
al_draw_rectangle(2.5, 3.5, 5.5, 5.5, color_purple, 1);

[Diagram showing a practical example of
pixel output resulting from the invocation of several primitives addon
functions.]


_Diagram showing a practical example of pixel output resulting from the
invocation of several primitives addon functions._
It can be seen that lines are generated by making a rectangle based on
the dashed line between the two endpoints.  The thickness causes the
rectangle to grow symmetrically about that generating line, as can be
seen by comparing the red and blue lines.  Note that to get proper pixel
coverage, the coordinates passed to the ‘al_draw_line’ had to be offset
by 0.5 in the appropriate dimensions.

Filled rectangles are generated by making a rectangle between the
endpoints passed to the ‘al_draw_filled_rectangle’.

Outlined rectangles are generated by symmetrically expanding an outline
of a rectangle.  With a thickness of 1, as depicted in the diagram, this
means that an offset of 0.5 is needed for both sets of endpoint
coordinates to exactly line up with the pixels of the display raster.

The above rules only apply when multisampling is turned off.  When
multisampling is turned on, the area of a pixel that is covered by a
shape is taken into account when choosing what color to draw there.
This also means that shapes no longer have to contain the pixel’s center
to affect its color.  For example, the green rectangle in the first
diagram may in fact be drawn as two (or one) semi-transparent pixels.
The advantages of multisampling is that slanted shapes will look
smoother because they will not have jagged edges.  A disadvantage of
multisampling is that it may make vertical and horizontal edges blurry.
While the exact rules for multisampling are unspecified, and may vary
from GPU to GPU, it is usually safe to assume that as long as a pixel is
either completely covered by a shape or completely not covered, then the
shape edges will be sharp.  The offsets used in the second diagram were
chosen so that this is the case: if you use those offsets, your shapes
(if they are oriented the same way as they are on the diagram) should
look the same whether multisampling is turned on or off.


File: refman.info,  Node: al_draw_line,  Next: al_draw_triangle,  Prev: Pixel-precise output,  Up: High level drawing routines

38.2.2 al_draw_line
-------------------

void al_draw_line(float x1, float y1, float x2, float y2,
   ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L81)

Draws a line segment between two points.

_Parameters:_

   • x1, y1, x2, y2 - Start and end points of the line
   • color - Color of the line
   • thickness - Thickness of the line, pass ‘<= 0’ to draw hairline
     lines

See also: *note al_draw_soft_line: #al_draw_soft_line.


File: refman.info,  Node: al_draw_triangle,  Next: al_draw_filled_triangle,  Prev: al_draw_line,  Up: High level drawing routines

38.2.3 al_draw_triangle
-----------------------

void al_draw_triangle(float x1, float y1, float x2, float y2,
   float x3, float y3, ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L126)

Draws an outlined triangle.

_Parameters:_

   • x1, y1, x2, y2, x3, y3 - Three points of the triangle
   • color - Color of the triangle
   • thickness - Thickness of the lines, pass ‘<= 0’ to draw hairline
     lines

See also: *note al_draw_filled_triangle: #al_draw_filled_triangle, *note
al_draw_soft_triangle: #al_draw_soft_triangle.


File: refman.info,  Node: al_draw_filled_triangle,  Next: al_draw_rectangle,  Prev: al_draw_triangle,  Up: High level drawing routines

38.2.4 al_draw_filled_triangle
------------------------------

void al_draw_filled_triangle(float x1, float y1, float x2, float y2,
   float x3, float y3, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L339)

Draws a filled triangle.

_Parameters:_

   • x1, y1, x2, y2, x3, y3 - Three points of the triangle
   • color - Color of the triangle

See also: *note al_draw_triangle: #al_draw_triangle.


File: refman.info,  Node: al_draw_rectangle,  Next: al_draw_filled_rectangle,  Prev: al_draw_filled_triangle,  Up: High level drawing routines

38.2.5 al_draw_rectangle
------------------------

void al_draw_rectangle(float x1, float y1, float x2, float y2,
   ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L361)

Draws an outlined rectangle.

_Parameters:_

   • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
   • color - Color of the rectangle
   • thickness - Thickness of the lines, pass ‘<= 0’ to draw hairline
     lines

See also: *note al_draw_filled_rectangle: #al_draw_filled_rectangle,
*note al_draw_rounded_rectangle: #al_draw_rounded_rectangle.


File: refman.info,  Node: al_draw_filled_rectangle,  Next: al_draw_rounded_rectangle,  Prev: al_draw_rectangle,  Up: High level drawing routines

38.2.6 al_draw_filled_rectangle
-------------------------------

void al_draw_filled_rectangle(float x1, float y1, float x2, float y2,
   ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L406)

Draws a filled rectangle.

_Parameters:_

   • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
   • color - Color of the rectangle

See also: *note al_draw_rectangle: #al_draw_rectangle, *note
al_draw_filled_rounded_rectangle: #al_draw_filled_rounded_rectangle.


File: refman.info,  Node: al_draw_rounded_rectangle,  Next: al_draw_filled_rounded_rectangle,  Prev: al_draw_filled_rectangle,  Up: High level drawing routines

38.2.7 al_draw_rounded_rectangle
--------------------------------

void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2,
   float rx, float ry, ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L855)

Draws an outlined rounded rectangle.

_Parameters:_

   • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
   • color - Color of the rectangle
   • rx, ry - The radii of the round
   • thickness - Thickness of the lines, pass ‘<= 0’ to draw hairline
     lines

See also: *note al_draw_filled_rounded_rectangle:
#al_draw_filled_rounded_rectangle, *note al_draw_rectangle:
#al_draw_rectangle.


File: refman.info,  Node: al_draw_filled_rounded_rectangle,  Next: al_calculate_arc,  Prev: al_draw_rounded_rectangle,  Up: High level drawing routines

38.2.8 al_draw_filled_rounded_rectangle
---------------------------------------

void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2,
   float rx, float ry, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L953)

Draws an filled rounded rectangle.

_Parameters:_

   • x1, y1, x2, y2 - Upper left and lower right points of the rectangle
   • color - Color of the rectangle
   • rx, ry - The radii of the round

See also: *note al_draw_rounded_rectangle: #al_draw_rounded_rectangle,
*note al_draw_filled_rectangle: #al_draw_filled_rectangle.


File: refman.info,  Node: al_calculate_arc,  Next: al_draw_pieslice,  Prev: al_draw_filled_rounded_rectangle,  Up: High level drawing routines

38.2.9 al_calculate_arc
-----------------------

void al_calculate_arc(float* dest, int stride, float cx, float cy,
   float rx, float ry, float start_theta, float delta_theta, float thickness,
   int num_points)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L427)

When ‘thickness <= 0’ this function computes positions of ‘num_points’
regularly spaced points on an elliptical arc.  When ‘thickness > 0’ this
function computes two sets of points, obtained as follows: the first set
is obtained by taking the points computed in the ‘thickness <= 0’ case
and shifting them by ‘thickness / 2’ outward, in a direction
perpendicular to the arc curve.  The second set is the same, but shifted
‘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 ‘stride’.  For example, if you have a
tightly packed array of floats with no spaces between pairs, then
‘stride’ will be exactly ‘2 * sizeof(float)’.

Example with ‘thickness <= 0’:

const int num_points = 4;
float points[num_points][2];
al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 0, num_points);

assert((int)points[0][0] == 10);
assert((int)points[0][1] == 0);

assert((int)points[num_points - 1][0] == 0);
assert((int)points[num_points - 1][1] == 10);

Example with ‘thickness > 0’:

const int num_points = 4;
float points[num_points * 2][2];
al_calculate_arc(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 2, num_points);

assert((int)points[0][0] == 11);
assert((int)points[0][1] == 0);
assert((int)points[1][0] == 9);
assert((int)points[1][1] == 0);

assert((int)points[(num_points - 1) * 2][0] == 0);
assert((int)points[(num_points - 1) * 2][1] == 11);
assert((int)points[(num_points - 1) * 2 + 1][0] == 0);
assert((int)points[(num_points - 1) * 2 + 1][1] == 9);

_Parameters:_

   • dest - The destination buffer
   • stride - Distance (in bytes) between starts of successive pairs of
     points
   • cx, cy - Center of the arc
   • rx, ry - Radii of the arc
   • start_theta - The initial angle from which the arc is calculated in
     radians
   • delta_theta - Angular span of the arc in radians (pass a negative
     number to switch direction)
   • thickness - Thickness of the arc
   • num_points - The number of points to calculate

See also: *note al_draw_arc: #al_draw_arc, *note al_calculate_spline:
#al_calculate_spline, *note al_calculate_ribbon: #al_calculate_ribbon.


File: refman.info,  Node: al_draw_pieslice,  Next: al_draw_filled_pieslice,  Prev: al_calculate_arc,  Up: High level drawing routines

38.2.10 al_draw_pieslice
------------------------

void al_draw_pieslice(float cx, float cy, float r, float start_theta,
   float delta_theta, ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L508)

Draws a pieslice (outlined circular sector).

_Parameters:_

   • cx, cy - Center of the pieslice
   • r - Radius of the pieslice
   • color - Color of the pieslice
   • start_theta - The initial angle from which the pieslice is drawn in
     radians
   • delta_theta - Angular span of the pieslice in radians (pass a
     negative number to switch direction)
   • thickness - Thickness of the circle, pass ‘<= 0’ to draw hairline
     pieslice

Since: 5.0.6, 5.1.0

See also: *note al_draw_filled_pieslice: #al_draw_filled_pieslice.


File: refman.info,  Node: al_draw_filled_pieslice,  Next: al_draw_ellipse,  Prev: al_draw_pieslice,  Up: High level drawing routines

38.2.11 al_draw_filled_pieslice
-------------------------------

void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta,
   float delta_theta, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L664)

Draws a filled pieslice (filled circular sector).

_Parameters:_

   • cx, cy - Center of the pieslice
   • r - Radius of the pieslice
   • color - Color of the pieslice
   • start_theta - The initial angle from which the pieslice is drawn in
     radians
   • delta_theta - Angular span of the pieslice in radians (pass a
     negative number to switch direction)

Since: 5.0.6, 5.1.0

See also: *note al_draw_pieslice: #al_draw_pieslice.


File: refman.info,  Node: al_draw_ellipse,  Next: al_draw_filled_ellipse,  Prev: al_draw_filled_pieslice,  Up: High level drawing routines

38.2.12 al_draw_ellipse
-----------------------

void al_draw_ellipse(float cx, float cy, float rx, float ry,
   ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L695)

Draws an outlined ellipse.

_Parameters:_

   • cx, cy - Center of the ellipse
   • rx, ry - Radii of the ellipse
   • color - Color of the ellipse
   • thickness - Thickness of the ellipse, pass ‘<= 0’ to draw a
     hairline ellipse

See also: *note al_draw_filled_ellipse: #al_draw_filled_ellipse, *note
al_draw_circle: #al_draw_circle.


File: refman.info,  Node: al_draw_filled_ellipse,  Next: al_draw_circle,  Prev: al_draw_ellipse,  Up: High level drawing routines

38.2.13 al_draw_filled_ellipse
------------------------------

void al_draw_filled_ellipse(float cx, float cy, float rx, float ry,
   ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L747)

Draws a filled ellipse.

_Parameters:_

   • cx, cy - Center of the ellipse
   • rx, ry - Radii of the ellipse
   • color - Color of the ellipse

See also: *note al_draw_ellipse: #al_draw_ellipse, *note
al_draw_filled_circle: #al_draw_filled_circle.


File: refman.info,  Node: al_draw_circle,  Next: al_draw_filled_circle,  Prev: al_draw_filled_ellipse,  Up: High level drawing routines

38.2.14 al_draw_circle
----------------------

void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color,
   float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L782)

Draws an outlined circle.

_Parameters:_

   • cx, cy - Center of the circle
   • r - Radius of the circle
   • color - Color of the circle
   • thickness - Thickness of the circle, pass ‘<= 0’ to draw a hairline
     circle

See also: *note al_draw_filled_circle: #al_draw_filled_circle, *note
al_draw_ellipse: #al_draw_ellipse.


File: refman.info,  Node: al_draw_filled_circle,  Next: al_draw_arc,  Prev: al_draw_circle,  Up: High level drawing routines

38.2.15 al_draw_filled_circle
-----------------------------

void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L790)

Draws a filled circle.

_Parameters:_

   • cx, cy - Center of the circle
   • r - Radius of the circle
   • color - Color of the circle

See also: *note al_draw_circle: #al_draw_circle, *note
al_draw_filled_ellipse: #al_draw_filled_ellipse.


File: refman.info,  Node: al_draw_arc,  Next: al_draw_elliptical_arc,  Prev: al_draw_filled_circle,  Up: High level drawing routines

38.2.16 al_draw_arc
-------------------

void al_draw_arc(float cx, float cy, float r, float start_theta,
   float delta_theta, ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L847)

Draws an arc.

_Parameters:_

   • cx, cy - Center of the arc
   • r - Radius of the arc
   • color - Color of the arc
   • start_theta - The initial angle from which the arc is calculated in
     radians
   • delta_theta - Angular span of the arc in radians (pass a negative
     number to switch direction)
   • thickness - Thickness of the arc, pass ‘<= 0’ to draw hairline arc

See also: *note al_calculate_arc: #al_calculate_arc, *note
al_draw_elliptical_arc: #al_draw_elliptical_arc.


File: refman.info,  Node: al_draw_elliptical_arc,  Next: al_calculate_spline,  Prev: al_draw_arc,  Up: High level drawing routines

38.2.17 al_draw_elliptical_arc
------------------------------

void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta,
   float delta_theta, ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L797)

Draws an elliptical arc.

_Parameters:_

   • cx, cy - Center of the arc
   • rx, ry - Radii of the arc
   • color - Color of the arc
   • start_theta - The initial angle from which the arc is calculated in
     radians
   • delta_theta - Angular span of the arc in radians (pass a negative
     number to switch direction)
   • thickness - Thickness of the arc, pass ‘<= 0’ to draw hairline arc

Since: 5.0.6, 5.1.0

See also: *note al_calculate_arc: #al_calculate_arc, *note al_draw_arc:
#al_draw_arc.


File: refman.info,  Node: al_calculate_spline,  Next: al_draw_spline,  Prev: al_draw_elliptical_arc,  Up: High level drawing routines

38.2.18 al_calculate_spline
---------------------------

void al_calculate_spline(float* dest, int stride, float points[8],
   float thickness, int num_segments)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L1004)

Calculates a Bézier spline given 4 control points.  If ‘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 stride bytes) doublets of floats,
corresponding to x and y coordinates of the vertices.

_Parameters:_

   • dest - The destination buffer
   • stride - Distance (in bytes) between starts of successive pairs of
     coordinates
   • points - An array of 4 pairs of coordinates of the 4 control points
   • thickness - Thickness of the spline ribbon
   • num_segments - The number of points to calculate

See also: *note al_draw_spline: #al_draw_spline, *note al_calculate_arc:
#al_calculate_arc, *note al_calculate_ribbon: #al_calculate_ribbon.


File: refman.info,  Node: al_draw_spline,  Next: al_calculate_ribbon,  Prev: al_calculate_spline,  Up: High level drawing routines

38.2.19 al_draw_spline
----------------------

void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L1083)

Draws a Bézier spline given 4 control points.

_Parameters:_

   • points - An array of 4 pairs of coordinates of the 4 control points
   • color - Color of the spline
   • thickness - Thickness of the spline, pass ‘<= 0’ to draw a hairline
     spline

See also: *note al_calculate_spline: #al_calculate_spline.


File: refman.info,  Node: al_calculate_ribbon,  Next: al_draw_ribbon,  Prev: al_draw_spline,  Up: High level drawing routines

38.2.20 al_calculate_ribbon
---------------------------

void al_calculate_ribbon(float* dest, int dest_stride, const float *points,
   int points_stride, float thickness, int num_segments)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L1127)

Calculates a ribbon given an array of points.  The ribbon will go
through all of the passed points.  If ‘thickness <= 0’, then
‘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.

_Parameters:_

   • dest - Pointer to the destination buffer
   • dest_stride - Distance (in bytes) between starts of successive
     pairs of coordinates in the destination buffer
   • points - An array of pairs of coordinates for each point
   • points_stride - Distance (in bytes) between starts of successive
     pairs of coordinates in the points buffer
   • thickness - Thickness of the spline ribbon
   • num_segments - The number of points to calculate

See also: *note al_draw_ribbon: #al_draw_ribbon, *note al_calculate_arc:
#al_calculate_arc, *note al_calculate_spline: #al_calculate_spline.


File: refman.info,  Node: al_draw_ribbon,  Prev: al_calculate_ribbon,  Up: High level drawing routines

38.2.21 al_draw_ribbon
----------------------

void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color,
   float thickness, int num_segments)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/high_primitives.c#L1249)

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.

_Parameters:_

   • points - An array of coordinate pairs (x and y) for each point
   • points_stride - Distance (in bytes) between starts of successive
     pairs of coordinates in the points buffer
   • color - Color of the spline
   • thickness - Thickness of the spline, pass ‘<= 0’ to draw hairline
     spline
   • num_segments - The number of segments

See also: *note al_calculate_ribbon: #al_calculate_ribbon.


File: refman.info,  Node: Low level drawing routines,  Next: Custom vertex declaration routines,  Prev: High level drawing routines,  Up: Primitives addon

38.3 Low level drawing routines
===============================

Low level drawing routines allow for more advanced usage of the addon,
allowing you to pass arbitrary sequences of vertices to draw to the
screen.  These routines also support using textures on the primitives
with the following restrictions:

For maximum portability, you should only use textures that have
dimensions that are a power of two, as not every videocard supports
textures of different sizes completely.  This warning is relaxed,
however, if the texture coordinates never exit the boundaries of a
single bitmap (i.e. you are not having the texture repeat/tile).  As
long as that is the case, any texture can be used safely.  Sub-bitmaps
work as textures, but cannot be tiled.

Some platforms also dictate a minimum texture size, which means that
textures smaller than that size will not tile properly.  The minimum
size that will work on all platforms is 32 by 32.

A note about pixel coordinates.  In OpenGL the texture coordinate (0, 0)
refers to the top left corner of the pixel.  This confuses some drivers,
because due to rounding errors the actual pixel sampled might be the
pixel to the top and/or left of the (0, 0) pixel.  To make this error
less likely it is advisable to offset the texture coordinates you pass
to the al_draw_prim by (0.5, 0.5) if you need precise pixel control.
E.g.  to refer to pixel (5, 10) you’d set the u and v to 5.5 and 10.5
respectively.

See also: *note Pixel-precise output: #pixel-precise-output.

* Menu:

* al_draw_prim::
* al_draw_indexed_prim::
* al_draw_vertex_buffer::
* al_draw_indexed_buffer::
* al_draw_soft_triangle::
* al_draw_soft_line::


File: refman.info,  Node: al_draw_prim,  Next: al_draw_indexed_prim,  Up: Low level drawing routines

38.3.1 al_draw_prim
-------------------

int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
   ALLEGRO_BITMAP* texture, int start, int end, int type)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L77)

Draws a subset of the passed vertex array.

_Parameters:_

   • texture - Texture to use, pass NULL to use only color shaded
     primitves
   • vtxs - Pointer to an array of vertices
   • decl - Pointer to a *note vertex declaration:
     #al_create_vertex_decl.  If set to NULL, the vertices are assumed
     to be of the *note ALLEGRO_VERTEX: #allegro_vertex. type
   • start - Start index of the subset of the vertex array to draw
   • end - One past the last index of the subset of the vertex array to
     draw
   • type - A member of the *note ALLEGRO_PRIM_TYPE: #allegro_prim_type.
     enumeration, specifying what kind of primitive to draw

_Returns:_ Number of primitives drawn

For example to draw a textured triangle you could use:

ALLEGRO_COLOR white = al_map_rgb_f(1, 1, 1);
ALLEGRO_VERTEX v[] = {
   {.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}};
al_draw_prim(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST);

See also: *note ALLEGRO_VERTEX: #allegro_vertex, *note
ALLEGRO_PRIM_TYPE: #allegro_prim_type, *note ALLEGRO_VERTEX_DECL:
#allegro_vertex_decl, *note al_draw_indexed_prim: #al_draw_indexed_prim.


File: refman.info,  Node: al_draw_indexed_prim,  Next: al_draw_vertex_buffer,  Prev: al_draw_prim,  Up: Low level drawing routines

38.3.2 al_draw_indexed_prim
---------------------------

int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
   ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L113)

Draws a subset of the passed vertex array.  This function uses an index
array to specify which vertices to use.

_Parameters:_

   • texture - Texture to use, pass NULL to use only color shaded
     primitves
   • vtxs - Pointer to an array of vertices
   • decl - Pointer to a vertex declaration.  If set to NULL, the vtxs
     are assumed to be of the ALLEGRO_VERTEX type
   • indices - An array of indices into the vertex array
   • num_vtx - Number of indices from the indices array you want to draw
   • type - A member of the *note ALLEGRO_PRIM_TYPE: #allegro_prim_type.
     enumeration, specifying what kind of primitive to draw

_Returns:_ Number of primitives drawn

See also: *note ALLEGRO_VERTEX: #allegro_vertex, *note
ALLEGRO_PRIM_TYPE: #allegro_prim_type, *note ALLEGRO_VERTEX_DECL:
#allegro_vertex_decl, *note al_draw_prim: #al_draw_prim.


File: refman.info,  Node: al_draw_vertex_buffer,  Next: al_draw_indexed_buffer,  Prev: al_draw_indexed_prim,  Up: Low level drawing routines

38.3.3 al_draw_vertex_buffer
----------------------------

int al_draw_vertex_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
   ALLEGRO_BITMAP* texture, int start, int end, int type)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L512)

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 ‘ALLEGRO_PRIM_BUFFER_READWRITE’).

_Parameters:_

   • vertex_buffer - Vertex buffer to draw
   • texture - Texture to use, pass NULL to use only color shaded
     primitves
   • start - Start index of the subset of the vertex buffer to draw
   • end - One past the last index of the subset of the vertex buffer to
     draw
   • type - A member of the *note ALLEGRO_PRIM_TYPE: #allegro_prim_type.
     enumeration, specifying what kind of primitive to draw

_Returns:_ Number of primitives drawn

Since: 5.1.3

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer, *note
ALLEGRO_PRIM_TYPE: #allegro_prim_type.


File: refman.info,  Node: al_draw_indexed_buffer,  Next: al_draw_soft_triangle,  Prev: al_draw_vertex_buffer,  Up: Low level drawing routines

38.3.4 al_draw_indexed_buffer
-----------------------------

int al_draw_indexed_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
   ALLEGRO_BITMAP* texture, ALLEGRO_INDEX_BUFFER* index_buffer,
   int start, int end, int type)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L547)

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 ‘ALLEGRO_PRIM_BUFFER_READWRITE’).

_Parameters:_

   • vertex_buffer - Vertex buffer to draw
   • texture - Texture to use, pass NULL to use only color shaded
     primitves
   • index_buffer - Index buffer to use
   • start - Start index of the subset of the vertex buffer to draw
   • end - One past the last index of the subset of the vertex buffer to
     draw
   • type - A member of the *note ALLEGRO_PRIM_TYPE: #allegro_prim_type.
     enumeration, specifying what kind of primitive to draw.  Note that
     ALLEGRO_PRIM_LINE_LOOP and ALLEGRO_PRIM_POINT_LIST are not
     supported.

_Returns:_ Number of primitives drawn

Since: 5.1.8

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer, *note
ALLEGRO_INDEX_BUFFER: #allegro_index_buffer, *note ALLEGRO_PRIM_TYPE:
#allegro_prim_type.


File: refman.info,  Node: al_draw_soft_triangle,  Next: al_draw_soft_line,  Prev: al_draw_indexed_buffer,  Up: Low level drawing routines

38.3.5 al_draw_soft_triangle
----------------------------

void al_draw_soft_triangle(
   ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state,
   void (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
   void (*first)(uintptr_t, int, int, int, int),
   void (*step)(uintptr_t, int),
   void (*draw)(uintptr_t, int, int, int))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/prim_soft.c#L523)

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
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.

_Parameters:_

   • v1, v2, v3 - The three vertices of the triangle
   • state - A pointer to a user supplied struct, this struct will be
     passed to all the pixel functions
   • init - Called once per call before any drawing is done.  The three
     points passed to it may be altered by clipping.
   • first - Called twice per call, once per triangle segment.  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.
   • 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.
   • draw - Called once per scanline.  The function is expected to draw
     the scanline starting with a point specified by the first two
     parameters (corresponding to x and y values) going to the right
     until it reaches the value of the third parameter (the x value of
     the end point).  All coordinates are inclusive.

See also: *note al_draw_triangle: #al_draw_triangle.


File: refman.info,  Node: al_draw_soft_line,  Prev: al_draw_soft_triangle,  Up: Low level drawing routines

38.3.6 al_draw_soft_line
------------------------

void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state,
   void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
   void (*step)(uintptr_t, int),
   void (*draw)(uintptr_t, int, int))

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/line_soft.c#L571)

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
addons/primitives/line_soft.c.  The line is drawn top to bottom.

_Parameters:_

   • v1, v2 - The two vertices of the line
   • state - A pointer to a user supplied struct, this struct will be
     passed to all the pixel functions
   • first - Called before drawing the first pixel of the 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.
   • 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.
   • draw - Called once per pixel.  The function is expected to draw the
     pixel at the coordinates passed to it.

See also: *note al_draw_line: #al_draw_line.


File: refman.info,  Node: Custom vertex declaration routines,  Next: Vertex buffer routines,  Prev: Low level drawing routines,  Up: Primitives addon

38.4 Custom vertex declaration routines
=======================================

* Menu:

* al_create_vertex_decl::
* al_destroy_vertex_decl::


File: refman.info,  Node: al_create_vertex_decl,  Next: al_destroy_vertex_decl,  Up: Custom vertex declaration routines

38.4.1 al_create_vertex_decl
----------------------------

ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L167)

Creates a vertex declaration, which describes a custom vertex format.

_Parameters:_

   • elements - An array of *note ALLEGRO_VERTEX_ELEMENT:
     #allegro_vertex_element. structures.
   • stride - Size of the custom vertex structure

_Returns:_ Newly created vertex declaration.

See also: *note ALLEGRO_VERTEX_ELEMENT: #allegro_vertex_element, *note
ALLEGRO_VERTEX_DECL: #allegro_vertex_decl, *note al_destroy_vertex_decl:
#al_destroy_vertex_decl.


File: refman.info,  Node: al_destroy_vertex_decl,  Prev: al_create_vertex_decl,  Up: Custom vertex declaration routines

38.4.2 al_destroy_vertex_decl
-----------------------------

void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L227)

Destroys a vertex declaration.

_Parameters:_

   • decl - Vertex declaration to destroy

See also: *note ALLEGRO_VERTEX_ELEMENT: #allegro_vertex_element, *note
ALLEGRO_VERTEX_DECL: #allegro_vertex_decl, *note al_create_vertex_decl:
#al_create_vertex_decl.


File: refman.info,  Node: Vertex buffer routines,  Next: Index buffer routines,  Prev: Custom vertex declaration routines,  Up: Primitives addon

38.5 Vertex buffer routines
===========================

* Menu:

* al_create_vertex_buffer::
* al_destroy_vertex_buffer::
* al_lock_vertex_buffer::
* al_unlock_vertex_buffer::
* al_get_vertex_buffer_size::


File: refman.info,  Node: al_create_vertex_buffer,  Next: al_destroy_vertex_buffer,  Up: Vertex buffer routines

38.5.1 al_create_vertex_buffer
------------------------------

ALLEGRO_VERTEX_BUFFER* al_create_vertex_buffer(ALLEGRO_VERTEX_DECL* decl,
   const void* initial_data, int num_vertices, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L240)

Creates a vertex buffer.  Can return NULL if the buffer could not be
created (e.g. the system only supports write-only buffers).

     _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.
_Parameters:_

   • decl - Vertex type that this buffer will hold.  NULL implies that
     this buffer will hold *note ALLEGRO_VERTEX: #allegro_vertex.
     vertices
   • initial_data - Memory buffer to copy from to initialize the vertex
     buffer.  Can be ‘NULL’, in which case the buffer is uninitialized.
   • num_vertices - Number of vertices the buffer will hold
   • flags - A combination of the *note ALLEGRO_PRIM_BUFFER_FLAGS:
     #allegro_prim_buffer_flags. flags specifying how this buffer will
     be created.  Passing 0 is the same as passing
     ‘ALLEGRO_PRIM_BUFFER_STATIC’.

Since: 5.1.3

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer, *note
al_destroy_vertex_buffer: #al_destroy_vertex_buffer.


File: refman.info,  Node: al_destroy_vertex_buffer,  Next: al_lock_vertex_buffer,  Prev: al_create_vertex_buffer,  Up: Vertex buffer routines

38.5.2 al_destroy_vertex_buffer
-------------------------------

void al_destroy_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L314)

Destroys a vertex buffer.  Does nothing if passed NULL.

Since: 5.1.3

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer, *note
al_create_vertex_buffer: #al_create_vertex_buffer.


File: refman.info,  Node: al_lock_vertex_buffer,  Next: al_unlock_vertex_buffer,  Prev: al_destroy_vertex_buffer,  Up: Vertex buffer routines

38.5.3 al_lock_vertex_buffer
----------------------------

void* al_lock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer, int offset,
   int length, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L371)

Locks a vertex buffer so you can access its data.  Will return NULL if
the parameters are invalid, if reading is requested from a write only
buffer, or if the buffer is already locked.

_Parameters:_

   • buffer - Vertex buffer to lock
   • offset - Vertex index of the start of the locked range
   • length - How many vertices to lock
   • flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or
     ALLEGRO_LOCK_READWRITE

Since: 5.1.3

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer, *note
al_unlock_vertex_buffer: #al_unlock_vertex_buffer.


File: refman.info,  Node: al_unlock_vertex_buffer,  Next: al_get_vertex_buffer_size,  Prev: al_lock_vertex_buffer,  Up: Vertex buffer routines

38.5.4 al_unlock_vertex_buffer
------------------------------

void al_unlock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L426)

Unlocks a previously locked vertex buffer.

Since: 5.1.3

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer, *note
al_lock_vertex_buffer: #al_lock_vertex_buffer.


File: refman.info,  Node: al_get_vertex_buffer_size,  Prev: al_unlock_vertex_buffer,  Up: Vertex buffer routines

38.5.5 al_get_vertex_buffer_size
--------------------------------

int al_get_vertex_buffer_size(ALLEGRO_VERTEX_BUFFER* buffer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L585)

Returns the size of the vertex buffer

Since: 5.1.8

See also: *note ALLEGRO_VERTEX_BUFFER: #allegro_vertex_buffer.


File: refman.info,  Node: Index buffer routines,  Next: Polygon routines,  Prev: Vertex buffer routines,  Up: Primitives addon

38.6 Index buffer routines
==========================

* Menu:

* al_create_index_buffer::
* al_destroy_index_buffer::
* al_lock_index_buffer::
* al_unlock_index_buffer::
* al_get_index_buffer_size::


File: refman.info,  Node: al_create_index_buffer,  Next: al_destroy_index_buffer,  Up: Index buffer routines

38.6.1 al_create_index_buffer
-----------------------------

ALLEGRO_INDEX_BUFFER* al_create_index_buffer(int index_size,
    const void* initial_data, int num_indices, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L274)

Creates a index buffer.  Can return NULL if the buffer could not be
created (e.g. the system only supports write-only buffers).

     _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.
_Parameters:_

   • index_size - Size of the index in bytes.  Supported sizes are 2 for
     short integers and 4 for integers
   • initial_data - Memory buffer to copy from to initialize the index
     buffer.  Can be ‘NULL’, in which case the buffer is uninitialized.
   • num_indices - Number of indices the buffer will hold
   • flags - A combination of the *note ALLEGRO_PRIM_BUFFER_FLAGS:
     #allegro_prim_buffer_flags. flags specifying how this buffer will
     be created.  Passing 0 is the same as passing
     ‘ALLEGRO_PRIM_BUFFER_STATIC’.

Since: 5.1.8

See also: *note ALLEGRO_INDEX_BUFFER: #allegro_index_buffer, *note
al_destroy_index_buffer: #al_destroy_index_buffer.


File: refman.info,  Node: al_destroy_index_buffer,  Next: al_lock_index_buffer,  Prev: al_create_index_buffer,  Up: Index buffer routines

38.6.2 al_destroy_index_buffer
------------------------------

void al_destroy_index_buffer(ALLEGRO_INDEX_BUFFER* buffer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L336)

Destroys a index buffer.  Does nothing if passed NULL.

Since: 5.1.8

See also: *note ALLEGRO_INDEX_BUFFER: #allegro_index_buffer, *note
al_create_index_buffer: #al_create_index_buffer.


File: refman.info,  Node: al_lock_index_buffer,  Next: al_unlock_index_buffer,  Prev: al_destroy_index_buffer,  Up: Index buffer routines

38.6.3 al_lock_index_buffer
---------------------------

void* al_lock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer, int offset,
    int length, int flags)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L400)

Locks a index buffer so you can access its data.  Will return NULL if
the parameters are invalid, if reading is requested from a write only
buffer and if the buffer is already locked.

_Parameters:_

   • buffer - Index buffer to lock
   • offset - Element index of the start of the locked range
   • length - How many indices to lock
   • flags - ALLEGRO_LOCK_READONLY, ALLEGRO_LOCK_WRITEONLY or
     ALLEGRO_LOCK_READWRITE

Since: 5.1.8

See also: *note ALLEGRO_INDEX_BUFFER: #allegro_index_buffer, *note
al_unlock_index_buffer: #al_unlock_index_buffer.


File: refman.info,  Node: al_unlock_index_buffer,  Next: al_get_index_buffer_size,  Prev: al_lock_index_buffer,  Up: Index buffer routines

38.6.4 al_unlock_index_buffer
-----------------------------

void al_unlock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L447)

Unlocks a previously locked index buffer.

Since: 5.1.8

See also: *note ALLEGRO_INDEX_BUFFER: #allegro_index_buffer, *note
al_lock_index_buffer: #al_lock_index_buffer.


File: refman.info,  Node: al_get_index_buffer_size,  Prev: al_unlock_index_buffer,  Up: Index buffer routines

38.6.5 al_get_index_buffer_size
-------------------------------

int al_get_index_buffer_size(ALLEGRO_INDEX_BUFFER* buffer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/primitives.c#L593)

Returns the size of the index buffer

Since: 5.1.8

See also: *note ALLEGRO_INDEX_BUFFER: #allegro_index_buffer.


File: refman.info,  Node: Polygon routines,  Next: Structures and types,  Prev: Index buffer routines,  Up: Primitives addon

38.7 Polygon routines
=====================

* Menu:

* al_draw_polyline::
* al_draw_polygon::
* al_draw_filled_polygon::
* al_draw_filled_polygon_with_holes::
* al_triangulate_polygon::


File: refman.info,  Node: al_draw_polyline,  Next: al_draw_polygon,  Up: Polygon routines

38.7.1 al_draw_polyline
-----------------------

void al_draw_polyline(const float* vertices, int vertex_stride,
   int vertex_count, int join_style, int cap_style,
   ALLEGRO_COLOR color, float thickness, float miter_limit)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/polyline.c#L534)

Draw a series of line segments.

   • vertices - Interleaved array of (x, y) vertex coordinates
   • vertex_stride - the number of bytes between pairs of vertices (the
     stride)
   • vertex_count - Number of vertices in the array
   • join_style - Member of *note ALLEGRO_LINE_JOIN: #allegro_line_join.
     specifying how to render the joins between line segments
   • cap_style - Member of *note ALLEGRO_LINE_CAP: #allegro_line_cap.
     specifying how to render the end caps
   • color - Color of the line
   • thickness - Thickness of the line, pass ‘<= 0’ to draw hairline
     lines
   • miter_limit - Parameter for miter join style

The stride is normally ‘2 * sizeof(float)’ but may be more if the vertex
coordinates are in an array of some structure type, e.g.

struct VertexInfo {
   float x;
   float y;
   int id;
};

void my_draw(struct VertexInfo verts[], int vertex_count, ALLEGRO_COLOR c)
{
   al_draw_polyline((float *)verts, sizeof(VertexInfo), vertex_count,
      ALLEGRO_LINE_JOIN_NONE, ALLEGRO_LINE_CAP_NONE, c, 1.0, 1.0);
}

The stride may also be negative if the vertices are stored in reverse
order.

Since: 5.1.0

See also: *note al_draw_polygon: #al_draw_polygon, *note
ALLEGRO_LINE_JOIN: #allegro_line_join, *note ALLEGRO_LINE_CAP:
#allegro_line_cap.


File: refman.info,  Node: al_draw_polygon,  Next: al_draw_filled_polygon,  Prev: al_draw_polyline,  Up: Polygon routines

38.7.2 al_draw_polygon
----------------------

void al_draw_polygon(const float *vertices, int vertex_count,
   int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/polygon.c#L44)

Draw an unfilled polygon.  This is the same as passing
‘ALLEGRO_LINE_CAP_CLOSED’ to *note al_draw_polyline: #al_draw_polyline.

   • vertex - Interleaved array of (x, y) vertex coordinates
   • vertex_count - Number of vertices in the array
   • join_style - Member of *note ALLEGRO_LINE_JOIN: #allegro_line_join.
     specifying how to render the joins between line segments
   • color - Color of the line
   • thickness - Thickness of the line, pass ‘<= 0’ to draw hairline
     lines
   • miter_limit - Parameter for miter join style

Since: 5.1.0

See also: *note al_draw_filled_polygon: #al_draw_filled_polygon, *note
al_draw_polyline: #al_draw_polyline, *note ALLEGRO_LINE_JOIN:
#allegro_line_join.


File: refman.info,  Node: al_draw_filled_polygon,  Next: al_draw_filled_polygon_with_holes,  Prev: al_draw_polygon,  Up: Polygon routines

38.7.3 al_draw_filled_polygon
-----------------------------

void al_draw_filled_polygon(const float *vertices, int vertex_count,
   ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/polygon.c#L53)

Draw a filled, simple polygon.  Simple means it does not have to be
convex but must not be self-overlapping.

   • vertices - Interleaved array of (x, y) vertex coordinates
   • vertex_count - Number of vertices in the array
   • color - Color of the filled polygon

When the y-axis is facing downwards (the usual), the coordinates must be
ordered anti-clockwise.

Since: 5.1.0

See also: *note al_draw_polygon: #al_draw_polygon, *note
al_draw_filled_polygon_with_holes: #al_draw_filled_polygon_with_holes.


File: refman.info,  Node: al_draw_filled_polygon_with_holes,  Next: al_triangulate_polygon,  Prev: al_draw_filled_polygon,  Up: Polygon routines

38.7.4 al_draw_filled_polygon_with_holes
----------------------------------------

void al_draw_filled_polygon_with_holes(const float *vertices,
   const int *vertex_counts, ALLEGRO_COLOR color)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/polygon.c#L71)

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.

   • vertices - Interleaved array of (x, y) vertex coordinates for each
     of the polygons, including holes.
   • vertex_counts - Number of vertices for each polygon.  The number of
     vertices in the filled 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.
   • color - Color of the filled polygon

When the y-axis is facing downwards (the usual) the filled polygon
coordinates must be ordered anti-clockwise.  All hole vertices must use
the opposite order (clockwise with y down).  All hole vertices must be
inside the main polygon and no hole may overlap the main polygon.

For example:

float vertices[] = {
      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
};
int vertex_counts[] = {
   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).

Since: 5.1.0

See also: *note al_draw_filled_polygon: #al_draw_filled_polygon, *note
al_draw_filled_polygon_with_holes: #al_draw_filled_polygon_with_holes,
*note al_triangulate_polygon: #al_triangulate_polygon.


File: refman.info,  Node: al_triangulate_polygon,  Prev: al_draw_filled_polygon_with_holes,  Up: Polygon routines

38.7.5 al_triangulate_polygon
-----------------------------

bool al_triangulate_polygon(
   const float* vertices, size_t vertex_stride, const int* vertex_counts,
   void (*emit_triangle)(int, int, int, void*), void* userdata)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/triangulator.c#L814)

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.

_Parameters:_

   • vertices - Interleaved array of (x, y) vertex coordinates for each
     of the polygons, including holes.
   • vertex_stride - distance (in bytes) between successive pairs of
     vertices in the array.
   • 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.
   • 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 ‘vertices’ and ‘userdata’.
   • userdata - arbitrary data to be passed to emit_triangle.

Since: 5.1.0

See also: *note al_draw_filled_polygon_with_holes:
#al_draw_filled_polygon_with_holes.


File: refman.info,  Node: Structures and types,  Prev: Polygon routines,  Up: Primitives addon

38.8 Structures and types
=========================

* Menu:

* ALLEGRO_VERTEX::
* ALLEGRO_VERTEX_DECL::
* ALLEGRO_VERTEX_ELEMENT::
* ALLEGRO_PRIM_TYPE::
* ALLEGRO_PRIM_ATTR::
* ALLEGRO_PRIM_STORAGE::
* ALLEGRO_VERTEX_CACHE_SIZE::
* ALLEGRO_PRIM_QUALITY::
* ALLEGRO_LINE_JOIN::
* ALLEGRO_LINE_CAP::
* ALLEGRO_VERTEX_BUFFER::
* ALLEGRO_INDEX_BUFFER::
* ALLEGRO_PRIM_BUFFER_FLAGS::


File: refman.info,  Node: ALLEGRO_VERTEX,  Next: ALLEGRO_VERTEX_DECL,  Up: Structures and types

38.8.1 ALLEGRO_VERTEX
---------------------

typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L145)

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 z to 0.  Note that you must initialize all members
of this struct when you’re using it.  One exception to this rule are the
u and v variables which can be left uninitialized when you are not using
textures.

_Fields:_

   • x, y, z - Position of the vertex (float)
   • u, v - Texture coordinates measured in pixels (float)
   • color - *note ALLEGRO_COLOR: #allegro_color. structure, storing the
     color of the vertex

See also: *note ALLEGRO_PRIM_ATTR: #allegro_prim_attr.


File: refman.info,  Node: ALLEGRO_VERTEX_DECL,  Next: ALLEGRO_VERTEX_ELEMENT,  Prev: ALLEGRO_VERTEX,  Up: Structures and types

38.8.2 ALLEGRO_VERTEX_DECL
--------------------------

typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L137)

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.

See also: *note al_create_vertex_decl: #al_create_vertex_decl, *note
al_destroy_vertex_decl: #al_destroy_vertex_decl, *note
ALLEGRO_VERTEX_ELEMENT: #allegro_vertex_element.


File: refman.info,  Node: ALLEGRO_VERTEX_ELEMENT,  Next: ALLEGRO_PRIM_TYPE,  Prev: ALLEGRO_VERTEX_DECL,  Up: Structures and types

38.8.3 ALLEGRO_VERTEX_ELEMENT
-----------------------------

typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L127)

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
*note al_create_vertex_decl: #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 attribute field equal to
0, to signify that it is the end of the array.  Here is an example code
that would create a declaration describing the *note ALLEGRO_VERTEX:
#allegro_vertex. structure (passing this as vertex declaration to
al_draw_prim would be identical to passing NULL):

/* On compilers without the offsetof keyword you need to obtain the
 * offset with sizeof and make sure to account for packing.
 */
ALLEGRO_VERTEX_ELEMENT elems[] = {
   {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)},
   {ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)},
   {ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)},
   {0, 0, 0}
};
ALLEGRO_VERTEX_DECL* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX));

_Fields:_

   • attribute - A member of the *note ALLEGRO_PRIM_ATTR:
     #allegro_prim_attr. enumeration, specifying what this attribute
     signifies
   • storage - A member of the *note ALLEGRO_PRIM_STORAGE:
     #allegro_prim_storage. enumeration, specifying how this attribute
     is stored
   • offset - Offset in bytes from the beginning of the custom vertex
     structure.  The C function offsetof is very useful here.

See also: *note al_create_vertex_decl: #al_create_vertex_decl, *note
ALLEGRO_VERTEX_DECL: #allegro_vertex_decl, *note ALLEGRO_PRIM_ATTR:
#allegro_prim_attr, *note ALLEGRO_PRIM_STORAGE: #allegro_prim_storage.


File: refman.info,  Node: ALLEGRO_PRIM_TYPE,  Next: ALLEGRO_PRIM_ATTR,  Prev: ALLEGRO_VERTEX_ELEMENT,  Up: Structures and types

38.8.4 ALLEGRO_PRIM_TYPE
------------------------

typedef enum ALLEGRO_PRIM_TYPE

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L36)

Enumerates the types of primitives this addon can draw.

   • ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a
     point

   • ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of
     vertices define disjointed lines

   • ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices
     define a strip of lines

   • ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the
     first and the last vertices are also connected by a line

   • ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential
     triplets of vertices define disjointed triangles

   • ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential
     vertices define a strip of triangles

   • ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share
     the first vertex


File: refman.info,  Node: ALLEGRO_PRIM_ATTR,  Next: ALLEGRO_PRIM_STORAGE,  Prev: ALLEGRO_PRIM_TYPE,  Up: Structures and types

38.8.5 ALLEGRO_PRIM_ATTR
------------------------

typedef enum ALLEGRO_PRIM_ATTR

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L55)

Enumerates the types of vertex attributes that a custom vertex may have.

   • ALLEGRO_PRIM_POSITION - Position information, can be stored only in
     ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and
     ALLEGRO_PRIM_FLOAT_3.

   • ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an *note
     ALLEGRO_COLOR: #allegro_color.  The storage field of
     ALLEGRO_VERTEX_ELEMENT is ignored

   • ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be
     stored only in ALLEGRO_PRIM_FLOAT_2 and 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 (1, 1).

   • ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can
     be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2.
     These coordinates are measured in pixels.

   • ALLEGRO_PRIM_USER_ATTR - A user specified attribute.  You can use
     any storage for this attribute.  You may have at most
     ALLEGRO_PRIM_MAX_USER_ATTR (currently 10) of these that you can
     specify by adding an index to the value of ALLEGRO_PRIM_USER_ATTR,
     e.g. the first user attribute is ‘ALLEGRO_PRIM_USER_ATTR + 0’, the
     second is ‘ALLEGRO_PRIM_USER_ATTR + 1’ and so on.

     To access these custom attributes from GLSL shaders you need to
     declare attributes that follow this nomenclature: ‘al_user_attr_#’
     where # is the index of the attribute.

     For example to have a position and a normal vector for each vertex
     you could declare it like this:

     ALLEGRO_VERTEX_ELEMENT elements[3] = {
         {ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, 0},
         {ALLEGRO_PRIM_USER_ATTR + 0, ALLEGRO_PRIM_FLOAT_3, 12},
         {0, 0, 0}};

     And then in your vertex shader access it like this:

     attribute vec3 al_pos; // ALLEGRO_PRIM_POSITION
     attribute vec3 al_user_attr_0; // ALLEGRO_PRIM_USER_ATTR + 0
     varying float light;
     const vec3 light_direction = vec3(0, 0, 1);
     void main() {
         light = dot(al_user_attr_0, light_direction);
         gl_Position = al_pos;
     }

     To access these custom attributes from HLSL you need to declare a
     parameter with the following semantics: ‘TEXCOORD{# + 2}’ where #
     is the index of the attribute.  E.g.  the first attribute can be
     accessed via ‘TEXCOORD2’, second via ‘TEXCOORD3’ and so on.

     Since: 5.1.6

See also: *note ALLEGRO_VERTEX_DECL: #allegro_vertex_decl, *note
ALLEGRO_PRIM_STORAGE: #allegro_prim_storage, *note
al_attach_shader_source: #al_attach_shader_source.


File: refman.info,  Node: ALLEGRO_PRIM_STORAGE,  Next: ALLEGRO_VERTEX_CACHE_SIZE,  Prev: ALLEGRO_PRIM_ATTR,  Up: Structures and types

38.8.6 ALLEGRO_PRIM_STORAGE
---------------------------

typedef enum ALLEGRO_PRIM_STORAGE

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L67)

Enumerates the types of storage an attribute of a custom vertex may be
stored in.  Many of these can only be used for 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. ALLEGRO_PRIM_NORMALIZED_UBYTE_4 instead of ALLEGRO_PRIM_FLOAT_4)
when bandwidth (amount of memory sent to the GPU) is an issue but
precision is not.

   • ALLEGRO_PRIM_FLOAT_1 - A single float

     Since: 5.1.6

   • ALLEGRO_PRIM_FLOAT_2 - A doublet of floats

   • ALLEGRO_PRIM_FLOAT_3 - A triplet of floats

   • ALLEGRO_PRIM_FLOAT_4 - A quad of floats

     Since: 5.1.6

   • ALLEGRO_PRIM_SHORT_2 - A doublet of shorts

   • ALLEGRO_PRIM_SHORT_4 - A quad of shorts

     Since: 5.1.6

   • ALLEGRO_PRIM_UBYTE_4 - A quad of unsigned bytes

     Since: 5.1.6

   • 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

     Since: 5.1.6

   • 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

     Since: 5.1.6

   • 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

     Since: 5.1.6

   • 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

     Since: 5.1.6

   • 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

     Since: 5.1.6

   • ALLEGRO_PRIM_HALF_FLOAT_2 - A doublet of half-precision floats.
     Note that this storage format is not supported on all platforms.
     *note al_create_vertex_decl: #al_create_vertex_decl. will return
     NULL if you use it on those platforms

     Since: 5.1.6

   • ALLEGRO_PRIM_HALF_FLOAT_4 - A quad of half-precision floats.  Note
     that this storage format is not supported on all platforms.  *note
     al_create_vertex_decl: #al_create_vertex_decl. will return NULL if
     you use it on those platforms.

     Since: 5.1.6

See also: *note ALLEGRO_PRIM_ATTR: #allegro_prim_attr.


File: refman.info,  Node: ALLEGRO_VERTEX_CACHE_SIZE,  Next: ALLEGRO_PRIM_QUALITY,  Prev: ALLEGRO_PRIM_STORAGE,  Up: Structures and types

38.8.7 ALLEGRO_VERTEX_CACHE_SIZE
--------------------------------

#define ALLEGRO_VERTEX_CACHE_SIZE 256

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L119)

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.


File: refman.info,  Node: ALLEGRO_PRIM_QUALITY,  Next: ALLEGRO_LINE_JOIN,  Prev: ALLEGRO_VERTEX_CACHE_SIZE,  Up: Structures and types

38.8.8 ALLEGRO_PRIM_QUALITY
---------------------------

#define ALLEGRO_PRIM_QUALITY 10

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L123)

Controls the quality of the approximation of curved primitives
(e.g. circles).  Curved primitives are drawn by approximating them with
a sequence of line segments.  By default, this roughly corresponds to
error of less than half of a pixel.


File: refman.info,  Node: ALLEGRO_LINE_JOIN,  Next: ALLEGRO_LINE_CAP,  Prev: ALLEGRO_PRIM_QUALITY,  Up: Structures and types

38.8.9 ALLEGRO_LINE_JOIN
------------------------

typedef enum ALLEGRO_LINE_JOIN

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L87)

   • ALLEGRO_LINE_JOIN_NONE
   • ALLEGRO_LINE_JOIN_BEVEL
   • ALLEGRO_LINE_JOIN_ROUND
   • ALLEGRO_LINE_JOIN_MITER

[ALLEGRO_LINE_JOIN styles]


_ALLEGRO_LINE_JOIN styles_
See the picture for the difference.

The maximum miter length (relative to the line width) can be specified
as parameter to the polygon functions.

Since: 5.1.0

See also: *note al_draw_polygon: #al_draw_polygon.


File: refman.info,  Node: ALLEGRO_LINE_CAP,  Next: ALLEGRO_VERTEX_BUFFER,  Prev: ALLEGRO_LINE_JOIN,  Up: Structures and types

38.8.10 ALLEGRO_LINE_CAP
------------------------

typedef enum ALLEGRO_LINE_CAP

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L98)

   • ALLEGRO_LINE_CAP_NONE
   • ALLEGRO_LINE_CAP_SQUARE
   • ALLEGRO_LINE_CAP_ROUND
   • ALLEGRO_LINE_CAP_TRIANGLE
   • ALLEGRO_LINE_CAP_CLOSED

[ALLEGRO_LINE_CAP styles]


_ALLEGRO_LINE_CAP styles_
See the picture for the difference.

ALLEGRO_LINE_CAP_CLOSED is different from the others - it causes the
polygon to have no caps.  (And the *note ALLEGRO_LINE_JOIN:
#allegro_line_join. style will determine how the vertex looks.)

Since: 5.1.0

See also: *note al_draw_polygon: #al_draw_polygon.


File: refman.info,  Node: ALLEGRO_VERTEX_BUFFER,  Next: ALLEGRO_INDEX_BUFFER,  Prev: ALLEGRO_LINE_CAP,  Up: Structures and types

38.8.11 ALLEGRO_VERTEX_BUFFER
-----------------------------

typedef struct ALLEGRO_VERTEX_BUFFER ALLEGRO_VERTEX_BUFFER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L156)

A GPU vertex buffer that you can use to store vertices on the GPU
instead of uploading them afresh during every drawing operation.

Since: 5.1.3

See also: *note al_create_vertex_buffer: #al_create_vertex_buffer, *note
al_destroy_vertex_buffer: #al_destroy_vertex_buffer.


File: refman.info,  Node: ALLEGRO_INDEX_BUFFER,  Next: ALLEGRO_PRIM_BUFFER_FLAGS,  Prev: ALLEGRO_VERTEX_BUFFER,  Up: Structures and types

38.8.12 ALLEGRO_INDEX_BUFFER
----------------------------

typedef struct ALLEGRO_INDEX_BUFFER ALLEGRO_INDEX_BUFFER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L160)

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.

Since: 5.1.8

See also: *note al_create_index_buffer: #al_create_index_buffer, *note
al_destroy_index_buffer: #al_destroy_index_buffer.


File: refman.info,  Node: ALLEGRO_PRIM_BUFFER_FLAGS,  Prev: ALLEGRO_INDEX_BUFFER,  Up: Structures and types

38.8.13 ALLEGRO_PRIM_BUFFER_FLAGS
---------------------------------

typedef enum ALLEGRO_PRIM_BUFFER_FLAGS

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/primitives/allegro5/allegro_primitives.h#L109)

Flags to specify how to create a vertex or an index buffer.

   • ALLEGRO_PRIM_BUFFER_STREAM - Hints to the driver that the buffer is
     written to often, but used only a few times per frame

   • ALLEGRO_PRIM_BUFFER_STATIC - Hints to the driver that the buffer is
     written to once and is used often

   • ALLEGRO_PRIM_BUFFER_DYNAMIC - Hints to the driver that the buffer
     is written to often and is used often

   • 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
     ‘al_create_vertex_buffer’ or ‘al_create_index_buffer’ the call will
     fail.

Since: 5.1.3

See also: *note al_create_vertex_buffer: #al_create_vertex_buffer, *note
al_create_index_buffer: #al_create_index_buffer.


File: refman.info,  Node: Shader routines,  Next: Video streaming addon,  Prev: Primitives addon,  Up: Top

39 Shader routines
******************

These functions are declared in the main Allegro header file:

 #include <allegro5/allegro.h>

* Menu:

* ALLEGRO_SHADER::
* ALLEGRO_SHADER_TYPE::
* ALLEGRO_SHADER_PLATFORM::
* al_create_shader::
* al_attach_shader_source::
* al_attach_shader_source_file::
* al_build_shader::
* al_get_shader_log::
* al_get_shader_platform::
* al_use_shader::
* al_destroy_shader::
* al_set_shader_sampler::
* al_set_shader_matrix::
* al_set_shader_int::
* al_set_shader_float::
* al_set_shader_bool::
* al_set_shader_int_vector::
* al_set_shader_float_vector::
* al_get_default_shader_source::


File: refman.info,  Node: ALLEGRO_SHADER,  Next: ALLEGRO_SHADER_TYPE,  Up: Shader routines

39.1 ALLEGRO_SHADER
===================

typedef struct ALLEGRO_SHADER ALLEGRO_SHADER;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/shader.h#L14)

An *note ALLEGRO_SHADER: #allegro_shader. is a program that runs on the
GPU. It combines both a vertex and a pixel shader.  (In OpenGL terms, an
*note ALLEGRO_SHADER: #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 *note
ALLEGRO_SHADER_PLATFORM: #allegro_shader_platform. used when creating
it.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_SHADER_TYPE,  Next: ALLEGRO_SHADER_PLATFORM,  Prev: ALLEGRO_SHADER,  Up: Shader routines

39.2 ALLEGRO_SHADER_TYPE
========================

typedef enum ALLEGRO_SHADER_TYPE ALLEGRO_SHADER_TYPE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/shader.h#L23)

Used with *note al_attach_shader_source: #al_attach_shader_source. and
*note al_attach_shader_source_file: #al_attach_shader_source_file. to
specify how to interpret the attached source.

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.

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 *note
     al_draw_bitmap: #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).

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_SHADER_PLATFORM,  Next: al_create_shader,  Prev: ALLEGRO_SHADER_TYPE,  Up: Shader routines

39.3 ALLEGRO_SHADER_PLATFORM
============================

typedef enum ALLEGRO_SHADER_PLATFORM ALLEGRO_SHADER_PLATFORM;

Source Code
(https://github.com/liballeg/allegro5/blob/master/include/allegro5/shader.h#L37)

The underlying platform which the *note ALLEGRO_SHADER: #allegro_shader.
is built on top of, which dictates the language used to program the
shader.

   • ALLEGRO_SHADER_AUTO - Pick a platform automatically given the
     current display flags.
   • ALLEGRO_SHADER_GLSL - OpenGL Shading Language
   • ALLEGRO_SHADER_HLSL - High Level Shader Language (for Direct3D)
   • ALLEGRO_SHADER_AUTO_MINIMAL - Like ALLEGRO_SHADER_AUTO, but pick a
     more minimal implementation that supports only basic alpha
     blending.
   • ALLEGRO_SHADER_GLSL_MINIMAL - Minimal GLSL shader.
   • ALLEGRO_SHADER_HLSL_MINIMAL - Minimal HLSL shader.
   • ALLEGRO_SHADER_HLSL_SM_3_0 - HLSL shader using shader model 3_0.

Since: 5.1.0


File: refman.info,  Node: al_create_shader,  Next: al_attach_shader_source,  Prev: ALLEGRO_SHADER_PLATFORM,  Up: Shader routines

39.4 al_create_shader
=====================

ALLEGRO_SHADER *al_create_shader(ALLEGRO_SHADER_PLATFORM platform)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L58)

Create a shader object.

The platform argument is one of the *note ALLEGRO_SHADER_PLATFORM:
#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 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.

Returns the shader object on success.  Otherwise, returns NULL.

Since: 5.1.0

See also: *note al_attach_shader_source: #al_attach_shader_source, *note
al_attach_shader_source_file: #al_attach_shader_source_file, *note
al_build_shader: #al_build_shader, *note al_use_shader: #al_use_shader,
*note al_destroy_shader: #al_destroy_shader, *note
al_get_shader_platform: #al_get_shader_platform.


File: refman.info,  Node: al_attach_shader_source,  Next: al_attach_shader_source_file,  Prev: al_create_shader,  Up: Shader routines

39.5 al_attach_shader_source
============================

bool al_attach_shader_source(ALLEGRO_SHADER *shader, ALLEGRO_SHADER_TYPE type,
    const char *source)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L102)

Attaches the shader’s source code to the shader object and compiles it.
Passing NULL deletes the underlying (OpenGL or DirectX) shader.  See
also *note al_attach_shader_source_file: #al_attach_shader_source_file.
if you prefer to obtain your shader source from an external file.

If you do not use 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 ALLEGRO_PROGRAMMABLE_PIPELINE set automatically in this case?

When ALLEGRO_PROGRAMMABLE_PIPELINE is used the following shader uniforms
are provided by Allegro and can be accessed in your shaders:

al_projview_matrix

     matrix for Allegro’s orthographic projection multiplied by the
     *note al_use_transform: #al_use_transform. matrix.  The type is
     ‘mat4’ in GLSL, and ‘float4x4’ in HLSL.
al_use_tex

     whether or not to use the bound texture.  The type is ‘bool’ in
     both GLSL and HLSL.
al_tex

     the texture if one is bound.  The type is ‘sampler2D’ in GLSL and
     ‘texture’ in HLSL.
al_use_tex_matrix

     whether or not to use a texture matrix (used by the primitives
     addon).  The type is ‘bool’ in both GLSL and HLSL.
al_tex_matrix

     the texture matrix (used by the primitives addon).  Your shader
     should multiply the texture coordinates by this matrix.  The type
     is ‘mat4’ in GLSL, and ‘float4x4’ in HLSL.

With GLSL alpha testing is done in the shader and uses these additional
uniforms:

al_alpha_test

     Whether to do any alpha testing.  If false, the shader should
     render the pixel, otherwise it should interpret the values of
     ‘al_alpha_func’ and ‘al_alpha_test_val’.
al_alpha_func

     The alpha testing function used.  One of the *note
     ALLEGRO_RENDER_FUNCTION: #allegro_render_function. values.  The
     default is ALLEGRO_RENDER_ALWAYS which means all pixels (even
     completely transparent ones) are rendered.  The type is ‘int’.  See
     *note ALLEGRO_RENDER_STATE: #allegro_render_state.
al_alpha_test_val

     If alpha testing is not ALLEGRO_RENDER_NEVER or
     ALLEGRO_RENDER_ALWAYS the alpha value to compare to for alpha
     testing.  The type is ‘float’.

For GLSL shaders the vertex attributes are passed using the following
variables:

al_pos

     vertex position attribute.  Type is ‘vec4’.
al_texcoord

     vertex texture coordinate attribute.  Type is ‘vec2’.
al_color

     vertex color attribute.  Type is ‘vec4’.
al_user_attr_0

     The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR
al_user_attr_1, ..., al_user_attr_9

     The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR + X where X
     is an integer from 1 to 9

For HLSL shaders the vertex attributes are passed using the following
semantics:

POSITION0

     vertex position attribute.  Type is ‘float4’.
TEXCOORD0

     vertex texture coordinate attribute.  Type is ‘float2’.
TEXCOORD1

     vertex color attribute.  Type is ‘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.

   • ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX for “al_projview_matrix”
   • ALLEGRO_SHADER_VAR_POS for “al_pos”
   • ALLEGRO_SHADER_VAR_COLOR for “al_color”
   • ALLEGRO_SHADER_VAR_TEXCOORD for “al_texcoord”
   • ALLEGRO_SHADER_VAR_USE_TEX for “al_use_tex”
   • ALLEGRO_SHADER_VAR_TEX for “al_tex”
   • ALLEGRO_SHADER_VAR_USE_TEX_MATRIX for “al_use_tex_matrix”
   • ALLEGRO_SHADER_VAR_TEX_MATRIX for “al_tex_matrix”
   • ALLEGRO_SHADER_VAR_ALPHA_FUNCTION for “al_alpha_func”
   • ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE for “al_alpha_test_val”

Examine the output of *note al_get_default_shader_source:
#al_get_default_shader_source. for an example of how to use the above
uniforms and attributes.

Returns true on success and false on error, in which case the error log
is updated.  The error log can be retrieved with *note
al_get_shader_log: #al_get_shader_log.

Since: 5.1.0

See also: *note al_attach_shader_source_file:
#al_attach_shader_source_file, *note al_build_shader: #al_build_shader,
*note al_get_default_shader_source: #al_get_default_shader_source, *note
al_get_shader_log: #al_get_shader_log, *note ALLEGRO_PRIM_ATTR:
#allegro_prim_attr.


File: refman.info,  Node: al_attach_shader_source_file,  Next: al_build_shader,  Prev: al_attach_shader_source,  Up: Shader routines

39.6 al_attach_shader_source_file
=================================

bool al_attach_shader_source_file(ALLEGRO_SHADER *shader,
   ALLEGRO_SHADER_TYPE type, const char *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L111)

Like *note al_attach_shader_source: #al_attach_shader_source. but reads
the source code for the shader from the named file.

Returns true on success and false on error, in which case the error log
is updated.  The error log can be retrieved with *note
al_get_shader_log: #al_get_shader_log.

Since: 5.1.0

See also: *note al_attach_shader_source: #al_attach_shader_source, *note
al_build_shader: #al_build_shader, *note al_get_shader_log:
#al_get_shader_log.


File: refman.info,  Node: al_build_shader,  Next: al_get_shader_log,  Prev: al_attach_shader_source_file,  Up: Shader routines

39.7 al_build_shader
====================

bool al_build_shader(ALLEGRO_SHADER *shader)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L144)

This is required before the shader can be used with *note al_use_shader:
#al_use_shader.  It should be called after successfully attaching the
pixel and/or vertex shaders with *note al_attach_shader_source:
#al_attach_shader_source. or *note al_attach_shader_source_file:
#al_attach_shader_source_file.

Returns true on success and false on error, in which case the error log
is updated.  The error log can be retrieved with *note
al_get_shader_log: #al_get_shader_log.

     _Note:_ If you are using the ALLEGRO_PROGRAMMABLE_PIPELINE flag,
     then you must specify both a pixel and a vertex shader sources for
     anything to be rendered.
Since: 5.1.6

See also: *note al_use_shader: #al_use_shader, *note al_get_shader_log:
#al_get_shader_log.


File: refman.info,  Node: al_get_shader_log,  Next: al_get_shader_platform,  Prev: al_build_shader,  Up: Shader routines

39.8 al_get_shader_log
======================

const char *al_get_shader_log(ALLEGRO_SHADER *shader)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L152)

Return a read-only string containing the information log for a shader
program.  The log is updated by certain functions, such as *note
al_attach_shader_source: #al_attach_shader_source. or *note
al_build_shader: #al_build_shader. when there is an error.

This function never returns NULL.

Since: 5.1.0

See also: *note al_attach_shader_source: #al_attach_shader_source, *note
al_attach_shader_source_file: #al_attach_shader_source_file, *note
al_build_shader: #al_build_shader.


File: refman.info,  Node: al_get_shader_platform,  Next: al_use_shader,  Prev: al_get_shader_log,  Up: Shader routines

39.9 al_get_shader_platform
===========================

ALLEGRO_SHADER_PLATFORM al_get_shader_platform(ALLEGRO_SHADER *shader)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L161)

Returns the platform the shader was created with (either
ALLEGRO_SHADER_HLSL or ALLEGRO_SHADER_GLSL).

Since: 5.1.6

See also: *note al_create_shader: #al_create_shader.


File: refman.info,  Node: al_use_shader,  Next: al_destroy_shader,  Prev: al_get_shader_platform,  Up: Shader routines

39.10 al_use_shader
===================

bool al_use_shader(ALLEGRO_SHADER *shader)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L169)

Uses the shader for subsequent drawing operations on the current target
bitmap.  Pass NULL to stop using any shader on the current target
bitmap.

Returns true on success.  Otherwise returns false, e.g. because the
shader is incompatible with the target bitmap.

Since: 5.1.6

See also: *note al_destroy_shader: #al_destroy_shader, *note
al_set_shader_sampler: #al_set_shader_sampler, *note
al_set_shader_matrix: #al_set_shader_matrix, *note al_set_shader_int:
#al_set_shader_int, *note al_set_shader_float: #al_set_shader_float,
*note al_set_shader_bool: #al_set_shader_bool, *note
al_set_shader_int_vector: #al_set_shader_int_vector, *note
al_set_shader_float_vector: #al_set_shader_float_vector.


File: refman.info,  Node: al_destroy_shader,  Next: al_set_shader_sampler,  Prev: al_use_shader,  Up: Shader routines

39.11 al_destroy_shader
=======================

void al_destroy_shader(ALLEGRO_SHADER *shader)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L216)

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 NULL.

Since: 5.1.0

See also: *note al_create_shader: #al_create_shader.


File: refman.info,  Node: al_set_shader_sampler,  Next: al_set_shader_matrix,  Prev: al_destroy_shader,  Up: Shader routines

39.12 al_set_shader_sampler
===========================

bool al_set_shader_sampler(const char *name,
   ALLEGRO_BITMAP *bitmap, int unit)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L256)

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 ‘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
‘NULL’ 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
‘al_tex’ (the ‘al_use_tex’ variable will be set to ‘false’).

Returns true on success.  Otherwise returns false, e.g. if the uniform
by that name does not exist in the shader.

Since: 5.1.0

See also: *note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_set_shader_matrix,  Next: al_set_shader_int,  Prev: al_set_shader_sampler,  Up: Shader routines

39.13 al_set_shader_matrix
==========================

bool al_set_shader_matrix(const char *name,
   const ALLEGRO_TRANSFORM *matrix)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L277)

Sets a matrix uniform of the current target bitmap’s shader.

Returns true on success.  Otherwise returns false, e.g. if the uniform
by that name does not exist in the shader.

Since: 5.1.0

See also: *note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_set_shader_int,  Next: al_set_shader_float,  Prev: al_set_shader_matrix,  Up: Shader routines

39.14 al_set_shader_int
=======================

bool al_set_shader_int(const char *name, int i)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L298)

Sets an integer uniform of the current target bitmap’s shader.

Returns true on success.  Otherwise returns false, e.g. if the uniform
by that name does not exist in the shader.

Since: 5.1.0

See also: *note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_set_shader_float,  Next: al_set_shader_bool,  Prev: al_set_shader_int,  Up: Shader routines

39.15 al_set_shader_float
=========================

bool al_set_shader_float(const char *name, float f)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L318)

Sets a float uniform of the target bitmap’s shader.

Returns true on success.  Otherwise returns false, e.g. if the uniform
by that name does not exist in the shader.

Since: 5.1.0

See also: *note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_set_shader_bool,  Next: al_set_shader_int_vector,  Prev: al_set_shader_float,  Up: Shader routines

39.16 al_set_shader_bool
========================

bool al_set_shader_bool(const char *name, bool b)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L380)

Sets a boolean uniform of the target bitmap’s shader.

Returns true on success.  Otherwise returns false, e.g. if the uniform
by that name does not exist in the shader.

Since: 5.1.6

See also: *note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_set_shader_int_vector,  Next: al_set_shader_float_vector,  Prev: al_set_shader_bool,  Up: Shader routines

39.17 al_set_shader_int_vector
==============================

bool al_set_shader_int_vector(const char *name,
   int num_components, const int *i, int num_elems)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L338)

Sets an integer vector array uniform of the current target bitmap’s
shader.  The ‘num_components’ parameter can take one of the values 1, 2,
3 or 4.  If it is 1 then an array of ‘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 ivec3
flowers[4]’ or an HLSL uniform declared as ‘uniform int3 flowers[4]’,
then you’d use this function from your code like so:

int flowers[4][3] =
{
   {1, 2, 3},
   {4, 5, 6},
   {7, 8, 9},
   {2, 5, 7}
};

al_set_shader_int_vector("flowers", 3, (int*)flowers, 4);

Returns true on success.  Otherwise returns false, e.g. if the uniform
by that name does not exist in the shader.

Since: 5.1.0

See also: *note al_set_shader_float_vector: #al_set_shader_float_vector,
*note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_set_shader_float_vector,  Next: al_get_default_shader_source,  Prev: al_set_shader_int_vector,  Up: Shader routines

39.18 al_set_shader_float_vector
================================

bool al_set_shader_float_vector(const char *name,
   int num_components, const float *f, int num_elems)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L359)

Same as *note al_set_shader_int_vector: #al_set_shader_int_vector.
except all values are float instead of int.

Since: 5.1.0

See also: *note al_set_shader_int_vector: #al_set_shader_int_vector,
*note al_use_shader: #al_use_shader.


File: refman.info,  Node: al_get_default_shader_source,  Prev: al_set_shader_float_vector,  Up: Shader routines

39.19 al_get_default_shader_source
==================================

char const *al_get_default_shader_source(ALLEGRO_SHADER_PLATFORM platform,
   ALLEGRO_SHADER_TYPE type)

Source Code
(https://github.com/liballeg/allegro5/blob/master/src/shader.c#L400)

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

Since: 5.1.6

See also: *note al_attach_shader_source: #al_attach_shader_source.


File: refman.info,  Node: Video streaming addon,  Prev: Shader routines,  Up: Top

40 Video streaming addon
************************

These functions are declared in the following header file.  Link with
allegro_video.

 #include <allegro5/allegro_video.h>

Currently we have an Ogg backend (Theora + Vorbis).  See
<http://xiph.org/> for installation instructions, licensing information
and supported video formats.

* Menu:

* ALLEGRO_VIDEO_EVENT_TYPE::
* ALLEGRO_VIDEO_POSITION_TYPE::
* al_init_video_addon::
* al_is_video_addon_initialized::
* al_shutdown_video_addon::
* al_get_allegro_video_version::
* al_open_video::
* al_identify_video::
* al_identify_video_f::
* al_close_video::
* al_start_video::
* al_start_video_with_voice::
* al_get_video_event_source::
* al_set_video_playing::
* al_is_video_playing::
* al_get_video_audio_rate::
* al_get_video_fps::
* al_get_video_scaled_width::
* al_get_video_scaled_height::
* al_get_video_frame::
* al_get_video_position::
* al_seek_video::


File: refman.info,  Node: ALLEGRO_VIDEO_EVENT_TYPE,  Next: ALLEGRO_VIDEO_POSITION_TYPE,  Up: Video streaming addon

40.1 ALLEGRO_VIDEO_EVENT_TYPE
=============================

enum ALLEGRO_VIDEO_EVENT_TYPE

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/allegro5/allegro_video.h#L35)

Events sent by *note al_get_video_event_source:
#al_get_video_event_source.

* Menu:

* ALLEGRO_EVENT_VIDEO_FRAME_SHOW::
* ALLEGRO_EVENT_VIDEO_FINISHED::


File: refman.info,  Node: ALLEGRO_EVENT_VIDEO_FRAME_SHOW,  Next: ALLEGRO_EVENT_VIDEO_FINISHED,  Up: ALLEGRO_VIDEO_EVENT_TYPE

40.1.1 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 *note
al_get_video_frame: #al_get_video_frame.).  *note al_get_video_frame:
#al_get_video_frame. will continue returning the same frame until the
next ALLEGRO_EVENT_VIDEO_FRAME_SHOW is sent.

user.data1 (ALLEGRO_VIDEO *)

     The video which generated the event.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_EVENT_VIDEO_FINISHED,  Prev: ALLEGRO_EVENT_VIDEO_FRAME_SHOW,  Up: ALLEGRO_VIDEO_EVENT_TYPE

40.1.2 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.

user.data1 (ALLEGRO_VIDEO *)

     The video which generated the event.

Since: 5.1.0


File: refman.info,  Node: ALLEGRO_VIDEO_POSITION_TYPE,  Next: al_init_video_addon,  Prev: ALLEGRO_VIDEO_EVENT_TYPE,  Up: Video streaming addon

40.2 ALLEGRO_VIDEO_POSITION_TYPE
================================

typedef enum ALLEGRO_VIDEO_POSITION_TYPE ALLEGRO_VIDEO_POSITION_TYPE;

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/allegro5/allegro_video.h#L51)

Used with *note al_get_video_position: #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.

   • 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.

   • 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.

   • 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.

Since: 5.1.11


File: refman.info,  Node: al_init_video_addon,  Next: al_is_video_addon_initialized,  Prev: ALLEGRO_VIDEO_POSITION_TYPE,  Up: Video streaming addon

40.3 al_init_video_addon
========================

bool al_init_video_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L268)

Initializes the video addon.

Since: 5.1.12


File: refman.info,  Node: al_is_video_addon_initialized,  Next: al_shutdown_video_addon,  Prev: al_init_video_addon,  Up: Video streaming addon

40.4 al_is_video_addon_initialized
==================================

bool al_is_video_addon_initialized(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L290)

Returns true if the video addon is initialized, otherwise returns false.

Since: 5.2.6


File: refman.info,  Node: al_shutdown_video_addon,  Next: al_get_allegro_video_version,  Prev: al_is_video_addon_initialized,  Up: Video streaming addon

40.5 al_shutdown_video_addon
============================

void al_shutdown_video_addon(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L298)

Shut down the video addon.  This is done automatically at program exit,
but can be called any time the user wishes as well.

Since: 5.1.12


File: refman.info,  Node: al_get_allegro_video_version,  Next: al_open_video,  Prev: al_shutdown_video_addon,  Up: Video streaming addon

40.6 al_get_allegro_video_version
=================================

uint32_t al_get_allegro_video_version(void)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L311)

Returns the (compiled) version of the addon, in the same format as *note
al_get_allegro_version: #al_get_allegro_version.

Since: 5.1.12


File: refman.info,  Node: al_open_video,  Next: al_identify_video,  Prev: al_get_allegro_video_version,  Up: Video streaming addon

40.7 al_open_video
==================

ALLEGRO_VIDEO *al_open_video(char const *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L98)

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.

Since: 5.1.0


File: refman.info,  Node: al_identify_video,  Next: al_identify_video_f,  Prev: al_open_video,  Up: Video streaming addon

40.8 al_identify_video
======================

char const *al_identify_video(char const *filename)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L327)

This works exactly as *note al_identify_video_f: #al_identify_video_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.

Since: 5.2.8

See also: *note al_init_video_addon: #al_init_video_addon, *note
al_identify_video_f: #al_identify_video_f.


File: refman.info,  Node: al_identify_video_f,  Next: al_close_video,  Prev: al_identify_video,  Up: Video streaming addon

40.9 al_identify_video_f
========================

char const *al_identify_video_f(ALLEGRO_FILE *fp)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L319)

Tries to guess the video file type of the open ALLEGRO_FILE by reading
the first few bytes.  By default Allegro cannot recognize any file
types, but calling *note al_init_video_addon: #al_init_video_addon. will
add detection of the types it can read.

Returns a pointer to a static string with a file extension for the type,
including the leading dot.  For example “.ogv”.  Returns NULL if the
video type cannot be determined.

Since: 5.2.8

See also: *note al_init_video_addon: #al_init_video_addon, *note
al_identify_video: #al_identify_video.


File: refman.info,  Node: al_close_video,  Next: al_start_video,  Prev: al_identify_video_f,  Up: Video streaming addon

40.10 al_close_video
====================

void al_close_video(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L139)

Closes the video and frees all allocated resources.  The video pointer
is invalid after the function returns.

Since: 5.1.0


File: refman.info,  Node: al_start_video,  Next: al_start_video_with_voice,  Prev: al_close_video,  Up: Video streaming addon

40.11 al_start_video
====================

void al_start_video(ALLEGRO_VIDEO *video, ALLEGRO_MIXER *mixer)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L161)

Starts streaming the video from the beginning.

Since: 5.1.0


File: refman.info,  Node: al_start_video_with_voice,  Next: al_get_video_event_source,  Prev: al_start_video,  Up: Video streaming addon

40.12 al_start_video_with_voice
===============================

void al_start_video_with_voice(ALLEGRO_VIDEO *video, ALLEGRO_VOICE *voice)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L172)

Like *note al_start_video: #al_start_video. but audio is routed to the
provided voice.

Since: 5.1.0


File: refman.info,  Node: al_get_video_event_source,  Next: al_set_video_playing,  Prev: al_start_video_with_voice,  Up: Video streaming addon

40.13 al_get_video_event_source
===============================

ALLEGRO_EVENT_SOURCE *al_get_video_event_source(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L153)

Get an event source for the video.  The possible events are described
under *note ALLEGRO_VIDEO_EVENT_TYPE: #allegro_video_event_type.

Since: 5.1.0


File: refman.info,  Node: al_set_video_playing,  Next: al_is_video_playing,  Prev: al_get_video_event_source,  Up: Video streaming addon

40.14 al_set_video_playing
==========================

void al_set_video_playing(ALLEGRO_VIDEO *video, bool play)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L183)

Paused or resumes playback.

Since: 5.1.12


File: refman.info,  Node: al_is_video_playing,  Next: al_get_video_audio_rate,  Prev: al_set_video_playing,  Up: Video streaming addon

40.15 al_is_video_playing
=========================

bool al_is_video_playing(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L195)

Returns true if the video is currently playing.

Since: 5.1.12


File: refman.info,  Node: al_get_video_audio_rate,  Next: al_get_video_fps,  Prev: al_is_video_playing,  Up: Video streaming addon

40.16 al_get_video_audio_rate
=============================

double al_get_video_audio_rate(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L236)

Returns the audio rate of the video, in Hz.

Since: 5.1.0


File: refman.info,  Node: al_get_video_fps,  Next: al_get_video_scaled_width,  Prev: al_get_video_audio_rate,  Up: Video streaming addon

40.17 al_get_video_fps
======================

double al_get_video_fps(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L244)

Returns the speed of the video in frames per second.  Often this will
not be an integer value.

Since: 5.1.0


File: refman.info,  Node: al_get_video_scaled_width,  Next: al_get_video_scaled_height,  Prev: al_get_video_fps,  Up: Video streaming addon

40.18 al_get_video_scaled_width
===============================

float al_get_video_scaled_width(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L252)

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.

Since: 5.1.12

See also: *note al_get_video_frame: #al_get_video_frame.


File: refman.info,  Node: al_get_video_scaled_height,  Next: al_get_video_frame,  Prev: al_get_video_scaled_width,  Up: Video streaming addon

40.19 al_get_video_scaled_height
================================

float al_get_video_scaled_height(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L260)

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.

See also: *note al_get_video_frame: #al_get_video_frame.

Since: 5.1.12


File: refman.info,  Node: al_get_video_frame,  Next: al_get_video_position,  Prev: al_get_video_scaled_height,  Up: Video streaming addon

40.20 al_get_video_frame
========================

ALLEGRO_BITMAP *al_get_video_frame(ALLEGRO_VIDEO *video)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L204)

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 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:

float scale = 1.0; /* Adjust this to fit your target bitmap dimensions. */
ALLEGRO_BITMAP* frame = al_get_video_frame(video);
float sw = al_get_bitmap_width(frame);
float sh = al_get_bitmap_height(frame);
float dw = scale * al_get_video_scaled_width(video);
float dh = scale * al_get_video_scaled_height(video);
al_draw_scaled_bitmap(frame, 0, 0, sw, sh, 0, 0, dw, dh, 0);

Since: 5.1.0

See also: *note al_get_video_scaled_width: #al_get_video_scaled_width,
*note al_get_video_scaled_height: #al_get_video_scaled_height.


File: refman.info,  Node: al_get_video_position,  Next: al_seek_video,  Prev: al_get_video_frame,  Up: Video streaming addon

40.21 al_get_video_position
===========================

double al_get_video_position(ALLEGRO_VIDEO *video, ALLEGRO_VIDEO_POSITION_TYPE which)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L214)

Returns the current position of the video stream in seconds since the
beginning.  The parameter is one of the *note
ALLEGRO_VIDEO_POSITION_TYPE: #allegro_video_position_type. constants.

Since: 5.1.0


File: refman.info,  Node: al_seek_video,  Prev: al_get_video_position,  Up: Video streaming addon

40.22 al_seek_video
===================

bool al_seek_video(ALLEGRO_VIDEO *video, double pos_in_seconds)

Source Code
(https://github.com/liballeg/allegro5/blob/master/addons/video/video.c#L227)

Seek to a different position in the video.  Currently only seeking to
the beginning of the video is supported.

Since: 5.1.0



Tag Table:
Node: Top75
Node: Getting started guide1060
Ref: #getting-started-guide1210
Node: Introduction1527
Ref: #introduction1680
Node: Structure of the library and its addons2290
Ref: #structure-of-the-library-and-its-addons2523
Node: The main function3503
Ref: #the-main-function3694
Node: Initialisation4141
Ref: #initialisation4303
Node: Opening a window4758
Ref: #opening-a-window4923
Node: Display an image5384
Ref: #display-an-image5562
Node: Changing the drawing target6063
Ref: #changing-the-drawing-target6269
Node: Event queues and input6993
Ref: #event-queues-and-input7193
Node: Displaying some text8701
Ref: #displaying-some-text8888
Node: Drawing primitives9383
Ref: #drawing-primitives9554
Node: Blending9771
Ref: #blending9907
Node: Sound10367
Ref: #sound10491
Node: Unstable API12285
Ref: #unstable-api12426
Node: Not the end12904
Ref: #not-the-end13029
Node: Configuration files13097
Ref: #configuration-files13248
Node: ALLEGRO_CONFIG15674
Ref: #allegro_config15814
Node: ALLEGRO_CONFIG_SECTION15993
Ref: #allegro_config_section16178
Node: ALLEGRO_CONFIG_ENTRY16560
Ref: #allegro_config_entry16743
Node: al_create_config17110
Ref: #al_create_config17280
Node: al_destroy_config17548
Ref: #al_destroy_config17719
Node: al_load_config_file18037
Ref: #al_load_config_file18217
Node: al_load_config_file_f18632
Ref: #al_load_config_file_f18818
Node: al_save_config_file19231
Ref: #al_save_config_file19415
Node: al_save_config_file_f19771
Ref: #al_save_config_file_f19959
Node: al_add_config_section20313
Ref: #al_add_config_section20508
Node: al_remove_config_section20778
Ref: #al_remove_config_section20979
Node: al_add_config_comment21270
Ref: #al_add_config_comment21463
Node: al_get_config_value22001
Ref: #al_get_config_value22185
Node: al_set_config_value22710
Ref: #al_set_config_value22893
Node: al_remove_config_key23653
Ref: #al_remove_config_key23846
Node: al_get_first_config_section24183
Ref: #al_get_first_config_section24397
Node: al_get_next_config_section25115
Ref: #al_get_next_config_section25332
Node: al_get_first_config_entry25788
Ref: #al_get_first_config_entry26000
Node: al_get_next_config_entry26630
Ref: #al_get_next_config_entry26829
Node: al_merge_config27200
Ref: #al_merge_config27376
Node: al_merge_config_into27866
Ref: #al_merge_config_into28019
Node: Displays28417
Ref: #displays28548
Node: Display creation31050
Ref: #display-creation31181
Node: ALLEGRO_DISPLAY31541
Ref: #allegro_display31680
Node: al_create_display31881
Ref: #al_create_display32051
Node: al_destroy_display33107
Ref: #al_destroy_display33288
Node: al_get_new_display_flags33818
Ref: #al_get_new_display_flags34018
Node: al_set_new_display_flags34336
Ref: #al_set_new_display_flags34543
Node: al_get_new_display_option39729
Ref: #al_get_new_display_option39939
Node: al_set_new_display_option40216
Ref: #al_set_new_display_option40430
Node: al_reset_new_display_options47051
Ref: #al_reset_new_display_options47272
Node: al_get_new_window_position47523
Ref: #al_get_new_window_position47741
Node: al_set_new_window_position48041
Ref: #al_set_new_window_position48264
Node: al_get_new_display_refresh_rate48736
Ref: #al_get_new_display_refresh_rate48974
Node: al_set_new_display_refresh_rate49273
Ref: #al_set_new_display_refresh_rate49476
Node: Display operations50081
Ref: #display-operations50250
Node: al_get_display_event_source50385
Ref: #al_get_display_event_source50562
Node: al_get_backbuffer50881
Ref: #al_get_backbuffer51062
Node: al_flip_display52106
Ref: #al_flip_display52280
Node: al_update_display_region53817
Ref: #al_update_display_region54009
Node: al_wait_for_vsync54685
Ref: #al_wait_for_vsync54839
Node: Display size and position55354
Ref: #display-size-and-position55537
Node: al_get_display_width55792
Ref: #al_get_display_width55959
Node: al_get_display_height56229
Ref: #al_get_display_height56424
Node: al_resize_display56694
Ref: #al_resize_display56882
Node: al_acknowledge_resize57332
Ref: #al_acknowledge_resize57529
Node: al_get_window_position58391
Ref: #al_get_window_position58595
Node: al_set_window_position58863
Ref: #al_set_window_position59071
Node: al_get_window_constraints59347
Ref: #al_get_window_constraints59564
Node: al_set_window_constraints59904
Ref: #al_set_window_constraints60126
Node: al_apply_window_constraints60832
Ref: #al_apply_window_constraints61024
Node: Display settings62304
Ref: #display-settings62464
Node: al_get_display_flags62831
Ref: #al_get_display_flags62987
Node: al_set_display_flag63669
Ref: #al_set_display_flag63853
Node: al_get_display_option64630
Ref: #al_get_display_option64819
Node: al_set_display_option65096
Ref: #al_set_display_option65287
Node: al_get_display_format66403
Ref: #al_get_display_format66599
Node: al_get_display_orientation66836
Ref: #al_get_display_orientation67048
Node: al_get_display_refresh_rate67588
Ref: #al_get_display_refresh_rate67800
Node: al_set_window_title68065
Ref: #al_set_window_title68258
Node: al_set_new_window_title68552
Ref: #al_set_new_window_title68759
Node: ALLEGRO_NEW_WINDOW_TITLE_MAX_SIZE69389
Ref: #allegro_new_window_title_max_size69622
Node: al_get_new_window_title69965
Ref: #al_get_new_window_title70174
Node: al_set_display_icon70878
Ref: #al_set_display_icon71066
Node: al_set_display_icons71465
Ref: #al_set_display_icons71623
Node: Drawing halts72345
Ref: #drawing-halts72485
Node: al_acknowledge_drawing_halt72561
Ref: #al_acknowledge_drawing_halt72745
Node: al_acknowledge_drawing_resume73430
Ref: #al_acknowledge_drawing_resume73618
Node: Screensaver73991
Ref: #screensaver74120
Node: al_inhibit_screensaver74157
Ref: #al_inhibit_screensaver74286
Node: Clipboard74674
Ref: #clipboard74777
Node: al_get_clipboard_text75058
Ref: #al_get_clipboard_text75212
Node: al_set_clipboard_text76016
Ref: #al_set_clipboard_text76200
Node: al_clipboard_has_text76558
Ref: #al_clipboard_has_text76712
Node: Event system and events77059
Ref: #event-system-and-events77209
Node: ALLEGRO_EVENT79197
Ref: #allegro_event79334
Node: ALLEGRO_EVENT_JOYSTICK_AXIS81274
Ref: #allegro_event_joystick_axis81463
Node: ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN81907
Ref: #allegro_event_joystick_button_down82151
Node: ALLEGRO_EVENT_JOYSTICK_BUTTON_UP82341
Ref: #allegro_event_joystick_button_up82590
Node: ALLEGRO_EVENT_JOYSTICK_CONFIGURATION82782
Ref: #allegro_event_joystick_configuration83027
Node: ALLEGRO_EVENT_KEY_DOWN83145
Ref: #allegro_event_key_down83350
Node: ALLEGRO_EVENT_KEY_UP83827
Ref: #allegro_event_key_up84014
Node: ALLEGRO_EVENT_KEY_CHAR84339
Ref: #allegro_event_key_char84532
Node: ALLEGRO_EVENT_MOUSE_AXES86316
Ref: #allegro_event_mouse_axes86524
Node: ALLEGRO_EVENT_MOUSE_BUTTON_DOWN87880
Ref: #allegro_event_mouse_button_down88109
Node: ALLEGRO_EVENT_MOUSE_BUTTON_UP88506
Ref: #allegro_event_mouse_button_up88735
Node: ALLEGRO_EVENT_MOUSE_WARPED89134
Ref: #allegro_event_mouse_warped89359
Node: ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY89494
Ref: #allegro_event_mouse_enter_display89737
Node: ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY90003
Ref: #allegro_event_mouse_leave_display90245
Node: ALLEGRO_EVENT_TOUCH_BEGIN90526
Ref: #allegro_event_touch_begin90742
Node: ALLEGRO_EVENT_TOUCH_END91376
Ref: #allegro_event_touch_end91579
Node: ALLEGRO_EVENT_TOUCH_MOVE91694
Ref: #allegro_event_touch_move91900
Node: ALLEGRO_EVENT_TOUCH_CANCEL92033
Ref: #allegro_event_touch_cancel92239
Node: ALLEGRO_EVENT_TIMER92521
Ref: #allegro_event_timer92717
Node: ALLEGRO_EVENT_DISPLAY_EXPOSE92896
Ref: #allegro_event_display_expose93112
Node: ALLEGRO_EVENT_DISPLAY_RESIZE93720
Ref: #allegro_event_display_resize93944
Node: ALLEGRO_EVENT_DISPLAY_CLOSE94554
Ref: #allegro_event_display_close94774
Node: ALLEGRO_EVENT_DISPLAY_LOST94896
Ref: #allegro_event_display_lost95113
Node: ALLEGRO_EVENT_DISPLAY_FOUND96093
Ref: #allegro_event_display_found96317
Node: ALLEGRO_EVENT_DISPLAY_SWITCH_OUT96518
Ref: #allegro_event_display_switch_out96757
Node: ALLEGRO_EVENT_DISPLAY_SWITCH_IN97179
Ref: #allegro_event_display_switch_in97422
Node: ALLEGRO_EVENT_DISPLAY_ORIENTATION97538
Ref: #allegro_event_display_orientation97787
Node: ALLEGRO_EVENT_DISPLAY_HALT_DRAWING98308
Ref: #allegro_event_display_halt_drawing98564
Node: ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING100323
Ref: #allegro_event_display_resume_drawing100581
Node: ALLEGRO_EVENT_DISPLAY_CONNECTED101414
Ref: #allegro_event_display_connected101662
Node: ALLEGRO_EVENT_DISPLAY_DISCONNECTED101980
Ref: #allegro_event_display_disconnected102189
Node: ALLEGRO_USER_EVENT102501
Ref: #allegro_user_event102676
Node: ALLEGRO_EVENT_QUEUE104051
Ref: #allegro_event_queue104235
Node: ALLEGRO_EVENT_SOURCE104723
Ref: #allegro_event_source104909
Node: ALLEGRO_EVENT_TYPE105548
Ref: #allegro_event_type105733
Node: ALLEGRO_GET_EVENT_TYPE106102
Ref: #allegro_get_event_type106301
Node: ALLEGRO_EVENT_TYPE_IS_USER107490
Ref: #allegro_event_type_is_user107700
Node: al_create_event_queue108011
Ref: #al_create_event_queue108211
Node: al_destroy_event_queue108637
Ref: #al_destroy_event_queue108837
Node: al_register_event_source109246
Ref: #al_register_event_source109457
Node: al_unregister_event_source109998
Ref: #al_unregister_event_source110220
Node: al_is_event_source_registered110730
Ref: #al_is_event_source_registered110954
Node: al_pause_event_queue111269
Ref: #al_pause_event_queue111473
Node: al_is_event_queue_paused112118
Ref: #al_is_event_queue_paused112324
Node: al_is_event_queue_empty112590
Ref: #al_is_event_queue_empty112791
Node: al_get_next_event113096
Ref: #al_get_next_event113279
Node: al_peek_next_event113842
Ref: #al_peek_next_event114022
Node: al_drop_next_event114612
Ref: #al_drop_next_event114795
Node: al_flush_event_queue115175
Ref: #al_flush_event_queue115361
Node: al_wait_for_event115656
Ref: #al_wait_for_event115841
Node: al_wait_for_event_timed116464
Ref: #al_wait_for_event_timed116664
Node: al_wait_for_event_until117497
Ref: #al_wait_for_event_until117705
Node: al_init_user_event_source118618
Ref: #al_init_user_event_source118835
Node: al_destroy_user_event_source120358
Ref: #al_destroy_user_event_source120576
Node: al_emit_user_event120959
Ref: #al_emit_user_event121151
Node: al_unref_user_event123247
Ref: #al_unref_user_event123437
Node: al_get_event_source_data124026
Ref: #al_get_event_source_data124232
Node: al_set_event_source_data124567
Ref: #al_set_event_source_data124745
Node: File I/O125171
Ref: #file-io125308
Node: ALLEGRO_FILE126000
Ref: #allegro_file126123
Node: ALLEGRO_FILE_INTERFACE126357
Ref: #allegro_file_interface126521
Node: ALLEGRO_SEEK128151
Ref: #allegro_seek128291
Node: al_fopen128630
Ref: #al_fopen128758
Node: al_fopen_interface130071
Ref: #al_fopen_interface130221
Node: al_fopen_slice130586
Ref: #al_fopen_slice130729
Node: al_fclose132465
Ref: #al_fclose132588
Node: al_fread132847
Ref: #al_fread132963
Node: al_fwrite133665
Ref: #al_fwrite133783
Node: al_fflush134344
Ref: #al_fflush134464
Node: al_ftell134748
Ref: #al_ftell134865
Node: al_fseek135217
Ref: #al_fseek135332
Node: al_feof136130
Ref: #al_feof136244
Node: al_ferror136857
Ref: #al_ferror136977
Node: al_ferrmsg137360
Ref: #al_ferrmsg137487
Node: al_fclearerr137895
Ref: #al_fclearerr138027
Node: al_fungetc138540
Ref: #al_fungetc138666
Node: al_fsize139525
Ref: #al_fsize139643
Node: al_fgetc139830
Ref: #al_fgetc139946
Node: al_fputc140198
Ref: #al_fputc140316
Node: al_fprintf140686
Ref: #al_fprintf140811
Node: al_vfprintf141125
Ref: #al_vfprintf141256
Node: al_fread16le141621
Ref: #al_fread16le141756
Node: al_fread16be142236
Ref: #al_fread16be142373
Node: al_fwrite16le142850
Ref: #al_fwrite16le142990
Node: al_fwrite16be143304
Ref: #al_fwrite16be143444
Node: al_fread32le143755
Ref: #al_fread32le143892
Node: al_fread32be144372
Ref: #al_fread32be144509
Node: al_fwrite32le144985
Ref: #al_fwrite32le145125
Node: al_fwrite32be145439
Ref: #al_fwrite32be145575
Node: al_fgets145886
Ref: #al_fgets146011
Node: al_fget_ustr146766
Ref: #al_fget_ustr146894
Node: al_fputs147528
Ref: #al_fputs147670
Node: Standard I/O specific routines148299
Ref: #standard-io-specific-routines148497
Node: al_fopen_fd148545
Ref: #al_fopen_fd148688
Node: al_make_temp_file149319
Ref: #al_make_temp_file149474
Node: Alternative file streams150205
Ref: #alternative-file-streams150374
Node: al_set_new_file_interface151260
Ref: #al_set_new_file_interface151452
Node: al_set_standard_file_interface151943
Ref: #al_set_standard_file_interface152179
Node: al_get_new_file_interface152566
Ref: #al_get_new_file_interface152788
Node: al_create_file_handle153143
Ref: #al_create_file_handle153347
Node: al_get_file_userdata153937
Ref: #al_get_file_userdata154105
Node: Fixed point math routines154418
Ref: #fixed-point-math-routines154586
Node: al_fixed154868
Ref: #al_fixed154983
Node: al_itofix156487
Ref: #al_itofix156622
Node: al_fixtoi157434
Ref: #al_fixtoi157572
Node: al_fixfloor158100
Ref: #al_fixfloor158243
Node: al_fixceil158706
Ref: #al_fixceil158847
Node: al_ftofix159300
Ref: #al_ftofix159437
Node: al_fixtof160252
Ref: #al_fixtof160388
Node: al_fixmul160833
Ref: #al_fixmul160969
Node: al_fixdiv162090
Ref: #al_fixdiv162226
Node: al_fixadd163463
Ref: #al_fixadd163601
Node: al_fixsub164594
Ref: #al_fixsub164739
Node: Fixed point trig165777
Ref: #fixed-point-trig165918
Node: al_fixtorad_r166732
Ref: #al_fixtorad_r166863
Node: al_radtofix_r167409
Ref: #al_radtofix_r167558
Node: al_fixsin168014
Ref: #al_fixsin168151
Node: al_fixcos168675
Ref: #al_fixcos168808
Node: al_fixtan169367
Ref: #al_fixtan169501
Node: al_fixasin170122
Ref: #al_fixasin170259
Node: al_fixacos171188
Ref: #al_fixacos171326
Node: al_fixatan172030
Ref: #al_fixatan172169
Node: al_fixatan2172675
Ref: #al_fixatan2172816
Node: al_fixsqrt173722
Ref: #al_fixsqrt173864
Node: al_fixhypot174123
Ref: #al_fixhypot174247
Node: File system routines174547
Ref: #file-system-routines174713
Node: ALLEGRO_FS_ENTRY175439
Ref: #allegro_fs_entry175581
Node: ALLEGRO_FILE_MODE175906
Ref: #allegro_file_mode176077
Node: al_create_fs_entry176482
Ref: #al_create_fs_entry176658
Node: al_destroy_fs_entry176956
Ref: #al_destroy_fs_entry177137
Node: al_get_fs_entry_name177447
Ref: #al_get_fs_entry_name177630
Node: al_update_fs_entry178349
Ref: #al_update_fs_entry178529
Node: al_get_fs_entry_mode179153
Ref: #al_get_fs_entry_mode179338
Node: al_get_fs_entry_atime179667
Ref: #al_get_fs_entry_atime179857
Node: al_get_fs_entry_ctime180384
Ref: #al_get_fs_entry_ctime180575
Node: al_get_fs_entry_mtime180958
Ref: #al_get_fs_entry_mtime181150
Node: al_get_fs_entry_size181526
Ref: #al_get_fs_entry_size181713
Node: al_fs_entry_exists182008
Ref: #al_fs_entry_exists182188
Node: al_remove_fs_entry182556
Ref: #al_remove_fs_entry182734
Node: al_filename_exists183110
Ref: #al_filename_exists183288
Node: al_remove_filename183598
Ref: #al_remove_filename183777
Node: Directory functions184258
Ref: #directory-functions184453
Node: al_open_directory184688
Ref: #al_open_directory184838
Node: al_read_directory185310
Ref: #al_read_directory185487
Node: al_close_directory186139
Ref: #al_close_directory186325
Node: al_get_current_directory186703
Ref: #al_get_current_directory186903
Node: al_change_directory187407
Ref: #al_change_directory187596
Node: al_make_directory187818
Ref: #al_make_directory187995
Node: al_open_fs_entry188426
Ref: #al_open_fs_entry188614
Node: ALLEGRO_FOR_EACH_FS_ENTRY_RESULT189188
Ref: #allegro_for_each_fs_entry_result189411
Node: al_for_each_fs_entry190051
Ref: #al_for_each_fs_entry190225
Node: Alternative filesystem functions192803
Ref: #alternative-filesystem-functions192997
Node: ALLEGRO_FS_INTERFACE193485
Ref: #allegro_fs_interface193659
Node: al_set_fs_interface195136
Ref: #al_set_fs_interface195345
Node: al_set_standard_fs_interface195742
Ref: #al_set_standard_fs_interface195968
Node: al_get_fs_interface196257
Ref: #al_get_fs_interface196437
Node: Fullscreen modes196780
Ref: #fullscreen-modes196930
Node: ALLEGRO_DISPLAY_MODE197113
Ref: #allegro_display_mode197265
Node: al_get_display_mode197961
Ref: #al_get_display_mode198144
Node: al_get_num_display_modes198878
Ref: #al_get_num_display_modes199042
Node: Graphics routines199635
Ref: #graphics-routines199782
Node: Colors200126
Ref: #colors200243
Node: ALLEGRO_COLOR200451
Ref: #allegro_color200567
Node: al_map_rgb200925
Ref: #al_map_rgb201056
Node: al_map_rgb_f201499
Ref: #al_map_rgb_f201632
Node: al_map_rgba202051
Ref: #al_map_rgba202186
Node: al_premul_rgba202629
Ref: #al_premul_rgba202771
Node: al_map_rgba_f203789
Ref: #al_map_rgba_f203934
Node: al_premul_rgba_f204353
Ref: #al_premul_rgba_f204502
Node: al_unmap_rgb205480
Ref: #al_unmap_rgb205622
Node: al_unmap_rgb_f206083
Ref: #al_unmap_rgb_f206226
Node: al_unmap_rgba206684
Ref: #al_unmap_rgba206830
Node: al_unmap_rgba_f207313
Ref: #al_unmap_rgba_f207440
Node: Locking and pixel formats207893
Ref: #locking-and-pixel-formats208072
Node: ALLEGRO_LOCKED_REGION208398
Ref: #allegro_locked_region208567
Node: ALLEGRO_PIXEL_FORMAT210211
Ref: #allegro_pixel_format210404
Node: al_get_pixel_size216637
Ref: #al_get_pixel_size216827
Node: al_get_pixel_format_bits217205
Ref: #al_get_pixel_format_bits217412
Node: al_get_pixel_block_size217782
Ref: #al_get_pixel_block_size217994
Node: al_get_pixel_block_width218392
Ref: #al_get_pixel_block_width218607
Node: al_get_pixel_block_height218984
Ref: #al_get_pixel_block_height219192
Node: al_lock_bitmap219569
Ref: #al_lock_bitmap219752
Node: al_lock_bitmap_region222375
Ref: #al_lock_bitmap_region222563
Node: al_unlock_bitmap223730
Ref: #al_unlock_bitmap223918
Node: al_lock_bitmap_blocked224460
Ref: #al_lock_bitmap_blocked224668
Node: al_lock_bitmap_region_blocked225646
Ref: #al_lock_bitmap_region_blocked225843
Node: Bitmap creation226444
Ref: #bitmap-creation226614
Node: ALLEGRO_BITMAP227118
Ref: #allegro_bitmap227252
Node: al_create_bitmap227442
Ref: #al_create_bitmap227609
Node: al_create_sub_bitmap231237
Ref: #al_create_sub_bitmap231413
Node: al_clone_bitmap232677
Ref: #al_clone_bitmap232844
Node: al_convert_bitmap233549
Ref: #al_convert_bitmap233725
Node: al_convert_memory_bitmaps234528
Ref: #al_convert_memory_bitmaps234722
Node: al_destroy_bitmap235588
Ref: #al_destroy_bitmap235772
Node: al_get_new_bitmap_flags236368
Ref: #al_get_new_bitmap_flags236563
Node: al_get_new_bitmap_format236796
Ref: #al_get_new_bitmap_format236999
Node: al_set_new_bitmap_flags237287
Ref: #al_set_new_bitmap_flags237489
Node: al_add_new_bitmap_flag241491
Ref: #al_add_new_bitmap_flag241691
Node: al_set_new_bitmap_format242090
Ref: #al_set_new_bitmap_format242294
Node: al_set_new_bitmap_depth242774
Ref: #al_set_new_bitmap_depth242977
Node: al_get_new_bitmap_depth243521
Ref: #al_get_new_bitmap_depth243725
Node: al_set_new_bitmap_samples244150
Ref: #al_set_new_bitmap_samples244360
Node: al_get_new_bitmap_samples245725
Ref: #al_get_new_bitmap_samples245934
Node: al_set_new_bitmap_wrap246367
Ref: #al_set_new_bitmap_wrap246567
Node: al_get_new_bitmap_wrap247629
Ref: #al_get_new_bitmap_wrap247823
Node: ALLEGRO_BITMAP_WRAP248107
Ref: #allegro_bitmap_wrap248264
Node: Bitmap properties249053
Ref: #bitmap-properties249220
Node: al_get_bitmap_flags249766
Ref: #al_get_bitmap_flags249921
Node: al_get_bitmap_format250165
Ref: #al_get_bitmap_format250351
Node: al_get_bitmap_height250641
Ref: #al_get_bitmap_height250827
Node: al_get_bitmap_width251002
Ref: #al_get_bitmap_width251185
Node: al_get_bitmap_depth251358
Ref: #al_get_bitmap_depth251542
Node: al_get_bitmap_samples251937
Ref: #al_get_bitmap_samples252118
Node: al_get_pixel252520
Ref: #al_get_pixel252683
Node: al_is_bitmap_locked253163
Ref: #al_is_bitmap_locked253342
Node: al_is_compatible_bitmap253677
Ref: #al_is_compatible_bitmap253868
Node: al_is_sub_bitmap254836
Ref: #al_is_sub_bitmap255016
Node: al_get_parent_bitmap255330
Ref: #al_get_parent_bitmap255510
Node: al_get_bitmap_x256441
Ref: #al_get_bitmap_x256610
Node: al_get_bitmap_y256969
Ref: #al_get_bitmap_y257136
Node: al_reparent_bitmap257495
Ref: #al_reparent_bitmap257674
Node: al_get_bitmap_blender258489
Ref: #al_get_bitmap_blender258689
Node: al_get_separate_bitmap_blender259148
Ref: #al_get_separate_bitmap_blender259373
Node: al_get_bitmap_blend_color259888
Ref: #al_get_bitmap_blend_color260103
Node: al_set_bitmap_blender260454
Ref: #al_set_bitmap_blender260661
Node: al_set_separate_bitmap_blender261498
Ref: #al_set_separate_bitmap_blender261723
Node: al_set_bitmap_blend_color262390
Ref: #al_set_bitmap_blend_color262607
Node: al_reset_bitmap_blender263035
Ref: #al_reset_bitmap_blender263209
Node: Drawing operations263711
Ref: #drawing-operations263878
Node: al_clear_to_color264549
Ref: #al_clear_to_color264700
Node: al_clear_depth_buffer265064
Ref: #al_clear_depth_buffer265246
Node: al_draw_bitmap266241
Ref: #al_draw_bitmap266413
Node: al_draw_tinted_bitmap267829
Ref: #al_draw_tinted_bitmap268015
Node: al_draw_bitmap_region268835
Ref: #al_draw_bitmap_region269035
Node: al_draw_tinted_bitmap_region269906
Ref: #al_draw_tinted_bitmap_region270112
Node: al_draw_pixel270651
Ref: #al_draw_pixel270828
Node: al_draw_rotated_bitmap271843
Ref: #al_draw_rotated_bitmap272039
Node: al_draw_tinted_rotated_bitmap273410
Ref: #al_draw_tinted_rotated_bitmap273636
Node: al_draw_scaled_rotated_bitmap274168
Ref: #al_draw_scaled_rotated_bitmap274410
Node: al_draw_tinted_scaled_rotated_bitmap275519
Ref: #al_draw_tinted_scaled_rotated_bitmap275789
Node: al_draw_tinted_scaled_rotated_bitmap_region276373
Ref: #al_draw_tinted_scaled_rotated_bitmap_region276649
Node: al_draw_scaled_bitmap277671
Ref: #al_draw_scaled_bitmap277895
Node: al_draw_tinted_scaled_bitmap278805
Ref: #al_draw_tinted_scaled_bitmap279020
Node: al_get_target_bitmap279579
Ref: #al_get_target_bitmap279769
Node: al_put_pixel280003
Ref: #al_put_pixel280169
Node: al_put_blended_pixel280753
Ref: #al_put_blended_pixel280906
Node: Target bitmap281258
Ref: #target-bitmap281412
Node: al_set_target_bitmap281503
Ref: #al_set_target_bitmap281661
Node: al_set_target_backbuffer284855
Ref: #al_set_target_backbuffer285052
Node: al_get_current_display285360
Ref: #al_get_current_display285524
Node: Blending modes285804
Ref: #blending-modes285950
Node: al_get_blender286100
Ref: #al_get_blender286240
Node: al_get_separate_blender286585
Ref: #al_get_separate_blender286770
Node: al_get_blend_color287174
Ref: #al_get_blend_color287349
Node: al_set_blender287662
Ref: #al_set_blender287829
Node: al_set_separate_blender291616
Ref: #al_set_separate_blender291801
Node: al_set_blend_color292406
Ref: #al_set_blend_color292558
Node: Clipping292980
Ref: #clipping293127
Node: al_get_clipping_rectangle293229
Ref: #al_get_clipping_rectangle293398
Node: al_set_clipping_rectangle293667
Ref: #al_set_clipping_rectangle293872
Node: al_reset_clipping_rectangle294289
Ref: #al_reset_clipping_rectangle294464
Node: Graphics utility functions294868
Ref: #graphics-utility-functions295053
Node: al_convert_mask_to_alpha295092
Ref: #al_convert_mask_to_alpha295242
Node: Deferred drawing295606
Ref: #deferred-drawing295774
Node: al_hold_bitmap_drawing295841
Ref: #al_hold_bitmap_drawing296011
Node: al_is_bitmap_drawing_held297385
Ref: #al_is_bitmap_drawing_held297561
Node: Image I/O297819
Ref: #image-io297959
Node: al_register_bitmap_loader298305
Ref: #al_register_bitmap_loader298476
Node: al_register_bitmap_saver299250
Ref: #al_register_bitmap_saver299455
Node: al_register_bitmap_loader_f300224
Ref: #al_register_bitmap_loader_f300436
Node: al_register_bitmap_saver_f301155
Ref: #al_register_bitmap_saver_f301355
Node: al_load_bitmap302066
Ref: #al_load_bitmap302235
Node: al_load_bitmap_flags303237
Ref: #al_load_bitmap_flags303408
Node: al_load_bitmap_f307404
Ref: #al_load_bitmap_f307575
Node: al_load_bitmap_flags_f308670
Ref: #al_load_bitmap_flags_f308847
Node: al_save_bitmap309837
Ref: #al_save_bitmap309998
Node: al_save_bitmap_f310644
Ref: #al_save_bitmap_f310818
Node: al_register_bitmap_identifier311627
Ref: #al_register_bitmap_identifier311831
Node: al_identify_bitmap312972
Ref: #al_identify_bitmap313158
Node: al_identify_bitmap_f313758
Ref: #al_identify_bitmap_f313910
Node: Render State314828
Ref: #render-state314949
Node: ALLEGRO_RENDER_STATE315120
Ref: #allegro_render_state315278
Node: ALLEGRO_RENDER_FUNCTION317187
Ref: #allegro_render_function317384
Node: ALLEGRO_WRITE_MASK_FLAGS317867
Ref: #allegro_write_mask_flags318065
Node: al_set_render_state318602
Ref: #al_set_render_state318789
Node: al_backup_dirty_bitmap319305
Ref: #al_backup_dirty_bitmap319497
Node: al_backup_dirty_bitmaps320381
Ref: #al_backup_dirty_bitmaps320547
Node: Haptic routines320914
Ref: #haptic-routines321060
Node: ALLEGRO_HAPTIC322429
Ref: #allegro_haptic322569
Node: ALLEGRO_HAPTIC_CONSTANTS323096
Ref: #allegro_haptic_constants323286
Node: ALLEGRO_HAPTIC_EFFECT325257
Ref: #allegro_haptic_effect325451
Node: ALLEGRO_HAPTIC_EFFECT_ID336782
Ref: #allegro_haptic_effect_id336975
Node: al_install_haptic337545
Ref: #al_install_haptic337722
Node: al_uninstall_haptic338868
Ref: #al_uninstall_haptic339047
Node: al_is_haptic_installed339734
Ref: #al_is_haptic_installed339920
Node: al_is_mouse_haptic340317
Ref: #al_is_mouse_haptic340497
Node: al_is_keyboard_haptic340897
Ref: #al_is_keyboard_haptic341081
Node: al_is_display_haptic341491
Ref: #al_is_display_haptic341678
Node: al_is_joystick_haptic342183
Ref: #al_is_joystick_haptic342375
Node: al_is_touch_input_haptic342784
Ref: #al_is_touch_input_haptic342986
Node: al_get_haptic_from_mouse343412
Ref: #al_get_haptic_from_mouse343620
Node: al_get_haptic_from_keyboard344081
Ref: #al_get_haptic_from_keyboard344297
Node: al_get_haptic_from_display344767
Ref: #al_get_haptic_from_display344984
Node: al_get_haptic_from_joystick345451
Ref: #al_get_haptic_from_joystick345673
Node: al_get_haptic_from_touch_input346361
Ref: #al_get_haptic_from_touch_input346580
Node: al_release_haptic347066
Ref: #al_release_haptic347251
Node: al_is_haptic_active348153
Ref: #al_is_haptic_active348338
Node: al_get_haptic_capabilities348747
Ref: #al_get_haptic_capabilities348949
Node: al_is_haptic_capable349471
Ref: #al_is_haptic_capable349660
Node: al_set_haptic_gain350323
Ref: #al_set_haptic_gain350500
Node: al_get_haptic_gain351342
Ref: #al_get_haptic_gain351523
Node: al_set_haptic_autocenter352326
Ref: #al_set_haptic_autocenter352525
Node: al_get_haptic_autocenter353820
Ref: #al_get_haptic_autocenter354026
Node: al_get_max_haptic_effects355234
Ref: #al_get_max_haptic_effects355440
Node: al_is_haptic_effect_ok355981
Ref: #al_is_haptic_effect_ok356180
Node: al_upload_haptic_effect356707
Ref: #al_upload_haptic_effect356904
Node: al_play_haptic_effect357974
Ref: #al_play_haptic_effect358177
Node: al_upload_and_play_haptic_effect359163
Ref: #al_upload_and_play_haptic_effect359386
Node: al_stop_haptic_effect360539
Ref: #al_stop_haptic_effect360746
Node: al_is_haptic_effect_playing361426
Ref: #al_is_haptic_effect_playing361642
Node: al_get_haptic_effect_duration362452
Ref: #al_get_haptic_effect_duration362675
Node: al_release_haptic_effect363222
Ref: #al_release_haptic_effect363424
Node: al_rumble_haptic364786
Ref: #al_rumble_haptic364934
Node: Joystick routines366349
Ref: #joystick-routines366499
Node: ALLEGRO_JOYSTICK367664
Ref: #allegro_joystick367810
Node: ALLEGRO_JOYSTICK_STATE368074
Ref: #allegro_joystick_state368257
Node: ALLEGRO_JOYFLAGS368767
Ref: #allegro_joyflags368941
Node: al_install_joystick369334
Ref: #al_install_joystick369513
Node: al_uninstall_joystick369818
Ref: #al_uninstall_joystick370009
Node: al_is_joystick_installed370440
Ref: #al_is_joystick_installed370642
Node: al_reconfigure_joysticks370850
Ref: #al_reconfigure_joysticks371051
Node: al_get_num_joysticks372646
Ref: #al_get_num_joysticks372830
Node: al_get_joystick373324
Ref: #al_get_joystick373493
Node: al_release_joystick374332
Ref: #al_release_joystick374513
Node: al_get_joystick_active374734
Ref: #al_get_joystick_active374926
Node: al_get_joystick_name375422
Ref: #al_get_joystick_name375617
Node: al_get_joystick_stick_name375995
Ref: #al_get_joystick_stick_name376205
Node: al_get_joystick_axis_name376587
Ref: #al_get_joystick_axis_name376802
Node: al_get_joystick_button_name377206
Ref: #al_get_joystick_button_name377426
Node: al_get_joystick_stick_flags377894
Ref: #al_get_joystick_stick_flags378115
Node: al_get_joystick_num_sticks378433
Ref: #al_get_joystick_num_sticks378649
Node: al_get_joystick_num_axes379009
Ref: #al_get_joystick_num_axes379221
Node: al_get_joystick_num_buttons379539
Ref: #al_get_joystick_num_buttons379752
Node: al_get_joystick_state380010
Ref: #al_get_joystick_state380215
Node: al_get_joystick_event_source380605
Ref: #al_get_joystick_event_source380788
Node: Keyboard routines381064
Ref: #keyboard-routines381225
Node: ALLEGRO_KEYBOARD_STATE381629
Ref: #allegro_keyboard_state381780
Node: Key codes382354
Ref: #key-codes382511
Node: Keyboard modifier flags384709
Ref: #keyboard-modifier-flags384891
Node: al_install_keyboard385418
Ref: #al_install_keyboard385607
Node: al_is_keyboard_installed385976
Ref: #al_is_keyboard_installed386173
Node: al_uninstall_keyboard386384
Ref: #al_uninstall_keyboard386577
Node: al_get_keyboard_state386953
Ref: #al_get_keyboard_state387145
Node: al_clear_keyboard_state387570
Ref: #al_clear_keyboard_state387756
Node: al_key_down388800
Ref: #al_key_down388959
Node: al_keycode_to_name389248
Ref: #al_keycode_to_name389420
Node: al_set_keyboard_leds389605
Ref: #al_set_keyboard_leds389798
Node: al_get_keyboard_event_source390307
Ref: #al_get_keyboard_event_source390489
Node: Memory management routines390815
Ref: #memory-management-routines390999
Node: al_malloc391323
Ref: #al_malloc391442
Node: al_free391933
Ref: #al_free392067
Node: al_realloc392679
Ref: #al_realloc392819
Node: al_calloc393210
Ref: #al_calloc393363
Node: al_malloc_with_context393749
Ref: #al_malloc_with_context393938
Node: al_free_with_context394327
Ref: #al_free_with_context394526
Node: al_realloc_with_context394907
Ref: #al_realloc_with_context395112
Node: al_calloc_with_context395516
Ref: #al_calloc_with_context395723
Node: ALLEGRO_MEMORY_INTERFACE396126
Ref: #allegro_memory_interface396337
Node: al_set_memory_interface396976
Ref: #al_set_memory_interface397156
Node: Miscellaneous routines397826
Ref: #miscellaneous-routines397993
Node: ALLEGRO_PI398129
Ref: #allegro_pi398251
Node: al_run_main398498
Ref: #al_run_main398622
Node: Monitors399315
Ref: #monitors399442
Node: ALLEGRO_MONITOR_INFO399743
Ref: #allegro_monitor_info399896
Node: al_get_new_display_adapter400541
Ref: #al_get_new_display_adapter400741
Node: al_set_new_display_adapter401164
Ref: #al_set_new_display_adapter401363
Node: al_get_monitor_info401970
Ref: #al_get_monitor_info402147
Node: al_get_monitor_dpi402775
Ref: #al_get_monitor_dpi402949
Node: al_get_num_video_adapters403223
Ref: #al_get_num_video_adapters403419
Node: al_get_monitor_refresh_rate403995
Ref: #al_get_monitor_refresh_rate404168
Node: Mouse routines404567
Ref: #mouse-routines404699
Node: ALLEGRO_MOUSE_STATE405223
Ref: #allegro_mouse_state405369
Node: al_install_mouse406085
Ref: #al_install_mouse406255
Node: al_is_mouse_installed406494
Ref: #al_is_mouse_installed406673
Node: al_uninstall_mouse406874
Ref: #al_uninstall_mouse407052
Node: al_get_mouse_num_axes407359
Ref: #al_get_mouse_num_axes407546
Node: al_get_mouse_num_buttons407804
Ref: #al_get_mouse_num_buttons407997
Node: al_get_mouse_state408257
Ref: #al_get_mouse_state408440
Node: al_get_mouse_state_axis409218
Ref: #al_get_mouse_state_axis409407
Node: al_mouse_button_down409851
Ref: #al_mouse_button_down410031
Node: al_set_mouse_xy410491
Ref: #al_set_mouse_xy410654
Node: al_set_mouse_z411145
Ref: #al_set_mouse_z411300
Node: al_set_mouse_w411555
Ref: #al_set_mouse_w411712
Node: al_set_mouse_axis411974
Ref: #al_set_mouse_axis412148
Node: al_get_mouse_event_source412618
Ref: #al_get_mouse_event_source412822
Node: al_set_mouse_wheel_precision413138
Ref: #al_set_mouse_wheel_precision413359
Node: al_get_mouse_wheel_precision414626
Ref: #al_get_mouse_wheel_precision414835
Node: Mouse cursors415117
Ref: #mouse-cursors415259
Node: al_create_mouse_cursor415500
Ref: #al_create_mouse_cursor415667
Node: al_destroy_mouse_cursor416192
Ref: #al_destroy_mouse_cursor416389
Node: al_set_mouse_cursor416685
Ref: #al_set_mouse_cursor416878
Node: al_set_system_mouse_cursor417453
Ref: #al_set_system_mouse_cursor417665
Node: al_get_mouse_cursor_position419200
Ref: #al_get_mouse_cursor_position419417
Node: al_hide_mouse_cursor419868
Ref: #al_hide_mouse_cursor420063
Node: al_show_mouse_cursor420485
Ref: #al_show_mouse_cursor420665
Node: al_grab_mouse421030
Ref: #al_grab_mouse421191
Node: al_ungrab_mouse421757
Ref: #al_ungrab_mouse421893
Node: Path structures422172
Ref: #path-structures422303
Node: al_create_path423438
Ref: #al_create_path423582
Node: al_create_path_for_directory424121
Ref: #al_create_path_for_directory424317
Node: al_destroy_path424730
Ref: #al_destroy_path424899
Node: al_clone_path425192
Ref: #al_clone_path425342
Node: al_join_paths425590
Ref: #al_join_paths425739
Node: al_rebase_path426401
Ref: #al_rebase_path426556
Node: al_get_path_drive427111
Ref: #al_get_path_drive427285
Node: al_get_path_num_components427687
Ref: #al_get_path_num_components427886
Node: al_get_path_component428224
Ref: #al_get_path_component428412
Node: al_get_path_tail428900
Ref: #al_get_path_tail429074
Node: al_get_path_filename429295
Ref: #al_get_path_filename429476
Node: al_get_path_basename429989
Ref: #al_get_path_basename430175
Node: al_get_path_extension430768
Ref: #al_get_path_extension430953
Node: al_set_path_drive431508
Ref: #al_set_path_drive431689
Node: al_append_path_component432014
Ref: #al_append_path_component432212
Node: al_insert_path_component432459
Ref: #al_insert_path_component432665
Node: al_replace_path_component433259
Ref: #al_replace_path_component433467
Node: al_remove_path_component433962
Ref: #al_remove_path_component434161
Node: al_drop_path_tail434668
Ref: #al_drop_path_tail434848
Node: al_set_path_filename435088
Ref: #al_set_path_filename435271
Node: al_set_path_extension435672
Ref: #al_set_path_extension435852
Node: al_path_cstr436506
Ref: #al_path_cstr436660
Node: al_path_ustr437322
Ref: #al_path_ustr437477
Node: al_make_path_canonical438160
Ref: #al_make_path_canonical438314
Node: State438836
Ref: #state438948
Node: ALLEGRO_STATE439169
Ref: #allegro_state439291
Node: ALLEGRO_STATE_FLAGS440538
Ref: #allegro_state_flags440697
Node: al_restore_state441022
Ref: #al_restore_state441176
Node: al_store_state441515
Ref: #al_store_state441658
Node: al_get_errno442748
Ref: #al_get_errno442883
Node: al_set_errno443178
Ref: #al_set_errno443290
Node: System routines443476
Ref: #system-routines443600
Node: al_install_system444112
Ref: #al_install_system444244
Node: al_init445506
Ref: #al_init445646
Node: al_uninstall_system446389
Ref: #al_uninstall_system446558
Node: al_is_system_installed446858
Ref: #al_is_system_installed447048
Node: al_get_allegro_version447231
Ref: #al_get_allegro_version447422
Node: al_get_standard_path448225
Ref: #al_get_standard_path448405
Node: al_set_exe_name451596
Ref: #al_set_exe_name451759
Node: al_set_app_name452358
Ref: #al_set_app_name452516
Node: al_set_org_name453015
Ref: #al_set_org_name453173
Node: al_get_app_name453674
Ref: #al_get_app_name453834
Node: al_get_org_name454048
Ref: #al_get_org_name454213
Node: al_get_system_config454428
Ref: #al_get_system_config454604
Node: al_get_system_id463102
Ref: #al_get_system_id463281
Node: al_register_assert_handler463525
Ref: #al_register_assert_handler463729
Node: al_register_trace_handler464134
Ref: #al_register_trace_handler464336
Node: al_get_cpu_count464890
Ref: #al_get_cpu_count465063
Node: al_get_ram_size466109
Ref: #al_get_ram_size466272
Node: ALLEGRO_SYSTEM_ID467396
Ref: #allegro_system_id467538
Node: Threads468144
Ref: #threads468260
Node: ALLEGRO_THREAD469308
Ref: #allegro_thread469429
Node: ALLEGRO_MUTEX469615
Ref: #allegro_mutex469755
Node: ALLEGRO_COND469938
Ref: #allegro_cond470078
Node: al_create_thread470272
Ref: #al_create_thread470438
Node: al_create_thread_with_stacksize470932
Ref: #al_create_thread_with_stacksize471131
Node: al_start_thread471811
Ref: #al_start_thread471976
Node: al_join_thread472371
Ref: #al_join_thread472528
Node: al_set_thread_should_stop473128
Ref: #al_set_thread_should_stop473317
Node: al_get_thread_should_stop473641
Ref: #al_get_thread_should_stop473833
Node: al_destroy_thread474460
Ref: #al_destroy_thread474635
Node: al_run_detached_thread475001
Ref: #al_run_detached_thread475176
Node: al_create_mutex475719
Ref: #al_create_mutex475888
Node: al_create_mutex_recursive476248
Ref: #al_create_mutex_recursive476428
Node: al_lock_mutex477047
Ref: #al_lock_mutex477203
Node: al_unlock_mutex477987
Ref: #al_unlock_mutex478138
Node: al_destroy_mutex478498
Ref: #al_destroy_mutex478652
Node: al_create_cond478952
Ref: #al_create_cond479102
Node: al_destroy_cond479315
Ref: #al_destroy_cond479463
Node: al_wait_cond479757
Ref: #al_wait_cond479903
Node: al_wait_cond_until481056
Ref: #al_wait_cond_until481216
Node: al_broadcast_cond481646
Ref: #al_broadcast_cond481806
Node: al_signal_cond482284
Ref: #al_signal_cond482411
Node: Time routines482813
Ref: #time-routines482940
Node: ALLEGRO_TIMEOUT483113
Ref: #allegro_timeout483241
Node: al_get_time483562
Ref: #al_get_time483706
Node: al_init_timeout484041
Ref: #al_init_timeout484185
Node: al_rest484602
Ref: #al_rest484710
Node: Timer routines485194
Ref: #timer-routines485327
Node: ALLEGRO_TIMER485818
Ref: #allegro_timer485951
Node: ALLEGRO_USECS_TO_SECS486149
Ref: #allegro_usecs_to_secs486328
Node: ALLEGRO_MSECS_TO_SECS486512
Ref: #allegro_msecs_to_secs486697
Node: ALLEGRO_BPS_TO_SECS486878
Ref: #allegro_bps_to_secs487057
Node: ALLEGRO_BPM_TO_SECS487239
Ref: #allegro_bpm_to_secs487412
Node: al_create_timer487595
Ref: #al_create_timer487755
Node: al_start_timer488326
Ref: #al_start_timer488480
Node: al_resume_timer489057
Ref: #al_resume_timer489211
Node: al_stop_timer489754
Ref: #al_stop_timer489910
Node: al_get_timer_started490342
Ref: #al_get_timer_started490515
Node: al_destroy_timer490711
Ref: #al_destroy_timer490881
Node: al_get_timer_count491289
Ref: #al_get_timer_count491461
Node: al_set_timer_count491733
Ref: #al_set_timer_count491907
Node: al_add_timer_count492329
Ref: #al_add_timer_count492503
Node: al_get_timer_speed492917
Ref: #al_get_timer_speed493091
Node: al_set_timer_speed493447
Ref: #al_set_timer_speed493628
Node: al_get_timer_event_source494207
Ref: #al_get_timer_event_source494375
Node: Touch input494654
Ref: #touch-input494783
Node: ALLEGRO_TOUCH_INPUT495308
Ref: #allegro_touch_input495470
Node: ALLEGRO_TOUCH_INPUT_MAX_TOUCH_COUNT495714
Ref: #allegro_touch_input_max_touch_count495936
Node: ALLEGRO_TOUCH_STATE496170
Ref: #allegro_touch_state496366
Node: ALLEGRO_TOUCH_INPUT_STATE497046
Ref: #allegro_touch_input_state497247
Node: ALLEGRO_MOUSE_EMULATION_MODE497637
Ref: #allegro_mouse_emulation_mode497847
Node: al_install_touch_input498594
Ref: #al_install_touch_input498791
Node: al_uninstall_touch_input499131
Ref: #al_uninstall_touch_input499331
Node: al_is_touch_input_installed499709
Ref: #al_is_touch_input_installed499917
Node: al_get_touch_input_state500154
Ref: #al_get_touch_input_state500359
Node: al_set_mouse_emulation_mode500698
Ref: #al_set_mouse_emulation_mode500911
Node: al_get_mouse_emulation_mode501426
Ref: #al_get_mouse_emulation_mode501646
Node: al_get_touch_input_event_source502168
Ref: #al_get_touch_input_event_source502416
Node: al_get_touch_input_mouse_emulation_event_source502828
Ref: #al_get_touch_input_mouse_emulation_event_source503072
Node: Transformations503711
Ref: #transformations503855
Node: ALLEGRO_TRANSFORM507924
Ref: #allegro_transform508066
Node: al_copy_transform508467
Ref: #al_copy_transform508634
Node: al_use_transform508930
Ref: #al_use_transform509102
Node: al_get_current_transform510157
Ref: #al_get_current_transform510355
Node: al_use_projection_transform510818
Ref: #al_use_projection_transform511041
Node: al_get_current_projection_transform512986
Ref: #al_get_current_projection_transform513233
Node: al_get_current_inverse_transform513594
Ref: #al_get_current_inverse_transform513827
Node: al_invert_transform514363
Ref: #al_invert_transform514557
Node: al_transpose_transform515219
Ref: #al_transpose_transform515403
Node: al_check_inverse515984
Ref: #al_check_inverse516160
Node: al_identity_transform517771
Ref: #al_identity_transform517953
Node: al_build_transform518587
Ref: #al_build_transform518772
Node: al_build_camera_transform519727
Ref: #al_build_camera_transform519927
Node: al_translate_transform521600
Ref: #al_translate_transform521795
Node: al_rotate_transform522236
Ref: #al_rotate_transform522418
Node: al_scale_transform522869
Ref: #al_scale_transform523051
Node: al_transform_coordinates523488
Ref: #al_transform_coordinates523690
Node: al_transform_coordinates_3d524112
Ref: #al_transform_coordinates_3d524329
Node: al_transform_coordinates_4d524951
Ref: #al_transform_coordinates_4d525182
Node: al_transform_coordinates_3d_projective525709
Ref: #al_transform_coordinates_3d_projective525955
Node: al_compose_transform527685
Ref: #al_compose_transform527893
Node: al_orthographic_transform528644
Ref: #al_orthographic_transform528848
Node: al_perspective_transform530366
Ref: #al_perspective_transform530573
Node: al_translate_transform_3d533653
Ref: #al_translate_transform_3d533858
Node: al_scale_transform_3d534235
Ref: #al_scale_transform_3d534430
Node: al_rotate_transform_3d534802
Ref: #al_rotate_transform_3d535003
Node: al_horizontal_shear_transform535434
Ref: #al_horizontal_shear_transform535655
Node: al_vertical_shear_transform536050
Ref: #al_vertical_shear_transform536236
Node: UTF-8 string routines536631
Ref: #utf-8-string-routines536803
Node: About UTF-8 string routines537372
Ref: #about-utf-8-string-routines537551
Node: UTF-8 string types541890
Ref: #utf-8-string-types542091
Node: ALLEGRO_USTR542140
Ref: #allegro_ustr542274
Node: ALLEGRO_USTR_INFO542570
Ref: #allegro_ustr_info542714
Node: Creating and destroying strings543101
Ref: #creating-and-destroying-strings543319
Node: al_ustr_new543496
Ref: #al_ustr_new543646
Node: al_ustr_new_from_buffer544105
Ref: #al_ustr_new_from_buffer544300
Node: al_ustr_newf544676
Ref: #al_ustr_newf544850
Node: al_ustr_free545821
Ref: #al_ustr_free545979
Node: al_cstr546307
Ref: #al_cstr546460
Node: al_ustr_to_buffer547579
Ref: #al_ustr_to_buffer547751
Node: al_cstr_dup548158
Ref: #al_cstr_dup548322
Node: al_ustr_dup548790
Ref: #al_ustr_dup548955
Node: al_ustr_dup_substr549295
Ref: #al_ustr_dup_substr549454
Node: Predefined strings550052
Ref: #predefined-strings550268
Node: al_ustr_empty_string550303
Ref: #al_ustr_empty_string550435
Node: Creating strings by referencing other data550655
Ref: #creating-strings-by-referencing-other-data550905
Node: al_ref_cstr550965
Ref: #al_ref_cstr551116
Node: al_ref_buffer551857
Ref: #al_ref_buffer552032
Node: al_ref_ustr552540
Ref: #al_ref_ustr552691
Node: Sizes and offsets553653
Ref: #sizes-and-offsets553854
Node: al_ustr_size553953
Ref: #al_ustr_size554083
Node: al_ustr_length554421
Ref: #al_ustr_length554578
Node: al_ustr_offset554839
Ref: #al_ustr_offset554996
Node: al_ustr_next555587
Ref: #al_ustr_next555738
Node: al_ustr_prev556498
Ref: #al_ustr_prev556626
Node: Getting code points557383
Ref: #getting-code-points557568
Node: al_ustr_get557636
Ref: #al_ustr_get557767
Node: al_ustr_get_next558248
Ref: #al_ustr_get_next558414
Node: al_ustr_prev_get559025
Ref: #al_ustr_prev_get559171
Node: Inserting into strings559765
Ref: #inserting-into-strings559959
Node: al_ustr_insert560035
Ref: #al_ustr_insert560181
Node: al_ustr_insert_cstr560922
Ref: #al_ustr_insert_cstr561105
Node: al_ustr_insert_chr561450
Ref: #al_ustr_insert_chr561608
Node: Appending to strings562156
Ref: #appending-to-strings562352
Node: al_ustr_append562469
Ref: #al_ustr_append562613
Node: al_ustr_append_cstr563174
Ref: #al_ustr_append_cstr563355
Node: al_ustr_append_chr563641
Ref: #al_ustr_append_chr563821
Node: al_ustr_appendf564103
Ref: #al_ustr_appendf564274
Node: al_ustr_vappendf564743
Ref: #al_ustr_vappendf564889
Node: Removing parts of strings565390
Ref: #removing-parts-of-strings565607
Node: al_ustr_remove_chr565748
Ref: #al_ustr_remove_chr565912
Node: al_ustr_remove_range566417
Ref: #al_ustr_remove_range566610
Node: al_ustr_truncate567121
Ref: #al_ustr_truncate567304
Node: al_ustr_ltrim_ws567838
Ref: #al_ustr_ltrim_ws568017
Node: al_ustr_rtrim_ws568377
Ref: #al_ustr_rtrim_ws568555
Node: al_ustr_trim_ws568930
Ref: #al_ustr_trim_ws569081
Node: Assigning one string to another569414
Ref: #assigning-one-string-to-another569648
Node: al_ustr_assign569727
Ref: #al_ustr_assign569886
Node: al_ustr_assign_substr570249
Ref: #al_ustr_assign_substr570450
Node: al_ustr_assign_cstr571053
Ref: #al_ustr_assign_cstr571227
Node: Replacing parts of string571602
Ref: #replacing-parts-of-string571808
Node: al_ustr_set_chr571864
Ref: #al_ustr_set_chr572020
Node: al_ustr_replace_range572736
Ref: #al_ustr_replace_range572904
Node: Searching573573
Ref: #searching573725
Node: al_ustr_find_chr574017
Ref: #al_ustr_find_chr574156
Node: al_ustr_rfind_chr574535
Ref: #al_ustr_rfind_chr574701
Node: al_ustr_find_set575085
Ref: #al_ustr_find_set575254
Node: al_ustr_find_set_cstr575751
Ref: #al_ustr_find_set_cstr575930
Node: al_ustr_find_cset576302
Ref: #al_ustr_find_cset576479
Node: al_ustr_find_cset_cstr577070
Ref: #al_ustr_find_cset_cstr577252
Node: al_ustr_find_str577627
Ref: #al_ustr_find_str577797
Node: al_ustr_find_cstr578331
Ref: #al_ustr_find_cstr578498
Node: al_ustr_rfind_str578864
Ref: #al_ustr_rfind_str579033
Node: al_ustr_rfind_cstr579503
Ref: #al_ustr_rfind_cstr579679
Node: al_ustr_find_replace580046
Ref: #al_ustr_find_replace580234
Node: al_ustr_find_replace_cstr580701
Ref: #al_ustr_find_replace_cstr580872
Node: Comparing581176
Ref: #comparing581320
Node: al_ustr_equal581491
Ref: #al_ustr_equal581619
Node: al_ustr_compare581991
Ref: #al_ustr_compare582148
Node: al_ustr_ncompare582692
Ref: #al_ustr_ncompare582856
Node: al_ustr_has_prefix583340
Ref: #al_ustr_has_prefix583516
Node: al_ustr_has_prefix_cstr583837
Ref: #al_ustr_has_prefix_cstr584025
Node: al_ustr_has_suffix584341
Ref: #al_ustr_has_suffix584524
Node: al_ustr_has_suffix_cstr584843
Ref: #al_ustr_has_suffix_cstr585004
Node: UTF-16 conversion585318
Ref: #utf-16-conversion585493
Node: al_ustr_new_from_utf16585578
Ref: #al_ustr_new_from_utf16585744
Node: al_ustr_size_utf16586110
Ref: #al_ustr_size_utf16586297
Node: al_ustr_encode_utf16586698
Ref: #al_ustr_encode_utf16586858
Node: Low-level UTF-8 routines587481
Ref: #low-level-utf-8-routines587686
Node: al_utf8_width587733
Ref: #al_utf8_width587875
Node: al_utf8_encode588262
Ref: #al_utf8_encode588406
Node: Low-level UTF-16 routines588919
Ref: #low-level-utf-16-routines589100
Node: al_utf16_width589149
Ref: #al_utf16_width589296
Node: al_utf16_encode589680
Ref: #al_utf16_encode589829
Node: Platform-specific functions590397
Ref: #platform-specific-functions590586
Node: Windows590652
Ref: #windows590767
Node: al_get_win_window_handle590971
Ref: #al_get_win_window_handle591139
Node: al_win_add_window_callback591352
Ref: #al_win_add_window_callback591562
Node: al_win_remove_window_callback592450
Ref: #al_win_remove_window_callback592633
Node: Mac OS X593207
Ref: #mac-os-x593339
Node: al_osx_get_window593467
Ref: #al_osx_get_window593580
Node: iPhone593813
Ref: #iphone593941
Node: al_iphone_set_statusbar_orientation594138
Ref: #al_iphone_set_statusbar_orientation594330
Node: al_iphone_get_view594808
Ref: #al_iphone_get_view594995
Node: al_iphone_get_window595236
Ref: #al_iphone_get_window595383
Node: Android595618
Ref: #android595743
Node: al_android_set_apk_file_interface596012
Ref: #al_android_set_apk_file_interface596212
Node: al_android_set_apk_fs_interface596655
Ref: #al_android_set_apk_fs_interface596885
Node: al_android_get_os_version597504
Ref: #al_android_get_os_version597711
Node: al_android_get_jni_env598011
Ref: #al_android_get_jni_env598204
Node: al_android_get_activity599136
Ref: #al_android_get_activity599297
Node: X11599742
Ref: #x11599844
Node: al_get_x_window_id599997
Ref: #al_get_x_window_id600138
Node: al_x_set_initial_icon600344
Ref: #al_x_set_initial_icon600491
Node: Direct3D integration600948
Ref: #direct3d-integration601120
Node: al_get_d3d_device601560
Ref: #al_get_d3d_device601715
Node: al_get_d3d_system_texture602046
Ref: #al_get_d3d_system_texture602250
Node: al_get_d3d_video_texture602596
Ref: #al_get_d3d_video_texture602817
Node: al_have_d3d_non_pow2_texture_support603192
Ref: #al_have_d3d_non_pow2_texture_support603450
Node: al_have_d3d_non_square_texture_support603752
Ref: #al_have_d3d_non_square_texture_support604013
Node: al_get_d3d_texture_size604317
Ref: #al_get_d3d_texture_size604539
Node: al_get_d3d_texture_position604982
Ref: #al_get_d3d_texture_position605195
Node: al_is_d3d_device_lost605683
Ref: #al_is_d3d_device_lost605895
Node: al_set_d3d_device_release_callback606255
Ref: #al_set_d3d_device_release_callback606500
Node: al_set_d3d_device_restore_callback606973
Ref: #al_set_d3d_device_restore_callback607190
Node: OpenGL integration607644
Ref: #opengl-integration607796
Node: al_get_opengl_extension_list608281
Ref: #al_get_opengl_extension_list608468
Node: al_get_opengl_proc_address609885
Ref: #al_get_opengl_proc_address610098
Node: al_get_opengl_texture611265
Ref: #al_get_opengl_texture611466
Node: al_get_opengl_texture_size611861
Ref: #al_get_opengl_texture_size612076
Node: al_get_opengl_texture_position612613
Ref: #al_get_opengl_texture_position612843
Node: al_get_opengl_program_object613191
Ref: #al_get_opengl_program_object613408
Node: al_get_opengl_fbo613695
Ref: #al_get_opengl_fbo613880
Node: al_remove_opengl_fbo614751
Ref: #al_remove_opengl_fbo614938
Node: al_have_opengl_extension615371
Ref: #al_have_opengl_extension615570
Node: al_get_opengl_version616075
Ref: #al_get_opengl_version616271
Node: al_get_opengl_variant616856
Ref: #al_get_opengl_variant617057
Node: al_set_current_opengl_context617679
Ref: #al_set_current_opengl_context617895
Node: OpenGL configuration618713
Ref: #opengl-configuration618881
Node: Audio addon619213
Ref: #audio-addon619349
Node: Basic Audio619674
Ref: #basic-audio619784
Node: ALLEGRO_SAMPLE_ID621120
Ref: #allegro_sample_id621261
Node: al_install_audio621731
Ref: #al_install_audio621897
Node: al_uninstall_audio622455
Ref: #al_uninstall_audio622629
Node: al_is_audio_installed622837
Ref: #al_is_audio_installed623019
Node: al_reserve_samples623252
Ref: #al_reserve_samples623424
Node: al_play_sample624616
Ref: #al_play_sample624773
Node: al_stop_sample626203
Ref: #al_stop_sample626357
Node: al_stop_samples626619
Ref: #al_stop_samples626778
Node: al_lock_sample_id627019
Ref: #al_lock_sample_id627187
Node: al_unlock_sample_id628179
Ref: #al_unlock_sample_id628358
Node: al_play_audio_stream629085
Ref: #al_play_audio_stream629271
Node: al_play_audio_stream_f630058
Ref: #al_play_audio_stream_f630220
Node: Samples631294
Ref: #samples631419
Node: ALLEGRO_SAMPLE631698
Ref: #allegro_sample631826
Node: al_create_sample632348
Ref: #al_create_sample632503
Node: al_load_sample633903
Ref: #al_load_sample634056
Node: al_load_sample_f634852
Ref: #al_load_sample_f635007
Node: al_save_sample636041
Ref: #al_save_sample636194
Node: al_save_sample_f636849
Ref: #al_save_sample_f637007
Node: al_destroy_sample637754
Ref: #al_destroy_sample637922
Node: al_get_sample_channels638510
Ref: #al_get_sample_channels638691
Node: al_get_sample_depth639173
Ref: #al_get_sample_depth639354
Node: al_get_sample_frequency639826
Ref: #al_get_sample_frequency640015
Node: al_get_sample_length640433
Ref: #al_get_sample_length640615
Node: al_get_sample_data641042
Ref: #al_get_sample_data641188
Node: Advanced Audio641601
Ref: #advanced-audio641745
Node: Sample instances646360
Ref: #sample-instances646514
Node: ALLEGRO_SAMPLE_INSTANCE647425
Ref: #allegro_sample_instance647598
Node: al_create_sample_instance648625
Ref: #al_create_sample_instance648837
Node: al_destroy_sample_instance649347
Ref: #al_destroy_sample_instance649561
Node: al_play_sample_instance649933
Ref: #al_play_sample_instance650139
Node: al_stop_sample_instance650435
Ref: #al_stop_sample_instance650646
Node: al_get_sample_instance_channels650905
Ref: #al_get_sample_instance_channels651137
Node: al_get_sample_instance_depth651464
Ref: #al_get_sample_instance_depth651699
Node: al_get_sample_instance_frequency652006
Ref: #al_get_sample_instance_frequency652247
Node: al_get_sample_instance_length652497
Ref: #al_get_sample_instance_length652733
Node: al_set_sample_instance_length653190
Ref: #al_set_sample_instance_length653427
Node: al_get_sample_instance_position653982
Ref: #al_get_sample_instance_position654225
Node: al_set_sample_instance_position654537
Ref: #al_set_sample_instance_position654779
Node: al_get_sample_instance_speed655142
Ref: #al_get_sample_instance_speed655375
Node: al_set_sample_instance_speed655682
Ref: #al_set_sample_instance_speed655911
Node: al_get_sample_instance_gain656354
Ref: #al_get_sample_instance_gain656580
Node: al_set_sample_instance_gain656874
Ref: #al_set_sample_instance_gain657098
Node: al_get_sample_instance_pan657504
Ref: #al_get_sample_instance_pan657725
Node: al_set_sample_instance_pan658009
Ref: #al_set_sample_instance_pan658230
Node: al_get_sample_instance_time659093
Ref: #al_get_sample_instance_time659321
Node: al_get_sample_instance_playmode659657
Ref: #al_get_sample_instance_playmode659898
Node: al_set_sample_instance_playmode660258
Ref: #al_set_sample_instance_playmode660502
Node: al_get_sample_instance_playing660910
Ref: #al_get_sample_instance_playing661151
Node: al_set_sample_instance_playing661532
Ref: #al_set_sample_instance_playing661773
Node: al_get_sample_instance_attached662192
Ref: #al_get_sample_instance_attached662430
Node: al_detach_sample_instance662893
Ref: #al_detach_sample_instance663102
Node: al_get_sample663604
Ref: #al_get_sample663771
Node: al_set_sample664488
Ref: #al_set_sample664667
Node: al_set_sample_instance_channel_matrix665618
Ref: #al_set_sample_instance_channel_matrix665823
Node: Audio streams667169
Ref: #audio-streams667326
Node: ALLEGRO_AUDIO_STREAM668410
Ref: #allegro_audio_stream668568
Node: al_create_audio_stream670712
Ref: #al_create_audio_stream670903
Node: al_load_audio_stream673472
Ref: #al_load_audio_stream673661
Node: al_load_audio_stream_f674753
Ref: #al_load_audio_stream_f674947
Node: al_destroy_audio_stream676378
Ref: #al_destroy_audio_stream676586
Node: al_get_audio_stream_event_source677130
Ref: #al_get_audio_stream_event_source677355
Node: al_drain_audio_stream677788
Ref: #al_drain_audio_stream677990
Node: al_rewind_audio_stream678400
Ref: #al_rewind_audio_stream678601
Node: al_get_audio_stream_frequency679114
Ref: #al_get_audio_stream_frequency679336
Node: al_get_audio_stream_channels679549
Ref: #al_get_audio_stream_channels679774
Node: al_get_audio_stream_depth680064
Ref: #al_get_audio_stream_depth680280
Node: al_get_audio_stream_length680554
Ref: #al_get_audio_stream_length680769
Node: al_get_audio_stream_speed680979
Ref: #al_get_audio_stream_speed681192
Node: al_set_audio_stream_speed681479
Ref: #al_set_audio_stream_speed681690
Node: al_get_audio_stream_gain682110
Ref: #al_get_audio_stream_gain682318
Node: al_set_audio_stream_gain682592
Ref: #al_set_audio_stream_gain682798
Node: al_get_audio_stream_pan683181
Ref: #al_get_audio_stream_pan683384
Node: al_set_audio_stream_pan683648
Ref: #al_set_audio_stream_pan683854
Node: al_get_audio_stream_playing684626
Ref: #al_get_audio_stream_playing684844
Node: al_set_audio_stream_playing685124
Ref: #al_set_audio_stream_playing685347
Node: al_get_audio_stream_playmode685675
Ref: #al_get_audio_stream_playmode685901
Node: al_set_audio_stream_playmode686245
Ref: #al_set_audio_stream_playmode686472
Node: al_get_audio_stream_attached686860
Ref: #al_get_audio_stream_attached687081
Node: al_detach_audio_stream687512
Ref: #al_detach_audio_stream687727
Node: al_get_audio_stream_played_samples688171
Ref: #al_get_audio_stream_played_samples688410
Node: al_get_audio_stream_fragment688686
Ref: #al_get_audio_stream_fragment688919
Node: al_set_audio_stream_fragment690544
Ref: #al_set_audio_stream_fragment690772
Node: al_get_audio_stream_fragments691230
Ref: #al_get_audio_stream_fragments691471
Node: al_get_available_audio_stream_fragments691919
Ref: #al_get_available_audio_stream_fragments692177
Node: al_seek_audio_stream_secs692645
Ref: #al_seek_audio_stream_secs692879
Node: al_get_audio_stream_position_secs693560
Ref: #al_get_audio_stream_position_secs693802
Node: al_get_audio_stream_length_secs694374
Ref: #al_get_audio_stream_length_secs694616
Node: al_set_audio_stream_loop_secs695223
Ref: #al_set_audio_stream_loop_secs695462
Node: al_set_audio_stream_channel_matrix695975
Ref: #al_set_audio_stream_channel_matrix696184
Node: Advanced audio file I/O696372
Ref: #advanced-audio-file-io696548
Node: al_register_sample_loader696836
Ref: #al_register_sample_loader697024
Node: al_register_sample_loader_f697788
Ref: #al_register_sample_loader_f698013
Node: al_register_sample_saver698716
Ref: #al_register_sample_saver698936
Node: al_register_sample_saver_f699706
Ref: #al_register_sample_saver_f699934
Node: al_register_audio_stream_loader700641
Ref: #al_register_audio_stream_loader700888
Node: al_register_audio_stream_loader_f701736
Ref: #al_register_audio_stream_loader_f701990
Node: al_register_sample_identifier702840
Ref: #al_register_sample_identifier703073
Node: al_identify_sample704216
Ref: #al_identify_sample704414
Node: al_identify_sample_f705023
Ref: #al_identify_sample_f705187
Node: Audio recording706104
Ref: #audio-recording706264
Node: ALLEGRO_AUDIO_RECORDER707045
Ref: #allegro_audio_recorder707217
Node: ALLEGRO_AUDIO_RECORDER_EVENT707542
Ref: #allegro_audio_recorder_event707759
Node: al_create_audio_recorder708438
Ref: #al_create_audio_recorder708648
Node: al_start_audio_recorder710380
Ref: #al_start_audio_recorder710582
Node: al_stop_audio_recorder711157
Ref: #al_stop_audio_recorder711363
Node: al_is_audio_recorder_recording712030
Ref: #al_is_audio_recorder_recording712256
Node: al_get_audio_recorder_event712599
Ref: #al_get_audio_recorder_event712831
Node: al_get_audio_recorder_event_source713196
Ref: #al_get_audio_recorder_event_source713437
Node: al_destroy_audio_recorder713802
Ref: #al_destroy_audio_recorder713989
Node: Audio devices714499
Ref: #audio-devices714638
Node: ALLEGRO_AUDIO_DEVICE714769
Ref: #allegro_audio_device714936
Node: al_get_num_audio_output_devices715155
Ref: #al_get_num_audio_output_devices715379
Node: al_get_audio_output_device715623
Ref: #al_get_audio_output_device715841
Node: al_get_audio_device_name716065
Ref: #al_get_audio_device_name716239
Node: Voices716469
Ref: #voices716585
Node: ALLEGRO_VOICE716956
Ref: #allegro_voice717079
Node: al_create_voice717595
Ref: #al_create_voice717747
Node: al_destroy_voice718809
Ref: #al_destroy_voice718965
Node: al_detach_voice719256
Ref: #al_detach_voice719426
Node: al_attach_audio_stream_to_voice719855
Ref: #al_attach_audio_stream_to_voice720065
Node: al_attach_mixer_to_voice720898
Ref: #al_attach_mixer_to_voice721113
Node: al_attach_sample_instance_to_voice721500
Ref: #al_attach_sample_instance_to_voice721726
Node: al_get_voice_frequency722432
Ref: #al_get_voice_frequency722631
Node: al_get_voice_channels722846
Ref: #al_get_voice_channels723027
Node: al_get_voice_depth723303
Ref: #al_get_voice_depth723478
Node: al_get_voice_playing723738
Ref: #al_get_voice_playing723916
Node: al_set_voice_playing724175
Ref: #al_set_voice_playing724356
Node: al_get_voice_position724817
Ref: #al_get_voice_position725001
Node: al_set_voice_position725370
Ref: #al_set_voice_position725525
Node: Mixers725920
Ref: #mixers726037
Node: ALLEGRO_MIXER726696
Ref: #allegro_mixer726827
Node: ALLEGRO_MIXER_QUALITY727558
Ref: #allegro_mixer_quality727729
Node: al_create_mixer728060
Ref: #al_create_mixer728222
Node: al_destroy_mixer729157
Ref: #al_destroy_mixer729320
Node: al_get_default_mixer729532
Ref: #al_get_default_mixer729708
Node: al_set_default_mixer730318
Ref: #al_set_default_mixer730502
Node: al_restore_default_mixer731214
Ref: #al_restore_default_mixer731406
Node: al_get_default_voice732208
Ref: #al_get_default_voice732392
Node: al_set_default_voice732660
Ref: #al_set_default_voice732844
Node: al_attach_mixer_to_mixer733268
Ref: #al_attach_mixer_to_mixer733476
Node: al_attach_sample_instance_to_mixer734050
Ref: #al_attach_sample_instance_to_mixer734289
Node: al_attach_audio_stream_to_mixer734689
Ref: #al_attach_audio_stream_to_mixer734920
Node: al_get_mixer_frequency735304
Ref: #al_get_mixer_frequency735505
Node: al_set_mixer_frequency735767
Ref: #al_set_mixer_frequency735958
Node: al_get_mixer_channels736328
Ref: #al_get_mixer_channels736513
Node: al_get_mixer_depth736782
Ref: #al_get_mixer_depth736956
Node: al_get_mixer_gain737209
Ref: #al_get_mixer_gain737377
Node: al_set_mixer_gain737669
Ref: #al_set_mixer_gain737839
Node: al_get_mixer_quality738160
Ref: #al_get_mixer_quality738339
Node: al_set_mixer_quality738647
Ref: #al_set_mixer_quality738829
Node: al_get_mixer_playing739265
Ref: #al_get_mixer_playing739447
Node: al_set_mixer_playing739696
Ref: #al_set_mixer_playing739879
Node: al_get_mixer_attached740177
Ref: #al_get_mixer_attached740357
Node: al_detach_mixer740822
Ref: #al_detach_mixer741003
Node: al_set_mixer_postprocess_callback741276
Ref: #al_set_mixer_postprocess_callback741463
Node: Miscelaneous742011
Ref: #miscelaneous742125
Node: ALLEGRO_AUDIO_DEPTH742367
Ref: #allegro_audio_depth742523
Node: ALLEGRO_AUDIO_PAN_NONE743149
Ref: #allegro_audio_pan_none743340
Node: ALLEGRO_CHANNEL_CONF744133
Ref: #allegro_channel_conf744317
Node: ALLEGRO_PLAYMODE744716
Ref: #allegro_playmode744894
Node: ALLEGRO_AUDIO_EVENT_TYPE745775
Ref: #allegro_audio_event_type745977
Node: ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT746419
Ref: #allegro_event_audio_stream_fragment746652
Node: ALLEGRO_EVENT_AUDIO_STREAM_FINISHED746779
Ref: #allegro_event_audio_stream_finished747058
Node: ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT747091
Ref: #allegro_event_audio_recorder_fragment747330
Node: al_get_allegro_audio_version747781
Ref: #al_get_allegro_audio_version747998
Node: al_get_audio_depth_size748256
Ref: #al_get_audio_depth_size748459
Node: al_get_channel_count748764
Ref: #al_get_channel_count748948
Node: al_fill_silence749252
Ref: #al_fill_silence749394
Node: Audio codecs addon749785
Ref: #audio-codecs-addon749928
Node: al_init_acodec_addon750158
Ref: #al_init_acodec_addon750325
Node: al_is_acodec_addon_initialized751551
Ref: #al_is_acodec_addon_initialized751776
Node: al_get_allegro_acodec_version751999
Ref: #al_get_allegro_acodec_version752193
Node: Color addon752453
Ref: #color-addon752582
Node: al_color_cmyk754627
Ref: #al_color_cmyk754756
Node: al_color_cmyk_to_rgb755131
Ref: #al_color_cmyk_to_rgb755295
Node: al_color_hsl755642
Ref: #al_color_hsl755796
Node: al_color_hsl_to_rgb756311
Ref: #al_color_hsl_to_rgb756471
Node: al_color_hsv757109
Ref: #al_color_hsv757262
Node: al_color_hsv_to_rgb757765
Ref: #al_color_hsv_to_rgb757926
Node: al_color_html758552
Ref: #al_color_html758709
Node: al_color_html_to_rgb759296
Ref: #al_color_html_to_rgb759468
Node: al_color_rgb_to_html760094
Ref: #al_color_rgb_to_html760266
Node: al_color_name760951
Ref: #al_color_name761111
Node: al_color_name_to_rgb761447
Ref: #al_color_name_to_rgb761621
Node: al_color_rgb_to_cmyk764136
Ref: #al_color_rgb_to_cmyk764316
Node: al_color_rgb_to_hsl764870
Ref: #al_color_rgb_to_hsl765047
Node: al_color_rgb_to_hsv765489
Ref: #al_color_rgb_to_hsv765666
Node: al_color_rgb_to_name766100
Ref: #al_color_rgb_to_name766279
Node: al_color_rgb_to_xyz766633
Ref: #al_color_rgb_to_xyz766803
Node: al_color_xyz767137
Ref: #al_color_xyz767292
Node: al_color_xyz_to_rgb768117
Ref: #al_color_xyz_to_rgb768286
Node: al_color_rgb_to_xyy768627
Ref: #al_color_rgb_to_xyy768796
Node: al_color_xyy769131
Ref: #al_color_xyy769286
Node: al_color_xyy_to_rgb769801
Ref: #al_color_xyy_to_rgb769970
Node: al_color_rgb_to_lab770312
Ref: #al_color_rgb_to_lab770481
Node: al_color_lab770818
Ref: #al_color_lab770973
Node: al_color_lab_to_rgb771886
Ref: #al_color_lab_to_rgb772055
Node: al_color_rgb_to_lch772403
Ref: #al_color_rgb_to_lch772572
Node: al_color_lch772910
Ref: #al_color_lch773065
Node: al_color_lch_to_rgb773817
Ref: #al_color_lch_to_rgb773994
Node: al_color_distance_ciede2000774339
Ref: #al_color_distance_ciede2000774539
Node: al_color_rgb_to_yuv775696
Ref: #al_color_rgb_to_yuv775873
Node: al_color_yuv776193
Ref: #al_color_yuv776348
Node: al_color_yuv_to_rgb776677
Ref: #al_color_yuv_to_rgb776855
Node: al_get_allegro_color_version777182
Ref: #al_get_allegro_color_version777383
Node: al_is_color_valid777641
Ref: #al_is_color_valid777822
Node: al_color_rgb_to_oklab778114
Ref: #al_color_rgb_to_oklab778289
Node: al_color_oklab778642
Ref: #al_color_oklab778807
Node: al_color_oklab_to_rgb779527
Ref: #al_color_oklab_to_rgb779707
Node: al_color_rgb_to_linear780051
Ref: #al_color_rgb_to_linear780234
Node: al_color_linear780620
Ref: #al_color_linear780790
Node: al_color_linear_to_rgb782039
Ref: #al_color_linear_to_rgb782192
Node: Font addons782559
Ref: #font-addons782685
Node: General font routines782929
Ref: #general-font-routines783085
Node: ALLEGRO_FONT783690
Ref: #allegro_font783823
Node: ALLEGRO_GLYPH784411
Ref: #allegro_glyph784573
Node: al_init_font_addon786193
Ref: #al_init_font_addon786381
Node: al_is_font_addon_initialized787215
Ref: #al_is_font_addon_initialized787432
Node: al_shutdown_font_addon787761
Ref: #al_shutdown_font_addon787960
Node: al_load_font788265
Ref: #al_load_font788431
Node: al_destroy_font789250
Ref: #al_destroy_font789423
Node: al_register_font_loader789676
Ref: #al_register_font_loader789876
Node: al_get_font_line_height790520
Ref: #al_get_font_line_height790723
Node: al_get_font_ascent791675
Ref: #al_get_font_ascent791866
Node: al_get_font_descent792161
Ref: #al_get_font_descent792348
Node: al_get_text_width792643
Ref: #al_get_text_width792825
Node: al_get_ustr_width793212
Ref: #al_get_ustr_width793387
Node: al_draw_text793738
Ref: #al_draw_text793898
Node: al_draw_ustr795098
Ref: #al_draw_ustr795263
Node: al_draw_justified_text795760
Ref: #al_draw_justified_text795955
Node: al_draw_justified_ustr796813
Ref: #al_draw_justified_ustr797009
Node: al_draw_textf797526
Ref: #al_draw_textf797705
Node: al_draw_justified_textf798155
Ref: #al_draw_justified_textf798354
Node: al_get_text_dimensions798894
Ref: #al_get_text_dimensions799100
Node: al_get_ustr_dimensions799946
Ref: #al_get_ustr_dimensions800156
Node: al_get_allegro_font_version800580
Ref: #al_get_allegro_font_version800796
Node: al_get_font_ranges801051
Ref: #al_get_font_ranges801247
Node: al_set_fallback_font802029
Ref: #al_set_fallback_font802222
Node: al_get_fallback_font802725
Ref: #al_get_fallback_font802891
Node: Per glyph text handling803164
Ref: #per-glyph-text-handling803355
Node: al_draw_glyph804151
Ref: #al_draw_glyph804294
Node: al_get_glyph_width805502
Ref: #al_get_glyph_width805687
Node: al_get_glyph_dimensions806180
Ref: #al_get_glyph_dimensions806382
Node: al_get_glyph_advance808953
Ref: #al_get_glyph_advance809122
Node: Multiline text drawing812111
Ref: #multiline-text-drawing812291
Node: al_draw_multiline_text812433
Ref: #al_draw_multiline_text812606
Node: al_draw_multiline_ustr815205
Ref: #al_draw_multiline_ustr815410
Node: al_draw_multiline_textf816009
Ref: #al_draw_multiline_textf816214
Node: al_do_multiline_text816839
Ref: #al_do_multiline_text817036
Node: al_do_multiline_ustr818847
Ref: #al_do_multiline_ustr819012
Node: Bitmap fonts819493
Ref: #bitmap-fonts819639
Node: al_grab_font_from_bitmap819759
Ref: #al_grab_font_from_bitmap819925
Node: al_load_bitmap_font822244
Ref: #al_load_bitmap_font822434
Node: al_load_bitmap_font_flags823181
Ref: #al_load_bitmap_font_flags823381
Node: al_create_builtin_font823931
Ref: #al_create_builtin_font824097
Node: TTF fonts824938
Ref: #ttf-fonts825047
Node: al_init_ttf_addon825409
Ref: #al_init_ttf_addon825559
Node: al_is_ttf_addon_initialized825922
Ref: #al_is_ttf_addon_initialized826122
Node: al_shutdown_ttf_addon826444
Ref: #al_shutdown_ttf_addon826631
Node: al_load_ttf_font826823
Ref: #al_load_ttf_font826991
Node: al_load_ttf_font_f828258
Ref: #al_load_ttf_font_f828433
Node: al_load_ttf_font_stretch828980
Ref: #al_load_ttf_font_stretch829177
Node: al_load_ttf_font_stretch_f830127
Ref: #al_load_ttf_font_stretch_f830336
Node: al_get_allegro_ttf_version831001
Ref: #al_get_allegro_ttf_version831198
Node: al_get_glyph831451
Ref: #al_get_glyph831585
Node: Image I/O addon832298
Ref: #image-io-addon832431
Node: al_init_image_addon832892
Ref: #al_init_image_addon833052
Node: al_is_image_addon_initialized834045
Ref: #al_is_image_addon_initialized834257
Node: al_shutdown_image_addon834475
Ref: #al_shutdown_image_addon834684
Node: al_get_allegro_image_version834933
Ref: #al_get_allegro_image_version835114
Node: Main addon835370
Ref: #main-addon835499
Node: Memfile interface836433
Ref: #memfile-interface836583
Node: al_open_memfile836913
Ref: #al_open_memfile837064
Node: al_get_allegro_memfile_version837830
Ref: #al_get_allegro_memfile_version838011
Node: Native dialogs support838275
Ref: #native-dialogs-support838446
Node: ALLEGRO_FILECHOOSER839121
Ref: #allegro_filechooser839274
Node: ALLEGRO_TEXTLOG839493
Ref: #allegro_textlog839674
Node: al_init_native_dialog_addon839882
Ref: #al_init_native_dialog_addon840105
Node: al_is_native_dialog_addon_initialized840804
Ref: #al_is_native_dialog_addon_initialized841063
Node: al_shutdown_native_dialog_addon841307
Ref: #al_shutdown_native_dialog_addon841555
Node: al_create_native_file_dialog841830
Ref: #al_create_native_file_dialog842061
Node: al_show_native_file_dialog844423
Ref: #al_show_native_file_dialog844650
Node: al_get_native_file_dialog_count845178
Ref: #al_get_native_file_dialog_count845417
Node: al_get_native_file_dialog_path845660
Ref: #al_get_native_file_dialog_path845900
Node: al_destroy_native_file_dialog846289
Ref: #al_destroy_native_file_dialog846524
Node: al_show_native_message_box846737
Ref: #al_show_native_message_box846959
Node: al_open_native_text_log849248
Ref: #al_open_native_text_log849459
Node: al_close_native_text_log850527
Ref: #al_close_native_text_log850739
Node: al_append_native_text_log851100
Ref: #al_append_native_text_log851326
Node: al_get_native_text_log_event_source851863
Ref: #al_get_native_text_log_event_source852121
Node: al_get_allegro_native_dialog_version852788
Ref: #al_get_allegro_native_dialog_version853028
Node: Menus853303
Ref: #menus853437
Node: ALLEGRO_MENU856474
Ref: #allegro_menu856597
Node: ALLEGRO_MENU_INFO856890
Ref: #allegro_menu_info857046
Node: al_create_menu858391
Ref: #al_create_menu858549
Node: al_create_popup_menu858879
Ref: #al_create_popup_menu859045
Node: al_build_menu859513
Ref: #al_build_menu859670
Node: al_append_menu_item860282
Ref: #al_append_menu_item860450
Node: al_insert_menu_item860929
Ref: #al_insert_menu_item861103
Node: al_remove_menu_item862470
Ref: #al_remove_menu_item862638
Node: al_clone_menu863329
Ref: #al_clone_menu863489
Node: al_clone_menu_for_popup863897
Ref: #al_clone_menu_for_popup864075
Node: al_destroy_menu864386
Ref: #al_destroy_menu864559
Node: al_get_menu_item_caption864950
Ref: #al_get_menu_item_caption865142
Node: al_set_menu_item_caption865542
Ref: #al_set_menu_item_caption865741
Node: al_get_menu_item_flags866165
Ref: #al_get_menu_item_flags866358
Node: al_set_menu_item_flags866822
Ref: #al_set_menu_item_flags867016
Node: al_toggle_menu_item_flags867453
Ref: #al_toggle_menu_item_flags867652
Node: al_get_menu_item_icon868375
Ref: #al_get_menu_item_icon868565
Node: al_set_menu_item_icon869075
Ref: #al_set_menu_item_icon869252
Node: al_find_menu869864
Ref: #al_find_menu870019
Node: al_find_menu_item870468
Ref: #al_find_menu_item870644
Node: al_get_default_menu_event_source871318
Ref: #al_get_default_menu_event_source871539
Node: al_enable_menu_event_source872123
Ref: #al_enable_menu_event_source872345
Node: al_disable_menu_event_source872929
Ref: #al_disable_menu_event_source873140
Node: al_get_display_menu873547
Ref: #al_get_display_menu873732
Node: al_set_display_menu874059
Ref: #al_set_display_menu874229
Node: al_popup_menu875254
Ref: #al_popup_menu875415
Node: al_remove_display_menu876463
Ref: #al_remove_display_menu876614
Node: PhysicsFS integration877097
Ref: #physicsfs-integration877265
Node: al_set_physfs_file_interface878088
Ref: #al_set_physfs_file_interface878281
Node: al_get_allegro_physfs_version879649
Ref: #al_get_allegro_physfs_version879844
Node: Primitives addon880108
Ref: #primitives-addon880259
Node: General880616
Ref: #general880739
Node: al_get_allegro_primitives_version880888
Ref: #al_get_allegro_primitives_version881081
Node: al_init_primitives_addon881354
Ref: #al_init_primitives_addon881572
Node: al_is_primitives_addon_initialized881868
Ref: #al_is_primitives_addon_initialized882101
Node: al_shutdown_primitives_addon882477
Ref: #al_shutdown_primitives_addon882665
Node: High level drawing routines883005
Ref: #high-level-drawing-routines883203
Node: Pixel-precise output884718
Ref: #pixel-precise-output884880
Node: al_draw_line889212
Ref: #al_draw_line889383
Node: al_draw_triangle889877
Ref: #al_draw_triangle890059
Node: al_draw_filled_triangle890639
Ref: #al_draw_filled_triangle890840
Node: al_draw_rectangle891253
Ref: #al_draw_rectangle891450
Node: al_draw_filled_rectangle892037
Ref: #al_draw_filled_rectangle892250
Node: al_draw_rounded_rectangle892737
Ref: #al_draw_rounded_rectangle892967
Node: al_draw_filled_rounded_rectangle893629
Ref: #al_draw_filled_rounded_rectangle893865
Node: al_calculate_arc894428
Ref: #al_calculate_arc894623
Node: al_draw_pieslice897672
Ref: #al_draw_pieslice897860
Node: al_draw_filled_pieslice898647
Ref: #al_draw_filled_pieslice898848
Node: al_draw_ellipse899525
Ref: #al_draw_ellipse899716
Node: al_draw_filled_ellipse900277
Ref: #al_draw_filled_ellipse900473
Node: al_draw_circle900928
Ref: #al_draw_circle901114
Node: al_draw_filled_circle901653
Ref: #al_draw_filled_circle901842
Node: al_draw_arc902274
Ref: #al_draw_arc902451
Node: al_draw_elliptical_arc903189
Ref: #al_draw_elliptical_arc903386
Node: al_calculate_spline904160
Ref: #al_calculate_spline904354
Node: al_draw_spline905378
Ref: #al_draw_spline905559
Node: al_calculate_ribbon906066
Ref: #al_calculate_ribbon906252
Node: al_draw_ribbon907494
Ref: #al_draw_ribbon907647
Node: Low level drawing routines908531
Ref: #low-level-drawing-routines908754
Node: al_draw_prim910358
Ref: #al_draw_prim910503
Node: al_draw_indexed_prim912017
Ref: #al_draw_indexed_prim912208
Node: al_draw_vertex_buffer913324
Ref: #al_draw_vertex_buffer913527
Node: al_draw_indexed_buffer914617
Ref: #al_draw_indexed_buffer914823
Node: al_draw_soft_triangle916198
Ref: #al_draw_soft_triangle916398
Node: al_draw_soft_line918589
Ref: #al_draw_soft_line918750
Node: Custom vertex declaration routines920244
Ref: #custom-vertex-declaration-routines920478
Node: al_create_vertex_decl920541
Ref: #al_create_vertex_decl920723
Node: al_destroy_vertex_decl921376
Ref: #al_destroy_vertex_decl921560
Node: Vertex buffer routines921976
Ref: #vertex-buffer-routines922181
Node: al_create_vertex_buffer922332
Ref: #al_create_vertex_buffer922510
Node: al_destroy_vertex_buffer923889
Ref: #al_destroy_vertex_buffer924099
Node: al_lock_vertex_buffer924453
Ref: #al_lock_vertex_buffer924657
Node: al_unlock_vertex_buffer925426
Ref: #al_unlock_vertex_buffer925635
Node: al_get_vertex_buffer_size925971
Ref: #al_get_vertex_buffer_size926154
Node: Index buffer routines926433
Ref: #index-buffer-routines926618
Node: al_create_index_buffer926764
Ref: #al_create_index_buffer926937
Node: al_destroy_index_buffer928256
Ref: #al_destroy_index_buffer928460
Node: al_lock_index_buffer928807
Ref: #al_lock_index_buffer929005
Node: al_unlock_index_buffer929767
Ref: #al_unlock_index_buffer929970
Node: al_get_index_buffer_size930299
Ref: #al_get_index_buffer_size930477
Node: Polygon routines930751
Ref: #polygon-routines930924
Node: al_draw_polyline931067
Ref: #al_draw_polyline931209
Node: al_draw_polygon932790
Ref: #al_draw_polygon932961
Node: al_draw_filled_polygon933922
Ref: #al_draw_filled_polygon934124
Node: al_draw_filled_polygon_with_holes934828
Ref: #al_draw_filled_polygon_with_holes935059
Node: al_triangulate_polygon937147
Ref: #al_triangulate_polygon937325
Node: Structures and types938773
Ref: #structures-and-types938924
Node: ALLEGRO_VERTEX939252
Ref: #allegro_vertex939396
Node: ALLEGRO_VERTEX_DECL940279
Ref: #allegro_vertex_decl940464
Node: ALLEGRO_VERTEX_ELEMENT940998
Ref: #allegro_vertex_element941192
Node: ALLEGRO_PRIM_TYPE943132
Ref: #allegro_prim_type943314
Node: ALLEGRO_PRIM_ATTR944283
Ref: #allegro_prim_attr944463
Node: ALLEGRO_PRIM_STORAGE947241
Ref: #allegro_prim_storage947435
Node: ALLEGRO_VERTEX_CACHE_SIZE950375
Ref: #allegro_vertex_cache_size950582
Node: ALLEGRO_PRIM_QUALITY951105
Ref: #allegro_prim_quality951299
Node: ALLEGRO_LINE_JOIN951691
Ref: #allegro_line_join951870
Node: ALLEGRO_LINE_CAP952412
Ref: #allegro_line_cap952592
Node: ALLEGRO_VERTEX_BUFFER953245
Ref: #allegro_vertex_buffer953438
Node: ALLEGRO_INDEX_BUFFER953889
Ref: #allegro_index_buffer954089
Node: ALLEGRO_PRIM_BUFFER_FLAGS954563
Ref: #allegro_prim_buffer_flags954743
Node: Shader routines955821
Ref: #shader-routines955970
Node: ALLEGRO_SHADER956550
Ref: #allegro_shader956685
Node: ALLEGRO_SHADER_TYPE957321
Ref: #allegro_shader_type957498
Node: ALLEGRO_SHADER_PLATFORM958830
Ref: #allegro_shader_platform959017
Node: al_create_shader959901
Ref: #al_create_shader960078
Node: al_attach_shader_source961325
Ref: #al_attach_shader_source961521
Node: al_attach_shader_source_file966291
Ref: #al_attach_shader_source_file966496
Node: al_build_shader967148
Ref: #al_build_shader967321
Node: al_get_shader_log968199
Ref: #al_get_shader_log968370
Node: al_get_shader_platform968987
Ref: #al_get_shader_platform969166
Node: al_use_shader969491
Ref: #al_use_shader969654
Node: al_destroy_shader970480
Ref: #al_destroy_shader970650
Node: al_set_shader_sampler971263
Ref: #al_set_shader_sampler971448
Node: al_set_shader_matrix972498
Ref: #al_set_shader_matrix972681
Node: al_set_shader_int973085
Ref: #al_set_shader_int973260
Node: al_set_shader_float973634
Ref: #al_set_shader_float973811
Node: al_set_shader_bool974178
Ref: #al_set_shader_bool974360
Node: al_set_shader_int_vector974727
Ref: #al_set_shader_int_vector974928
Node: al_set_shader_float_vector976015
Ref: #al_set_shader_float_vector976230
Node: al_get_default_shader_source976650
Ref: #al_get_default_shader_source976836
Node: Video streaming addon977517
Ref: #video-streaming-addon977653
Node: ALLEGRO_VIDEO_EVENT_TYPE978514
Ref: #allegro_video_event_type978693
Node: ALLEGRO_EVENT_VIDEO_FRAME_SHOW978985
Ref: #allegro_event_video_frame_show979190
Node: ALLEGRO_EVENT_VIDEO_FINISHED979602
Ref: #allegro_event_video_finished979803
Node: ALLEGRO_VIDEO_POSITION_TYPE980070
Ref: #allegro_video_position_type980283
Node: al_init_video_addon981327
Ref: #al_init_video_addon981529
Node: al_is_video_addon_initialized981696
Ref: #al_is_video_addon_initialized981914
Node: al_shutdown_video_addon982134
Ref: #al_shutdown_video_addon982349
Node: al_get_allegro_video_version982615
Ref: #al_get_allegro_video_version982824
Node: al_open_video983097
Ref: #al_open_video983270
Node: al_identify_video983551
Ref: #al_identify_video983723
Node: al_identify_video_f984253
Ref: #al_identify_video_f984430
Node: al_close_video985122
Ref: #al_close_video985288
Node: al_start_video985546
Ref: #al_start_video985718
Node: al_start_video_with_voice985935
Ref: #al_start_video_with_voice986140
Node: al_get_video_event_source986408
Ref: #al_get_video_event_source986619
Node: al_set_video_playing986930
Ref: #al_set_video_playing987125
Node: al_is_video_playing987319
Ref: #al_is_video_playing987510
Node: al_get_video_audio_rate987712
Ref: #al_get_video_audio_rate987907
Node: al_get_video_fps988110
Ref: #al_get_video_fps988297
Node: al_get_video_scaled_width988544
Ref: #al_get_video_scaled_width988752
Node: al_get_video_scaled_height989148
Ref: #al_get_video_scaled_height989360
Node: al_get_video_frame989759
Ref: #al_get_video_frame989951
Node: al_get_video_position990906
Ref: #al_get_video_position991091
Node: al_seek_video991469
Ref: #al_seek_video991611

End Tag Table


Local Variables:
coding: utf-8
End:
